到底做什么,算是入行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的對比,效果還可以。
總結: