imagenet-vgg-verydeep-19.mat 格式解析
05-20
imagenet-vgg-verydeep-19.mat 格式解析
今天在玩Stanford CS20SI公開課里的一個神經網路style_transfer小模型的時候,用到了vgg pretrained模型,然而,代碼里獲取weight和bias是這麼寫的:W = vgg_layers[0][layer][0][0][2][0][0]b = vgg_layers[0][layer][0][0][2][0][1]摔!這也沒注釋,完全看不懂啊!雖然可以查到vgg的模型信息(下面有個layer configuration的SVG圖),可是對應不上這些索引啊!於是把模型下載下來,在ipython里一步一步解析:首先,導入http://scipy.io包:
知乎的文章排版真是......(欲哭無淚),因此文章就先發在博客啦~粘貼在這裡以供預覽:
VGG pretrained模型地址:
http://www.vlfeat.org/matconvnet/pretrained/下載地址:http://www.vlfeat.org/matconvnet/models/imagenet-vgg-verydeep-19.mat不過我用的這個beta版本的不太一樣,地址
http://www.vlfeat.org/matconvnet/models/beta16/imagenet-vgg-verydeep-19.mat但是分析過程是一樣的
import http://scipy.io
然後,用loadmat載入模型(載入matlab文件格式的方法):vgg = scipy.io.loadmat(imagenet-vgg-verydeep-19.mat)接下來就是探索格式了:首先,看一下導入後的模型類型:type(vgg)嗯,不出所料,是個dict,scipy.io.loadmat的官方文檔也有說明,返回類型是個dict.然後就是看一下有哪些key啦:vgg.keys()輸出有dict_keys([__header__, __version__, __globals__, layers, classes, normalization])
嗯,看來前三項是meta信息,後面的三樣東西是我們需要的,看名字應該分別是層參數,分類信息,正則化參數(像素平均值)那麼,先看看layers層:layers = vgg[layers]輸出有一大坨,不過看頭部足以分析:array([[ array([[ (array([[ array([[[[ 0.39416704, -0.08419707, -0.03631314, ...頂級array有兩個[[所以是兩維,每一個維數的元素是array,array內部還有維數,因此可以看出,想要索引出元素確實需要很多index,那麼看一下shape:layers.shape輸出是(1, 43)說明雖然有兩維,但是第一維是」虛的」,也就是只有一個元素,我們index進去:
layers = layers[0]根據模型可以知道,這43個元素其實就是對應模型的43層信息(conv1_1,relu,conv1_2…),那麼看一層就足以,而且我們現在得到了一個有用的index,那就是layerlayers[layer]其中layer是layer參數,範圍0-42,我們選0看看:layer = layers[0]從輸出可以看出尾部有dtype信息,這個比較重要,記錄了元素的標籤:dtype=[(weights, O), (pad, O), (type, O), (name, O), (stride, O)]可以看出頂層的array有5個元素,分別是weight(含有bias), pad(填充元素,無用), type, name, stride信息,然後繼續看一下shape信息,layer.shape輸出是:
(1, 1)說明雖然有兩維,但是這兩維都是」虛的」,也就是只有一個元素,我們直接兩次index進去,應該會得到一個包含5中信息的arraylayer = layer[0][0]現在layer已經是」裸」的了,直接看看lenlen(layer)輸出是5果然不出所料,那麼已經很清楚了,對應上面的dtype說明,很容易得到weight,bias之類信息,比如layer的name,是第4個(從0開始索引),那麼:name = layer[3]輸出是
array([conv1_1],dtype=<U7)果然拿到了name信息,但是這是一個array,想拿到字元串還要再index進去:name = name[0]這次輸出就是一個字元串元素了,』conv1_1′,看來解析已經成功了,其他如法炮製,例如weight(含有bias)weight = layer[0]看一下weight的shape:weight.shape輸出是:(1, 2)
再次說明第一維是」虛的」,index進去:weight = weight[0]注意,這裡的weight是廣義的weight,也就是包含通常我們說的weight和bias,所以,分別拿到這兩個元素還要再解開一次:weight, bias = weight至此,已經完成了第0層的name, weight, bias解析,那麼其他層也一樣,改變layer的index即可,但是要注意的是,這是conv層的解析,relu層,fc層有所不同,不過原理一樣,在ipython里探索即可.所以,根據上面總結出layer的name的index順序name = vgg[layers(字典key)][0(去掉"虛"的維,相當於np.squeeze)][layer(層索引)][0][0(連續兩次去掉虛的維度)][3(weigh,pad,type,name,stride5類信息的索引,從0開始)][0(去掉"虛"的維,相當於np.squeeze)]weight, bias的index順序weight, bias = vgg[layers(字典key)][0(去掉"虛"的維,相當於np.squeeze)][layer(層索引)][0][0(連續兩次去掉虛的維度)][0(weigh, pad, type, name, stride5類信息的索引,從0開始)][0(去掉"虛"的維,相當於np.squeeze)]p.s. 感覺探索用了很多笨方法,但是整套下來基本思路倒是學到不少東西~
推薦閱讀:
TAG:TensorFlow | 深度學習DeepLearning |