下面的實(shí)現(xiàn)代碼可以在這里?找到氮凝,是ipython notebook格式的。如果你覺(jué)得ok的話請(qǐng)給我一個(gè)星吧~感謝M洹U终蟆!F羯恪稿壁!
正文
雖然alex_net是一個(gè)比較舊的模型(2012),但是因?yàn)槠浣Y(jié)構(gòu)簡(jiǎn)單歉备,而且在大多數(shù)任務(wù)上都能達(dá)到一個(gè)比較好的效果傅是,所以在遷移學(xué)習(xí)的時(shí)候也不妨試一試這個(gè)模型
其模型的基本結(jié)構(gòu)如下圖
因?yàn)檫@個(gè)模型當(dāng)初是用兩塊GPU訓(xùn)練的,所以在卷積的時(shí)候有一些麻煩蕾羊,這點(diǎn)在后面會(huì)再說(shuō)
從鏈接中可下載訓(xùn)練好的alex_net的權(quán)值喧笔,下面我們來(lái)看一看里面的數(shù)據(jù)的結(jié)構(gòu)是什么
首先加載這個(gè)模型的權(quán)值:
可以看到得到的weight_dict是字典形式,其key的名稱基本就能知道對(duì)應(yīng)的是哪一層的權(quán)值了
下面我們拿一層權(quán)值龟再,看看里面的數(shù)據(jù)是什么格式的
可以看到w里面是一個(gè)列表书闸,里面有兩個(gè)元素,估計(jì)應(yīng)該就是權(quán)值(w)和偏置(b)了
下面將用numpy轉(zhuǎn)換成矩陣形式利凑,看看其shape是不是這樣的
看來(lái)確實(shí)字典的value裝著列表浆劲,列表里面分別是權(quán)值和偏置。這里還有個(gè)問(wèn)題是為什么conv2,conv4的channel為什么是論文里面的一半哀澈?
比如conv2的kernel的大小為 5*5*48牌借,但是conv1的輸出明明是5*5*96。這是因?yàn)樵缙贕PU的RAM計(jì)較小日丹,這里將卷積分配到兩個(gè)GPU內(nèi)走哺,也就是將CONV2的輸入分成兩部分,5*5*48*128+5*5*48*128再分配到兩個(gè)GPU計(jì)算哲虾。也就是這里的卷積核的channel要改變一下丙躏。
因?yàn)槲覀兪沁w移學(xué)習(xí),必須要符合論文的模型結(jié)構(gòu)才能用到模型的訓(xùn)練值束凑,所以這里就需要對(duì)卷積函數(shù)進(jìn)行一些改造晒旅,
既然知道了模型數(shù)據(jù)大概是什么樣子的,下面我們就開(kāi)始自己搭建模型
2.模型搭建
alexnet的模型結(jié)構(gòu)其實(shí)也挺簡(jiǎn)單的汪诉,就是不停的堆積卷積->maxpool->lrn废恋,然后再用fc成堆幾層谈秫,就完事兒了。因?yàn)閍lex_net在一些卷積層里面會(huì)把卷積分在不同的GPU里面鱼鼓,所以這樣我們需要自己構(gòu)造一個(gè)卷積函數(shù)
這里和普通的卷積函數(shù)不一樣的是一個(gè) group參數(shù)拟烫,這個(gè)參數(shù)表示將輸入平分成幾組來(lái)分開(kāi)卷積(因?yàn)槌醮P陀昧?個(gè)GPU),所以這個(gè)值一般是1或者2.
對(duì)于平分來(lái)卷積的情況(也就是將輸入按channel來(lái)平分)迄本,這時(shí)候卷積核就會(huì)不一樣了硕淑,因?yàn)榫矸e核的輸入channel一定是和x的channel相同的。
其他的地方就和普通的卷積一樣啦
下面是每一層的結(jié)果
layer_1:conv-relu-maxpool-lrn
layer_2:conv-relu-maxpool-lrn(分組卷積)
layer_3:conv-relu
layer_4:conv-relu(分組卷積)
layer_5:conv-relu-maxpool(分組卷積)
layer_6:fc-relu
layer_7:fc-relu
layer_7:fc->輸出
3.結(jié)果分析
下面用image_net的圖片來(lái)測(cè)試一下效果嘉赎。分別用了斑馬置媳,羊駝,海獅的圖片來(lái)測(cè)試公条,可以看到效果還是不錯(cuò)的拇囊,說(shuō)明alex net的權(quán)值移植成功了
結(jié)語(yǔ):
實(shí)現(xiàn)alexnet模型只是第一步,下一步我們要fine-tune這個(gè)模型來(lái)用在自己的數(shù)據(jù)集上靶橱。如果喜歡請(qǐng)關(guān)注我吧
參考:
https://github.com/kratzert/finetune_alexnet_with_tensorflow