一個(gè)CV算法工程師的小反思【學(xué)術(shù)人生】
當(dāng)你初入江湖,迷茫不知道該干什么的時(shí)候,不妨去模仿前人是如何進(jìn)行科研的,并從中歸納出最適合自己的道路。為此,我們推出“學(xué)術(shù)人生”專欄,介紹科研的方法與經(jīng)驗(yàn),為你的科研學(xué)習(xí)提供幫助,敬請(qǐng)關(guān)注。
大佬可以寫總結(jié)給別人指導(dǎo),菜鳥(niǎo)可以寫總結(jié)給別人指坑。
原本打算是正式工作滿一年以后寫的,最近反思了很多事情,也找到了很多不足之處。怕以后忘記了,就想到什么寫什么,什么沒(méi)想到以后就補(bǔ)上。
1. 算法篇
雖然我沒(méi)有發(fā)表過(guò)頂會(huì)論文,談不上學(xué)術(shù)成就。但是我還是要硬談,在實(shí)際我們做算法落地的時(shí)候,最重要的東西確實(shí)是數(shù)據(jù)。一個(gè)CV算法項(xiàng)目的流程迭代基本都是:產(chǎn)品分析,業(yè)務(wù)指標(biāo)制定,算法調(diào)研,采集數(shù)據(jù)1W左右就夠了,出一個(gè)demo,產(chǎn)品測(cè)試,有初步badcase,其中肯定有泛化性問(wèn)題。因?yàn)榫?W數(shù)據(jù)。先增加數(shù)據(jù)量級(jí),在增大數(shù)據(jù)量級(jí)的時(shí)候要考慮badcase有哪些情況,還有數(shù)據(jù)采集這個(gè)事情也是需要一定經(jīng)驗(yàn)的。當(dāng)你考慮的case比較多的時(shí)候,很難做到窮舉。制定好數(shù)據(jù)采集策略非常重要。
算法優(yōu)化的套路不是提高指標(biāo),是要解決業(yè)務(wù)問(wèn)題。學(xué)術(shù)上統(tǒng)計(jì)一個(gè)測(cè)試集的mAP(比如檢測(cè)),業(yè)務(wù)中是要根據(jù)實(shí)際業(yè)務(wù)場(chǎng)景分開(kāi)建立測(cè)試集,比如暗光下測(cè)試集,帶遮擋測(cè)試集,通用場(chǎng)景測(cè)試集等等,要針對(duì)業(yè)務(wù)場(chǎng)景進(jìn)行優(yōu)化,業(yè)務(wù)場(chǎng)景下測(cè)試集就是算法和測(cè)試那邊溝通。
端側(cè)的算法優(yōu)化要考慮部署問(wèn)題 ,就這么說(shuō)吧,你打開(kāi)SNPE的文檔,基本照著里面的支持看基本就是八九不離十了。有些常見(jiàn)的考慮點(diǎn)時(shí)激活函數(shù)基本就是只用Relu,帶有邏輯操作的比如ROIAlign等等沒(méi)法部署,確切地說(shuō)不能直接生成一個(gè)Graph做Forward,需要構(gòu)件兩個(gè)網(wǎng)絡(luò),上采樣的方式有Deconv,Interp(nearest, bilinear), UpPooling,空洞卷積這幾種,但是不同的方式在不同的芯片平臺(tái)支持是不一樣的。還有全連接的耗時(shí)可能在有些平臺(tái)上也不太行。簡(jiǎn)單來(lái)說(shuō)除了conv relu,其他的東西都要在做之前有個(gè)調(diào)研和考慮。還有可能會(huì)有限制輸出Tensor數(shù)量和輸入Tensor數(shù)量的問(wèn)題。其他的就是不同平臺(tái)的量化支持不同了。講了這些我想現(xiàn)在還有人在用VGG還是可以理解的。Make VGG Great Again.
工作中最重要的不是論文的創(chuàng)新,尤其在初期做算法的套路,流程要清楚。以及執(zhí)行力要Max,還要有一定的數(shù)據(jù)敏感性。在標(biāo)注數(shù)據(jù)的時(shí)候需要界定什么是正樣本什么是負(fù)樣本,什么是無(wú)法判斷(ignore),什么時(shí)候需要腦補(bǔ),什么時(shí)候不需要腦補(bǔ),這個(gè)非常非常重要,數(shù)據(jù)標(biāo)錯(cuò)了后續(xù)要花費(fèi)很多力氣改正 。
要保證實(shí)驗(yàn)的正確性,一開(kāi)始實(shí)習(xí)的時(shí)候回經(jīng)常跑錯(cuò)實(shí)驗(yàn),或者實(shí)驗(yàn)跑到一半掛了,這會(huì)大大降低效率。做事情要慢一點(diǎn),但是要正確。
用tmux管理實(shí)驗(yàn)非常方便,要寫好實(shí)驗(yàn)日志,保證自己能夠看 到哪一行就知道這個(gè)實(shí)驗(yàn)做什么改動(dòng),并且可以直接找到實(shí)驗(yàn)結(jié)果保存的地方,我一般通過(guò)名字來(lái)體現(xiàn),比較復(fù)雜的就寫備注。
CV不像推薦廣告NLP,不需要用到SQL,Hadoop之類的數(shù)據(jù)查詢等工具,CV數(shù)據(jù)的管理要有自己的一套章法。要做到每一張圖片都是可溯源的,圖片和視頻,抽幀頻率,這些都需要列表。如果需要對(duì)圖片做后處理,比如人臉數(shù)據(jù),中間的結(jié)果人臉檢測(cè)bbox,摳出來(lái)的圖等等都要有記錄,腳本要整理好,一個(gè)任務(wù)從抽幀開(kāi)始到最后訓(xùn)練的圖片,分步驟處理并且每個(gè)步驟都保留中間結(jié)果,主要不要保留圖片,保留坐標(biāo)等信息。保留圖片會(huì)占用太多存儲(chǔ) 空間。每一個(gè)數(shù)據(jù)都要有專門的表格來(lái)記錄,不然以后整理其數(shù)據(jù)來(lái)有你難受的。
一個(gè)坑就是圖片的保存不要保存為jpg,jpg是有損壓縮模式,你每次保存都會(huì)導(dǎo)致圖片的質(zhì)量不斷下降,我一般都是png,不用bmp是因?yàn)閎mp太大了。
因?yàn)閳D片和標(biāo)注都是放在磁盤上,所以要有自己的風(fēng)格,我的風(fēng)格就是data目錄放視頻,Images目錄放圖片,Scripts目錄放腳本,Ann目錄放處理完的標(biāo)注文件,Ann_pre放標(biāo)注人員返回的原始標(biāo)注文件。其中每個(gè)目錄中會(huì)根據(jù)任務(wù)需求建立子目錄, 數(shù)據(jù)的信息必須要包括的是任務(wù)+時(shí)間,其他看著需求加。
要定期整理自己的文件內(nèi)容。
寫模型的訓(xùn)練和推理代碼的時(shí)候要按部就班來(lái)做,前處理的所有操作做完后在進(jìn)網(wǎng)絡(luò)之前把所有的GT都畫在圖上,保證進(jìn)網(wǎng)絡(luò)之前的結(jié)果都是正確的。生成target的時(shí)候也要把所有Target畫出來(lái),保證是正確的。
別著急寫代碼,先想好每個(gè)模塊的輸入輸出是什么,寫某個(gè)模塊的時(shí)候用pdb看下輸入和輸出是否正確,一步一步來(lái)。
圖片和標(biāo)注文件定好之后加下只讀權(quán)限,不然哪天手賤給刪了不知道上哪哭去。
訓(xùn)練模型之前要確認(rèn)的事情有:進(jìn)網(wǎng)絡(luò)的圖片和GT畫出來(lái),確認(rèn)是否會(huì)有問(wèn)題。網(wǎng)絡(luò)的Target畫出來(lái)確認(rèn)是否會(huì)有問(wèn)題,這兩點(diǎn)沒(méi)問(wèn)題Loss再下降那恭喜你等著看demo了
WarmpUp要加上,這東西誰(shuí)用都說(shuō)好
GradNorm打出來(lái),如果崩了也好分析
LearningRate一般就SGD和Adam,CosineLR等這些不怎么影響你最終的結(jié)果,可能會(huì)加快收斂.
要積累自己的代碼庫(kù),這樣很多時(shí)候只要搜一下copy過(guò)來(lái)改改就可以用,最重要的是不用再去查API浪費(fèi)時(shí)間了
提升代碼能力和算法能力的最好的方式就是看好的開(kāi)源代碼,多看多寫才能提高思維能力。
CV算法好卷啊,檢測(cè),分割 ,識(shí)別,跟蹤,OCR,ReID,分類,GAN,動(dòng)作遷移,SLAM,深度估計(jì),3D相關(guān),姿態(tài)估計(jì),圖像檢索,NAS,量化,立體匹配,圖像復(fù)原,……,What's Fuck,我這一寫感覺(jué)自己跟個(gè)白癡一樣好多都不懂。。。。
要用好vim和shell,在CV任務(wù)里面vim最常用的是一些文件的合并,交集,差集,排序,去重等等。shell命令+管道機(jī)制可以讓你快速地做很多事情,不然從頭開(kāi)始寫python代碼也是比較費(fèi)時(shí)間的。最常用的是find + 通配符找文件,然后對(duì)文件進(jìn)行刪除,移動(dòng)等等操作
opencv是必須要熟悉的,簡(jiǎn)單的讀取,存儲(chǔ),畫圖的API是必須記住。其他的要積累腳本。不過(guò)目前來(lái)看很少用到一些傳統(tǒng)特征。如果需要用到那句把這些腳本都存儲(chǔ)下來(lái)。
數(shù)據(jù)標(biāo)注完成后處理成數(shù)據(jù)集一定要考慮仔細(xì)了,在轉(zhuǎn)格式的時(shí)候一定要加上一些格式確認(rèn),比如標(biāo)注檢測(cè)框是否有左上角的坐標(biāo)值卻小于右下角這種異常情況,這個(gè)圖片是否是已經(jīng)被損壞了等等。很多時(shí)候你找半天bug發(fā)現(xiàn)是數(shù)據(jù)的問(wèn)題。
工作中沒(méi)人關(guān)注你的算法是不是新的,是不是牛逼,代碼有多難寫,不能為了新穎而新穎。能解決badcase的就是好優(yōu)化,不然就是白搭 。
要保證自己實(shí)驗(yàn)的可復(fù)現(xiàn)性,做優(yōu)化的過(guò)程中會(huì) 經(jīng)常需要改一些小細(xì)節(jié)??赡軐?duì)之前的實(shí)驗(yàn)有影響,盡量改成傳參的方式,不然也可以繼承重新寫一個(gè)類。
算法工程師要多向工程部署的同事請(qǐng)教,看看模型部署的時(shí)候需要考慮的東西有哪些,資源占用,速度優(yōu)化等等是怎么做的。
不要忽略算法的后處理,在實(shí)際用的時(shí)候經(jīng)常會(huì)加一些后處理的邏輯判斷,這個(gè)也非常重要,有時(shí)候能解決很多問(wèn)題。
目前我知道算法優(yōu)化的有效常用方案是:加數(shù)據(jù),數(shù)據(jù)增強(qiáng),好的pretrain_model,正負(fù)樣本均衡的優(yōu)化,正負(fù)樣本采樣相關(guān)優(yōu)化,知識(shí)蒸餾,額外監(jiān)督比如檢測(cè)中加分割基本能漲點(diǎn),attention模塊,多尺度,特征融合,合適的backbone,NAS搜索(應(yīng)該大家都在做),量化訓(xùn)練,剪枝。其他比如算法流程的大改動(dòng),一般人真做不了,比如VGG->MobileNet,DeepSort->CenterTrack,YOLO->YOLOv5,這些硬通貨都是大神的杰作,要向大神學(xué)習(xí),但是不要一口吃胖子。
python腳本要熟練編寫,多線程操作要信手拈來(lái),數(shù)據(jù) 處理經(jīng)常會(huì)需要多線程處理
2. 成長(zhǎng)篇
要相信自己,不要總覺(jué)得自己不如別人,要對(duì)自己有信心,才能讓別人對(duì)你有信心。
要不斷學(xué)習(xí),我的人生宗旨就是我可以菜得被開(kāi)除,但是我不能因?yàn)闊o(wú)所事事渾水摸魚(yú)被嫌棄。
要和同事友好相處,工作之后明顯就交際圈小了很多,同事是交流最多的人,不管怎么樣,都要客客氣氣。多幫別人一點(diǎn),別人才會(huì)多幫你一點(diǎn)。
要拼搏,但是不要拼命,程序員本質(zhì)上也只是一個(gè)打工的,干點(diǎn)活,拿點(diǎn)錢,不要把命搭上去。生活 還會(huì)很美好的
要去了解外界,不要一頭就在代碼里,要有個(gè)愛(ài)好,跳舞,跑步,拍照,旅游,這樣你才會(huì)能找到生活的感覺(jué)。
心態(tài)要躺平,我的心態(tài)就是什么事情我都會(huì)努力去做,如果我努力去做了卻沒(méi)做好那是我能力問(wèn)題,給我3.25,給我開(kāi)除我也接受。我要做的就是總結(jié)下為什么沒(méi)有把事情做好,去反思自己遇到的哪些問(wèn)題,走了哪些彎路,下次不要再犯。
不要抱怨家庭的出生,抱怨永遠(yuǎn)解決不了問(wèn)題,已經(jīng)五六十歲的父母難道還指望他們改變你的命運(yùn)讓你成為富二代?
暫時(shí)先寫到這里。。。。
不管以后是不是還在干程序員,我都會(huì)一直堅(jiān)持學(xué)習(xí),堅(jiān)持努力,還要堅(jiān)持輸出。
來(lái)源:知乎—CV伍六七?https://zhuanlan.zhihu.com/p/363354912
