工作一年的CV算法工程師感想——技術(shù)篇【學(xué)術(shù)人生】
當(dāng)你初入江湖,迷茫不知道該干什么的時(shí)候,不妨去模仿前人是如何進(jìn)行科研的,并從中歸納出最適合自己的道路。為此,我們推出“學(xué)術(shù)人生”專欄,介紹科研的方法與經(jīng)驗(yàn),為你的科研學(xué)習(xí)提供幫助,敬請關(guān)注。
上一篇文章,一個(gè)CV算法工程師的小反思 引起了很多人的贊同和共鳴,倍感榮幸。今天是正式工作后的第一年,打算做一件事,以后要持續(xù)記錄自己的工作感想和生活狀態(tài)。人這一輩子那么有限,作為一個(gè)普通人,也許我窮極一生也不會有什么大的成就可以讓外人為我寫下一個(gè)傳記。但是我可以用自己的手記錄下我這一生,吃過的苦,犯過的錯(cuò),愛過的人,在和一些網(wǎng)友聊過之后,我發(fā)現(xiàn)我是蕓蕓眾生中的一粒沙,那些自以為的經(jīng)歷其實(shí)在陌生的一個(gè)環(huán)境里也有人同樣地經(jīng)歷著。希望我的文字可以激勵(lì)那些人,希望我的錯(cuò)誤可以警惕那些人。
1. 算法工程師必備的技能
我的具體研究方向是計(jì)算機(jī)視覺算法工程師,眾所周知,當(dāng)我們在說起算法工程師的時(shí)候,大家一般都會把工程師說成調(diào)參俠,而那種天天看論文發(fā)論文的又被捧上天。其實(shí)不然,我想以我從業(yè)一年的角度來說,一個(gè)計(jì)算機(jī)視覺算法工程師需要具備的技能。
算法工程師的工作內(nèi)容首先是每日三問:業(yè)務(wù)KPI達(dá)標(biāo)了嗎?badcase解決了嗎?CornerCase優(yōu)化了嗎?你所有的工作的目的就是去解決這三個(gè)問題。所以日常的工作內(nèi)容是看看什么Case沒有解決,制定優(yōu)化目標(biāo),迭代,再看,再優(yōu)化,不斷循環(huán)往復(fù)??瓷先ナ遣皇怯X得算法工程師這個(gè)工作簡單,枯燥,無聊?
其實(shí)不然,因?yàn)槲蚁嘈琶恳环莨ぷ鞫际怯兴菰锖唵蔚牡胤?,大名鼎鼎的李飛飛,吳恩達(dá)這些數(shù)據(jù)科學(xué)家難道就沒有做過調(diào)參的工作了?凡是不可以偏概全,我眼中的算法工程師要具備的技能點(diǎn)是這樣的。
能意識到數(shù)據(jù)的價(jià)值和用法:頂尖的數(shù)據(jù)科學(xué)家肯定是會比一般人更理解數(shù)據(jù)的價(jià)值,以及做一個(gè)算法類的項(xiàng)目,需要用到什么樣的數(shù)據(jù),使用什么樣的特征,有哪些需要考量的細(xì)節(jié),在這個(gè)項(xiàng)目中的優(yōu)化目標(biāo)所關(guān)聯(lián)的數(shù)據(jù)需求是什么。
能做好高效合理的算法選型:這一個(gè)我就是要打臉那些說算法工程師是調(diào)參俠的人了,你以為的調(diào)參俠是把一個(gè)學(xué)習(xí)率從0到1e-3挨個(gè)嘗試,改改配置就行。實(shí)際上當(dāng)接到一個(gè)新項(xiàng)目的時(shí)候,作為一個(gè)算法工程師是需要快速調(diào)研算法論文,并且制定算法優(yōu)化方案的。并且很多時(shí)候這個(gè)子方向你是之前沒有接觸過,比如突然讓你去從一個(gè)分類項(xiàng)目中去做一個(gè)跟蹤項(xiàng)目,你需要在一周之內(nèi)去調(diào)研業(yè)界的跟蹤算法文章并理清楚跟蹤算法的分類成績,優(yōu)缺點(diǎn)分析,核心思想分析,這一點(diǎn)沒有論文積累是比較難的。優(yōu)秀的算法工程師就是要具備這種快速選型并且抓重點(diǎn),最后還能給出一個(gè)合理的算法選型。一般考慮的角度是(可部署性,精度指標(biāo),速度怎么樣,有沒有不支持的算子,是否開源等等)。話說在這一點(diǎn)上,沒有人會傻到對一個(gè)新項(xiàng)目去復(fù)現(xiàn)沒開源的SOTA論文。
全流程的把控能力:這方面算軟實(shí)力,偏項(xiàng)目管理。正如我之前說的一個(gè)需求從定義,調(diào)研,方案制定,數(shù)據(jù)采集,標(biāo)注,模型訓(xùn)練,Inference,SDK的集成。這一套流程都是要有時(shí)間節(jié)點(diǎn)的,不僅僅是項(xiàng)目負(fù)責(zé)人給的節(jié)點(diǎn),算法工程師自身也要給自己定義節(jié)點(diǎn)并且高效把控。比如采集的安排要考慮采集方案的合理性,高效性。標(biāo)注的時(shí)候要定義好標(biāo)注邊界,在你手里過的數(shù)據(jù)要要詳細(xì)的記錄,不然到時(shí)候數(shù)據(jù)找不到真是個(gè)很麻煩的事情。模型訓(xùn)練的時(shí)候從輸入圖片校對,target校對,inference代碼,看著loss慢慢降下去了就可以安心喝個(gè)咖啡休息休息,這套流程其實(shí)就是一般的軟件開發(fā)一樣,不需要擔(dān)心完不成的問題,但是要考慮風(fēng)險(xiǎn),把控進(jìn)度,注重細(xì)節(jié),考驗(yàn)的是一個(gè)算法工程細(xì)不細(xì)的問題。
代碼功底:算法工程師基本都是Python為主,python作為一種簡單的語言使用起來當(dāng)然非常方便。(不要用C++的高端來批判使用python的我們了,用C++寫模型的訓(xùn)練那是憨憨或者是大神(yolo作者)干的事。python代碼除了基礎(chǔ)的操作,數(shù)字,字符串,類,裝飾器等等,其他就是各種工具要用的數(shù)量,numpy, pandas, torch, opencv, multiprocess等,具體看你的研究方向了。在系統(tǒng)架構(gòu)上,我覺得學(xué)習(xí)開源代碼,比如PaddlePaddle和MMLab的代碼都是非常好的學(xué)習(xí)資源。只不過我們所謂的架構(gòu)是把一個(gè)算法項(xiàng)目的前處理,后處理,model_build, backbone,neck,head等等這些組件化的一種架構(gòu),但是我認(rèn)為一些設(shè)計(jì)模式的思想還是和軟件開發(fā)一樣的,大量的工廠模式,觀察者模式的思想在這些算法架構(gòu)中都有體現(xiàn)。對于C++這方面,我之前也有執(zhí)念要不要學(xué)CUDA,現(xiàn)在覺得不需要,我所任務(wù)的算法工程師的C++功底是要能高效完成邏輯上的處理,以及能夠快速定位和調(diào)試遇到的bug,Cmake也要能看得懂,要有把算法模型部署上線的能力,對C++的基礎(chǔ)類型,STL,指針,引用,多態(tài),繼承,命名空間,模板都熟悉。至于一些指令級優(yōu)化,算子融合啥的,那都是專業(yè)的人去做了。
算法優(yōu)化能力:這是個(gè)核心技能,一定要秉持著數(shù)據(jù)>算法>創(chuàng)新的思路去做一個(gè)項(xiàng)目,當(dāng)優(yōu)先級高的遇到了瓶頸了再去做下一個(gè)環(huán)節(jié)的事情。數(shù)據(jù)側(cè)就是要不斷去做badcase分析,按場景按類別去分好自己的訓(xùn)練數(shù)據(jù),同樣要對測試集,測試方案,測試指標(biāo)要不斷改進(jìn)和優(yōu)化。算法上則要考慮的是backbone的設(shè)計(jì)選擇,neck的設(shè)計(jì)選擇,head中target的設(shè)計(jì)選擇,數(shù)據(jù)增強(qiáng)方案(這個(gè)比較重要,除了幾何增強(qiáng),還有像素級增強(qiáng)),更好的Pretrain模型,后處理的邏輯優(yōu)化,大模型KD優(yōu)化,類別不均衡的優(yōu)化,難樣本挖掘優(yōu)化等。重點(diǎn)說下后處理,這個(gè)環(huán)節(jié)其實(shí)非常重要,很多時(shí)候基于邏輯的規(guī)則可以提高你模型一大半的性能,代碼一般都簡單,但是需要你去從數(shù)據(jù)反饋中挖掘這個(gè)規(guī)則怎么制定。創(chuàng)新性則是你的研究能力。
研究能力:很多論文其實(shí)價(jià)值不大,不是在于沒有創(chuàng)新,而是在于這個(gè)創(chuàng)新都是為了“新”去做的,并且在那么一兩個(gè)公開數(shù)據(jù)集上達(dá)到了比較好的效果就可以發(fā)論文來證明這個(gè)工作的價(jià)值。有時(shí)候?qū)嶒?yàn)了發(fā)現(xiàn)不好,就改一通網(wǎng)絡(luò),我已經(jīng)看了很多篇加了deform_conv魔改網(wǎng)絡(luò)的方案了。非常solid的文章當(dāng)然值得尊重,比如之前看多目標(biāo)跟蹤的時(shí)候看完centertrack的時(shí)候,感覺這篇文章真的簡單,溫柔,有力量!不過我其實(shí)也不是吃不到葡萄說葡萄酸哈,能發(fā)頂會當(dāng)然是大大的好哈。畢竟程序員往高了走,頂會頂刊,行業(yè)影響力是妥妥的硬通貨!但是不過是工程還會做研究,調(diào)研論文,復(fù)現(xiàn)論文都是必備的技能,這塊其實(shí)我覺得也是屬于研究能力的范疇。
數(shù)學(xué)能力:很多人都說算法工程師對數(shù)學(xué)要求高,其實(shí)我不太清楚這個(gè)要求高具體指啥水平,但是起碼公式推導(dǎo)是肯定要掌握的,不然很多論文也看不懂的,比如最近在看目標(biāo)跟蹤的文章,我感覺對數(shù)學(xué)水平還是有一定要求的,不然連傅里葉變換,卡爾曼濾波都整不明白,那真的沒法玩,至于比這更高的數(shù)學(xué)要求,那就讓那些數(shù)學(xué)家,研究員搞去吧。我反正是搞不了,爹媽就給我這腦袋,不是金剛鉆我也不攬瓷器活。
聚焦一個(gè)方向:由點(diǎn)開始出發(fā),算法一般就是推薦,搜索,NLP,CV,控制規(guī)劃這些子方向。我本身是做CV的,所以對CV稍微比較了解一點(diǎn),在CV里其實(shí)方向也非常多,傳統(tǒng)圖像處理,識別,檢測,分割,單目標(biāo)跟蹤,多目標(biāo)跟蹤,人臉相關(guān)任務(wù)(屬性,情緒,識別等等),GAN,顯著性檢測,異常檢測,超分辨率,OCR,圖像復(fù)原(去霧,去雨,去陰影,補(bǔ)全圖像...),深度估計(jì),ReID,SLAM,以及通用技術(shù)模型量化,剪枝,模型蒸餾,meta learning,遷移學(xué)習(xí)……??吹竭@應(yīng)該明白為啥CV這么卷了吧,而且有些方向的門檻和技術(shù)棧比較高,比如SLAM,一般社招SLAM的話基本都是要有相關(guān)經(jīng)驗(yàn)的,不然一個(gè)只做過分類任務(wù)的人去做SLAM估計(jì)會很吃力。我的想法就是要從一個(gè)小方向出發(fā),在幾個(gè)小方向內(nèi)挖深,然后對其他大方向也觸類旁通,這樣才能有更好的進(jìn)步。畢竟方向是不一樣,能力需求還是差不多的。
2. 算法工程師的技術(shù)成長
這一年下來,我感覺自己在技術(shù)上收獲還是蠻多的,在這個(gè)大項(xiàng)目組里,檢測,分割,分類,識別,關(guān)鍵點(diǎn)都有所接觸,同事也非常nice,不同方向的同事平時(shí)也樂于分享自己技術(shù)棧里的工作和前沿文章。但是有點(diǎn)比較無奈的就是自己在算法創(chuàng)新這一點(diǎn)上還是有所欠缺。希望下一年的時(shí)間里,自己可以不斷加強(qiáng)這方面的能力提升。
算法能力:當(dāng)然是重中之重,leetcode不僅僅是招聘的篩選標(biāo)準(zhǔn),也是鍛煉一個(gè)人算法思維的重要手段。雖然不得不說hard的題一般都是有一些ACM的技巧性在里面,但是我認(rèn)為一個(gè)成熟的算法工程師,一定是要有秒解easy題,對middle的題也要基本能cover得住。不然用技巧性,題目和業(yè)務(wù)不搭邊這樣的說法只能是掩蓋自己思維能力不足的借口。這一點(diǎn)自己做得還不夠好,還是要不斷提高。
PPT和文字能力:對,沒錯(cuò),我要把這個(gè)放到技術(shù)篇。因?yàn)閷慞PT真的是個(gè)技術(shù)活?。。】戳私M內(nèi)老大哥寫的那PPT,技術(shù)邏輯條理分明,布局結(jié)構(gòu)美觀大氣,講PPT那個(gè)滔滔不絕的樣子真是好萊塢大片一鏡到底,絕了?。?!作為一個(gè)有語言障礙的人,十分佩服,羨慕這樣的人。不過我總結(jié)了大佬的PPT和演講。做一個(gè)好的PPT,尤其是技術(shù)類的PPT,第一點(diǎn)就是要對自己的技術(shù)棧非常清晰,技術(shù)能力是絕對要過關(guān)。圖和文字上,就是要以圖代字,不能空洞,也不用浮夸,更不用像學(xué)校課件一樣放一些動(dòng)態(tài)特效。技術(shù)人員的PPT只要三個(gè)點(diǎn):邏輯清晰,內(nèi)容充實(shí),一目了然。在美觀性上,我下載了論壇和組內(nèi)會議的優(yōu)質(zhì)PPT分析了下,所謂美觀其實(shí)只要有個(gè)簡約的背景,文字和圖標(biāo)最好一起用,多放一些柱狀圖,折線圖等說明你的工作,時(shí)間線的匯報(bào)來個(gè)帶箭頭的圖表述下。PPT這個(gè)東西,要積累模板,要理清邏輯,要整理材料,要抓住重點(diǎn),要自信表達(dá)。希望自己和觀眾老爺們的PPT能力都可以不斷進(jìn)步,一時(shí)菜雞不要緊,永遠(yuǎn)不行動(dòng)才是最可怕的。
前沿技術(shù)的跟進(jìn):做算法這一點(diǎn)確實(shí)是和其他行業(yè)差異比較大的,算法的技術(shù)更迭特別快。要經(jīng)常閱讀前沿論文,也許不會直接拿來用,但是技術(shù)的優(yōu)化細(xì)節(jié)是否有助于現(xiàn)有的項(xiàng)目這個(gè)其實(shí)還是需要考量一下的。不要用(不都是用老方法做項(xiàng)目)這樣的說法來diss我,你要是這么想你就用10年的算法一直用,近3年的文章都不看,當(dāng)有新的有價(jià)值的東西出來的時(shí)候等你知道了別人早就用上了,而且長時(shí)間不看論文。也會慢慢喪失對文獻(xiàn)閱讀和理解的能力,就和一個(gè)人長時(shí)間不寫代碼了就不會寫代碼一樣。
現(xiàn)有的技術(shù)方案總結(jié):僅僅根據(jù)自己比較了解的識別,檢測,分割方面的一些總結(jié)。比較通用的算法側(cè)優(yōu)化是backbone(resnet resnext resnest efficientNet等大模型,mobilenet hrnet shufflenet等系列小模型),Neck(fpn, bi-fpn,panet等各種FPN層),比較實(shí)用的網(wǎng)絡(luò)優(yōu)化(deform_conv,se-net,cbam等attention結(jié)構(gòu)),head優(yōu)化(主要是target設(shè)計(jì)的方方面面,比如檢測anchor-base和anchor-free之間的差異就是在于target和輸出之間加了一個(gè)anchor作為橋梁),訓(xùn)練策略優(yōu)化(主要集中在正負(fù)樣本均衡,損失函數(shù)設(shè)計(jì),比如過采樣,欠采樣,損失函數(shù)比如FocalLoss,triplet_loss,訓(xùn)練流程上比如OHEM等),訓(xùn)練參數(shù)優(yōu)化(CosineLearningRate等LR方面的優(yōu)化,AutoAugment、Mixup、CutOut等數(shù)據(jù)增強(qiáng)方面的優(yōu)化),預(yù)訓(xùn)練模型(基于無監(jiān)督大數(shù)據(jù)Moco等, 大分辨率pretrain, 最差也地ImageNet-pretrain了,這塊NLP方面做的比較好,CV這塊我比較看好無監(jiān)督或者半監(jiān)督的方法),新方案(ViT,DETR等transformer在CV里的各種應(yīng)用)。知識蒸餾,大模型蒸餾小模型是每一個(gè)公司都會要的技術(shù)棧,可看hinto的開山之作,當(dāng)時(shí)后面還有各種多teacher,加權(quán)等方案。最后就是訓(xùn)練數(shù)據(jù)的干凈,對不同場景都能cover到,對于訓(xùn)練參數(shù)中的具體數(shù)值就跑模型看效果。以上是我這一年經(jīng)驗(yàn)所總結(jié)的算法優(yōu)化方向,重點(diǎn)在于總結(jié)方向,具體細(xì)節(jié)方法太多了就不一一贅述。就這一年的工作經(jīng)驗(yàn)看來,很多時(shí)候不同的算法方案之間很多時(shí)候效果上實(shí)際差距其實(shí)不大,這一點(diǎn)在我跑ATSS的實(shí)驗(yàn)的時(shí)候也更加確定。但是有些東西比如attention_block,transformer,KD等確實(shí)是硬通貨。做一個(gè)算法工程師最重要的素質(zhì)是在海量的算法方案中理解,吃透那些真正的干貨,然后不斷在實(shí)踐中去驗(yàn)證,并總結(jié)吸收到自己的腦子里。
后記:以后的時(shí)間啊,要做一個(gè)說書人,記錄自己的所思所想,講好一個(gè)故事,一個(gè)屬于我的故事。在這個(gè)誰都不認(rèn)識誰的網(wǎng)絡(luò)世界里,輸出我對這個(gè)世界的看法,激勵(lì)和我曾經(jīng)一樣墮落的人,照亮和我一樣前進(jìn)的人,溫暖和我一樣坎坷的人。清除了所有的可能包含個(gè)人信息的痕跡,我想以后,在這個(gè)世界里,為自己,寫一個(gè)故事,一個(gè)用一生來記錄的故事。
來源:CV伍六七?https://zhuanlan.zhihu.com/p/395255446
