我们不说怎么能够成为 XXX, 我们先来看看成为 XXX 之后要做什么事情, 而做这些事情, 需要什么样的能力, 在拥有了这些能力, 做上了这件事情之后, 又能向什么方向发展. 换言之, 本文中, 我们将从直观的角度, 管窥承担不同角色工作所需要具备的素质, 日常工作的状态, 和职业发展路径.
人工智能, 已经跌入到两三年前大数据风口上, 全民皆 "数据科学家" 的套路里了.
到底做什么, 算是入行 AI?
这个话题其实在笔者之前的几个 chat 里面已经反复提到过了, 在此再说一遍: 工业界直接应用 AI 技术的人员, 大致可以分为三个不同角色: 算法, 工程, 和数据.
现在各种媒体上, 包括 GitChat 中有大量的文章教大家怎么入行 AI, 怎么成为具体某个领域的工程师, 告诉大家要在某领域内发展需要掌握的技术栈是什么, 等等......
我们不说怎么能够成为 XXX, 我们先来看看成为 XXX 之后要做什么事情, 而做这些事情, 需要什么样的能力, 在拥有了这些能力, 做上了这件事情之后, 又能向什么方向发展.
换言之, 本文中, 我们将从直观的角度, 管窥承担不同角色工作所需要具备的素质, 日常工作的状态, 和职业发展路径.
做算法
1.1 日常工作
所有人都想做算法, 那么, 说到底, 在工业界做算法倒是干什么?
真正的算法工程师(也有公司叫科学家), 最基本的日常工作其实是: 读论文 & 实现之 -- 确认最新论文中的阐述是否真实可重现, 进一步确认是否可应用于本企业的产品, 进而将其应用到实践中提升产品质量.
1.2 必备能力
既然日常工作首先是读别人论文. 那么, 必不可少, 作为算法工程师得具备快速, 大量阅读英语论文的能力.
有一个网站, 所有有志于算法的同学必须要知道: https://arxiv.org -- 这里有多个学科 (包括 computer science) 大量的最新论文.
现在许多科学家, 学者, 研究人员和博士生在论文刚刚完成, 尚未在正式期刊会议上发表时就先将论文发布在此处, 为的是在尽量短的时间延误下对外传播自己的成果.
传统的正规渠道, 从论文完成到正式发表之间存在短则三四个月, 长则一年半载的延迟. 这对一些传统学科, 还勉强可以接受.
但计算机科学, 尤其是人工智能, 机器学习, 深度学习这几个当今世界最热门的主题, 大家都在争分夺秒地抢占制高点, 几个月的耽搁根本不能容忍.
因此, 对于 AI 的学术性文献而言, arxiv.org 实际上已经成为了当前的集大成之地.
如果要做算法, 平均而言, 大致要保持每周读一篇最新论文的频率.
也许这就是为什么, 到目前为止, 笔者所听闻和见过的算法工程师都是名校相关专业博士的原因.
经过几年强化学术研究训练, 这些博士们, 就算英语综合水平不过 CET-4, 也能读得进去一篇篇硬骨头似的英语论文!
1.3 自测 "算法力"
但当然不能说硕士, 学士或者其他专业的有志之士就做不成算法了. 人都不是生而知之, 不会可以学嘛.
但是到底能不能学会, 其实也并不需要三年五载的时间, 花费几万十几万金钱在各种培训或者付费阅读上才能够知道.
有个很简单的验证方法: 现在就去 https://arxiv.org 找一篇论文(比如这篇: Dynamic Routing Between Capsules), 从头到尾读一遍.
现在不懂没关系, 至少先试试在不懂的情况下能不能把它从头到尾一字不漏的读完, 有不认识的字查字典.
如果这都做不到, 还是当机立断和 "算法" 分手吧. 既然注定无缘, 何必一味纠缠?
1.4 学术实践能力
如果, 碰巧你喜欢读论文, 或者就算不喜欢也有足够强大的意志力, 专注力压迫自己去强行阅读论文. 那么恭喜你, 你已经跨上了通往算法山门的第一级台阶.
下面一级是: 读懂论文.
既然要读论文, 读最新论文, 而且阅读的目的是指导实践, 那么自然要读懂. 拿起一篇论文就达到懂的程度, 至少需要下面这三种能力:
1.4.1 回溯学习能力
一篇论文拿来一看, 一大堆名词术语不懂, 它们互相之间是什么关系也不知道. 怎么办? 去读参考文献, 去网上搜索, 去书籍中查找...... 总之, 动用一切资源和手段, 搞清不明概念的含义和联系.
这种能力是学术研究的最基础能力之一, 一般而言, 有学术背景的人这一点不在话下.
如果现在没有, 也可以去主动培养, 那么可能首先需要学习一下学术研究方法论.
1.4.2 数学能力
如果只是本着学习的目的读经典老论文, 那么只要清楚文中图表含义, 看公式推导明白一头一尾 (最开始公式成立的物理意义, 以及结束推导后最终形式所具备的基本性质) 也就可以了.
但读最新论文就不同. 因其新, 必然未经时光检验, 因此也就没人预先替你验证的它的正确性.
在这种情况下, 看公式就得看看推导了. 否则, 外一是数学推导有错, 导致了过于喜人的结果, 却无法在实践中重现, 岂不空耗时力?
如果目前数学能力不够, 当然也可以学. 但就与后面要说的做工程用到什么学什么的碎片化学习不同, 做算法, 需要系统学习数学.
微积分, 线性代数, 概率统计, 是无法回避的. 如果在这方面有所缺乏, 那还是先从计算机系的本科数学课开始吧, 个人推荐北师大教材.
做工程
2.1 日常工作
相对于算法的创新和尖端, 做工程要平实得多.
这一角色比较有代表性的一种岗位就是: 机器学习工程师(或戏称调参工程师)-- 他们使用别人开发的框架和工具, 运行已有算法, 训练业务数据, 获得工作模型.
其间可能需要一些处理数据, 选取特征或者调节参数的手段, 不过一般都有据可循, 并不需要自己去发明一个 XXXX.
做工程也得读论文, 不过和做算法不同, 做工程读论文的一般目的不是尝试最新方法, 而是用已知有效的方法来解决实际问题.
这就导致了, 做工程的, 读的经常是 "旧" 论文, 或者相对学术含量低一些 (不那么硬) 的论文.
而且在阅读时, 主要是为了直接找到某个问题的处理方法, 因此, 可以跳读.
对于其中的数学公式, 能够读懂头尾也就可以了. 论文阅读频率和学术深度的要求, 都比做算法低得多.
当然, 既然是有领域的程序员, 在专业上达到一定深度也是必要的.
虽然做工程一般要使用现成技术框架, 但并不是说, 直接把算法当黑盒用就可以做一名合格的 "调参" 工程师了.
把算法当黑盒用的问题在于: 黑盒能够解决问题的时候, 使用方便, 而一旦不能解决问题, 或者对质量有所要求, 就会感觉无所适从.
做工程,机器学习学到多深够用
当然, 既然是有领域的程序员, 在专业上达到一定深度也是必要的.
虽然做工程一般要使用现成技术框架, 但并不是说, 直接把算法当黑盒用就可以做一名合格的 "调参" 工程师了.
把算法当黑盒用的问题在于: 黑盒能够解决问题的时候, 使用方便, 而一旦不能解决问题, 或者对质量有所要求, 就会感觉无所适从.
做数据
此处说得做数据并非数据的清洗和处理 -- 大家可以看到做工程的岗位, 有一部分工作内容就是 ETL 和处理数据. 此处说的做数据是指数据标注.
3.1 标注数据的重要性
虽然机器学习中有无监督学习, 但在实践领域被证明有直接作用的, 基本上还都是有监督模型.
近年来, 深度学习在很多应用上取得了巨大的成功, 而深度学习的成功, 无论是图像, 语音, NLP, 自动翻译还是 AlphaGo, 恰恰依赖于海量的标注数据.
无论是做 ML 还是 DL 的工程师(算法 & 工程), 后者有甚, 都共同确认一个事实: 现阶段而言, 数据远比算法重要.
3.2 数据人工标注的必要性
数据标注的日常工作
简单说: 数据标注的日常工作就是给各种各样的数据 (文本, 图像, 视频, 音频等) 打上标签.
[好消息] : 数据标注工作几乎没有门槛. 一般任何专业的大学毕业生, 甚至更低学历, 都能够胜任. 上手不需要机器学习之类的专业知识.
[坏消息] : 这样一份工作, 是纯粹的 "脏活累活", 一点都不 cool, 起薪也很低.
打个不太恰当的比喻:
做算法是屠龙, 仗剑江湖, 天外飞仙;
做工程是狩猎, 跃马奔腾, 纵酒狂歌;
做数据是养猪, 每天拌猪食清猪粪, 一脸土一身泥.
所以, 虽然这是一件谁都能干的工作, 但是恐怕, 没几个人想干.
认清形势, 脚踏实地
近来一段时间, 能明显感到, 想入行 AI 的人越来越多, 而且增幅越来越大.
为什么这么多人想入行 AI 呢? 真的是对计算机科学研究或者扩展人类智能抱着无限的热忱吗? 说白了, 大多数人是为了高薪.
人们为了获得更高的回报而做出选择, 努力工作, 原本是非常正当的事情. 关键在于, 找对路径.
寻求入行的人虽多, 能真的认清市场当前的需求, 了解不同层次人才定位, 并结合自己实际寻找一条可行之路的人太少.
人人都想 "做算法", 却不想想: 大公司里的研究院养着一群高端科学家, 有得是读了十几二十年论文始终站在 AI 潮头的资深研究人员.
下面分享, ShuffleNet 算法详解
算法详解:
ShuffleNet 是 Face++ 的一篇关于降低深度网络计算量的论文, 号称是可以在移动设备上运行的深度网络. 这篇文章可以和 MobileNet,Xception 和 ResNeXt 结合来看, 因为有类似的思想. 卷积的 group 操作从 AlexNet 就已经有了, 当时主要是解决模型在双 GPU 上的训练. ResNeXt 借鉴了这种 group 操作改进了原本的 ResNet.MobileNet 则是采用了 depthwise separable convolution 代替传统的卷积操作, 在几乎不影响准确率的前提下大大降低计算量, 具体可以参考 MobileNets - 深度学习模型的加速. Xception 主要也是采用 depthwise separable convolution 改进 Inception v3 的结构.
该文章主要采用 channel shuffle,pointwise group convolutions 和 depthwise separable convolution 来修改原来的 ResNet 单元, 接下来依次讲解.
channel shuffle 的思想可以看下面的 Figure 1. 这就要先从 group 操作说起, 一般卷积操作中比如输入 feature map 的数量是 N, 该卷积层的 filter 数量是 M, 那么 M 个 filter 中的每一个 filter 都要和 N 个 feature map 的某个区域做卷积, 然后相加作为一个卷积的结果. 假设你引入 group 操作, 设 group 为 g, 那么 N 个输入 feature map 就被分成 g 个 group,M 个 filter 就被分成 g 个 group, 然后在做卷积操作的时候, 第一个 group 的 M/g 个 filter 中的每一个都和第一个 group 的 N/g 个输入 feature map 做卷积得到结果, 第二个 group 同理, 直到最后一个 group, 如 Figure1(a). 不同的颜色代表不同的 group, 图中有三个 group. 这种操作可以大大减少计算量, 因为你每个 filter 不再是和输入的全部 feature map 做卷积, 而是和一个 group 的 feature map 做卷积. 但是如果多个 group 操作叠加在一起, 如 Figure1(a)的两个卷积层都有 group 操作, 显然就会产生边界效应, 什么意思呢? 就是某个输出 channel 仅仅来自输入 channel 的一小部分. 这样肯定是不行的的, 学出来的特征会非常局限. 于是就有了 channel shuffle 来解决这个问题, 先看 Figure1(b), 在进行 GConv2 之前, 对其输入 feature map 做一个分配, 也就是每个 group 分成几个 subgroup, 然后将不同 group 的 subgroup 作为 GConv2 的一个 group 的输入, 使得 GConv2 的每一个 group 都能卷积输入的所有 group 的 feature map, 这和 Figure1(c)的 channel shuffle 的思想是一样的.
pointwise group convolutions, 其实就是带 group 的卷积核为 1*1 的卷积, 也就是说 pointwise convolution 是卷积核为 1*1 的卷积. 在 ResNeXt 中主要是对 3*3 的卷积做 group 操作, 但是在 ShuffleNet 中, 作者是对 1*1 的卷积做 group 的操作, 因为作者认为 1*1 的卷积操作的计算量不可忽视. 可以看 Figure2(b)中的第一个 1*1 卷积是 GConv, 表示 group convolution.Figure2(a)是 ResNet 中的 bottleneck unit, 不过将原来的 3*3 Conv 改成 3*3 DWConv, 作者的 ShuffleNet 主要也是在这基础上做改动. 首先用带 group 的 1*1 卷积代替原来的 1*1 卷积, 同时跟一个 channel shuffle 操作, 这个前面也介绍过了. 然后是 3*3 DWConv 表示 depthwise separable convolution.depthwise separable convolution 可以参考 MobileNet, 下面贴出 depthwise separable convolution 的示意图. Figure2(c)添加了一个 Average pooling 和设置了 stride=2, 另外原来 Resnet 最后是一个 Add 操作, 也就是元素值相加, 而在 (c) 中是采用 concat 的操作, 也就是按 channel 合并, 类似 googleNet 的 Inception 操作.
下图就是 depthwise separable convolution 的示意图, 其实就是将传统的卷积操作分成两步, 假设原来是 3*3 的卷积, 那么 depthwise separable convolution 就是先用 M 个 3*3 卷积核一对一卷积输入的 M 个 feature map, 不求和, 生成 M 个结果, 然后用 N 个 1*1 的卷积核正常卷积前面生成的 M 个结果, 求和, 最后得到 N 个结果. 具体可以看另一篇博文: MobileNets - 深度学习模型的加速.
Table 1 是 ShuffleNet 的结构表, 基本上和 ResNet 是一样的, 也是分成几个 stage(ResNet 中有 4 个 stage, 这里只有 3 个), 然后在每个 stage 中用 ShuffleNet unit 代替原来的 Residual block, 这也就是 ShuffleNet 算法的核心. 这个表是在限定 complexity 的情况下, 通过改变 group(g)的数量来改变 output channel 的数量, 更多的 output channel 一般而言可以提取更多的特征.
实验结果:
Table2 表示不同大小的 ShuffleNet 在不同 group 数量情况下的分类准确率比较. ShuffleNet s * 表示将 ShuffleNet 1 * 的 filter 个数变成 s 倍. arch2 表示将原来网络结构中的 Stage3 的两个 uint 移除, 同时在保持复杂度的前提下 widen each feature map.Table2 的一个重要结论是 group 个数的线性增长并不会带来分类准确率的线性增长. 但是发现 ShuffleNet 对于小的网络效果更明显, 因为一般小的网络的 channel 个数都不多, 在限定计算资源的前提下, ShuffleNet 可以使用更多的 feature map.
Table3 表示 channel shuffle 的重要性.
Table4 是几个流行的分类网络的分类准确率对比. Table5 是 ShuffleNet 和 MobileNet 的对比, 效果还可以.
总结:
ShuffleNet 的核心就是用 pointwise group convolution,channel shuffle 和 depthwise separable convolution 代替 ResNet block 的相应层构成了 ShuffleNet uint, 达到了减少计算量和提高准确率的目的. channel shuffle 解决了多个 group convolution 叠加出现的边界效应, pointwise group convolution 和 depthwise separable convolution 主要减少了计算量.
来源: http://ai.51cto.com/art/201807/578099.htm