日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

Caffe官方教程翻译(10):Editing model parameters

發(fā)布時間:2025/3/21 100 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Caffe官方教程翻译(10):Editing model parameters 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前言

最近打算重新跟著官方教程學習一下caffe,順便也自己翻譯了一下官方的文檔。自己也做了一些標注,都用斜體標記出來了。中間可能額外還加了自己遇到的問題或是運行結(jié)果之類的。歡迎交流指正,拒絕噴子!
官方教程的原文鏈接:
http://nbviewer.jupyter.org/github/BVLC/caffe/blob/master/examples/net_surgery.ipynb

Net Surgery

通過編輯模型參數(shù),可以將caffe網(wǎng)絡轉(zhuǎn)換成符合你特定需求的網(wǎng)絡。在pycaffe中,模型的數(shù)據(jù)、差值以及參數(shù)都是公開的。
開干吧!

import numpy as np import matplotlib.pyplot as plt %matplotlib inline# Make sure that caffe is on the python path: # caffe_root = '../' # this file is expected to be in {caffe_root}/examples # 修改為自己的caffe目錄的路徑 caffe_root = '/home/xhb/caffe/caffe/' import os os.chdir(os.path.join(caffe_root, 'examples')) import sys sys.path.insert(0, caffe_root + 'python')import caffe# configure plotting plt.rcParams['figure.figsize'] = (10, 10) plt.rcParams['image.interpolation'] = 'nearest' plt.rcParams['image.cmap'] = 'gray'

Designer Filters

為了說明如何加載,操作和保存參數(shù),我們把自己的濾波器設計為一個簡單的網(wǎng)絡,其只有一個卷積層。這個網(wǎng)絡有兩個blob,輸入數(shù)據(jù)層data和卷積輸出層conv。以及一個參數(shù),表示卷積層上權(quán)重和偏置參數(shù)的conv。

# Load the net, list its data and params, and filter an example image. caffe.set_mode_cpu() net = caffe.Net('net_surgery/conv.prototxt', caffe.TEST) print("blobs {}\nparams {}".format(net.blobs.keys(), net.params.keys()))# load image and prepare as a single input batch for Caffe im = np.array(caffe.io.load_image('images/cat_gray.jpg', color=False)).squeeze() plt.title('original image') plt.imshow(im) plt.axis('off')im_input = im[np.newaxis, np.newaxis, :, :] net.blobs['data'].reshape(*im_input.shape) net.blobs['data'].data[...] = im_input blobs ['data', 'conv'] params ['conv']

卷積層的權(quán)重都是由高斯噪聲初始化而來,而偏置則直接初始化為0.這些隨機濾波器給出的結(jié)果有點類似邊緣檢測的效果。

# helper show filter outputs def show_filters(net):net.forward()plt.figure()filt_min, filt_max = net.blobs['conv'].data.min(), net.blobs['conv'].data.max()for i in range(3):plt.subplot(1,4,i+2)plt.title("filter #{} output".format(i))plt.imshow(net.blobs['conv'].data[0, i], vmin=filt_min, vmax=filt_max)plt.tight_layout()plt.axis('off')# filter the image with initial show_filters(net)

增加濾波器的權(quán)重也會相應地增加其輸出。

# pick first filter output conv0 = net.blobs['conv'].data[0, 0] print("pre-surgery output mean {:.2f}".format(conv0.mean())) net.params['conv'][1].data[0] = 1. net.forward() print("post-surgery output mean {:.2f}".format(conv0.mean())) pre-surgery output mean -0.02 post-surgery output mean 0.98

改變?yōu)V波器的權(quán)重更令人興奮,因為我們可以分配任意的卷積核,比如高斯模糊、Sobel邊緣檢測算子,等等。一下操作將第0個濾波器的內(nèi)核變?yōu)榱烁咚鼓:?#xff0c;第1和第2個濾波器的內(nèi)核變?yōu)榱薙obel水平和垂直邊緣檢測算子。
看看第0個濾波器的輸出如何模糊處理的,第1個如何提取水平邊緣,第2個如何提取垂直邊緣。

ksize = net.params['conv'][0].data.shape[2:] # make Gaussian blur sigma = 1. y, x = np.mgrid[-ksize[0]//2 + 1 : ksize[0]//2 + 1, -ksize[1]//2 + 1 : ksize[1]//2 + 1] g = np.exp(-((x**2 + y**2) / (2.0 * sigma**2))) gaussian = (g / g.sum()).astype(np.float32) net.params['conv'][0].data[0] = gaussian # make Sobel operator for edge detection net.params['conv'][0].data[1:] = 0. sobel = np.array((-1, -2, -1, 0, 0, 0, 1, 2, 1), dtype=np.float32).reshape(3,3) net.params['conv'][0].data[1, 0, 1:-1, 1:-1] = sobel # horizontal net.params['conv'][0].data[2, 0, 1:-1, 1:-1] = sobel.T # vertical show_filters(net)

通過調(diào)整網(wǎng)絡,我們可以跨網(wǎng)絡移植參數(shù),通過自定義的每個對參數(shù)的操作進行規(guī)范化,并根據(jù)自己的方案進行轉(zhuǎn)換。

Casting a Classifier into a Fully Convolutional Network

我們使用caffe中的ImageNet模型——“CaffeNet”進行實驗,并將其轉(zhuǎn)換為一個完全的卷積網(wǎng)絡,以便對較大的輸入數(shù)據(jù)進行高效、密集的推理。這個模型生成的分類圖譜包含了給定的輸入尺寸,而不是單個分類的結(jié)果。特別是輸入為451××451,8××8的分類圖譜只需要3倍的時間就可以把輸出提高64倍。這里,我們通過撤銷重疊感受區(qū)域的計算,提升了卷積神經(jīng)網(wǎng)絡本身的高效性。
為此,我們將CaffeNet的InnerProduct矩陣內(nèi)積層換成了卷積層。這是唯一的改變:其他層的類型都與空間大小無關(guān)。卷積層是平移不變的,激活層是對每個元素的點積,等等。當通過fc6-conv卷積層進行計算之后,fc6內(nèi)積層(全連接層)變?yōu)樵趐ool5上的步長為1的6××6的卷積核?;氐綀D像空間,這里給出了對區(qū)域為227××227的圖像,對應每個像素步長為32的分類結(jié)果。請記住輸出/接收區(qū)域大小的計算公式,output = (input - kernel_size) / stride + 1,并通過下面的注釋理解。

# 注:比較兩個網(wǎng)絡的差異,可以根據(jù)上面所說的兩個網(wǎng)絡的差異比對一下是不是一致的 !diff net_surgery/bvlc_caffenet_full_conv.prototxt ../models/bvlc_reference_caffenet/deploy.prototxt 1,2c1 < # Fully convolutional network version of CaffeNet. < name: "CaffeNetConv" --- > name: "CaffeNet" 7,11c6 < input_param { < # initial shape for a fully convolutional network: < # the shape can be set for each input by reshape. < shape: { dim: 1 dim: 3 dim: 451 dim: 451 } < } --- > input_param { shape: { dim: 10 dim: 3 dim: 227 dim: 227 } } 157,158c152,153 < name: "fc6-conv" < type: "Convolution" --- > name: "fc6" > type: "InnerProduct" 160,161c155,156 < top: "fc6-conv" < convolution_param { --- > top: "fc6" > inner_product_param { 163d157 < kernel_size: 6 169,170c163,164 < bottom: "fc6-conv" < top: "fc6-conv" --- > bottom: "fc6" > top: "fc6" 175,176c169,170 < bottom: "fc6-conv" < top: "fc6-conv" --- > bottom: "fc6" > top: "fc6" 182,186c176,180 < name: "fc7-conv" < type: "Convolution" < bottom: "fc6-conv" < top: "fc7-conv" < convolution_param { --- > name: "fc7" > type: "InnerProduct" > bottom: "fc6" > top: "fc7" > inner_product_param { 188d181 < kernel_size: 1 194,195c187,188 < bottom: "fc7-conv" < top: "fc7-conv" --- > bottom: "fc7" > top: "fc7" 200,201c193,194 < bottom: "fc7-conv" < top: "fc7-conv" --- > bottom: "fc7" > top: "fc7" 207,211c200,204 < name: "fc8-conv" < type: "Convolution" < bottom: "fc7-conv" < top: "fc8-conv" < convolution_param { --- > name: "fc8" > type: "InnerProduct" > bottom: "fc7" > top: "fc8" > inner_product_param { 213d205 < kernel_size: 1 219c211 < bottom: "fc8-conv" --- > bottom: "fc8"

這個兩個網(wǎng)絡的結(jié)構(gòu)的唯一差異就是:將全連接層(內(nèi)積層)換成卷積核(濾波器)尺寸為6××6的卷積層,因為參考分類器模型將pool5的36個元素作為輸入,并且以步長為1進行分類。請注意,由于被修改的部分層被重命名了,所以在加載預訓練模型時,caffe不會盲目地加載舊參數(shù)。

# Load the original network and extract the fully connected layers' parameters. net = caffe.Net('../models/bvlc_reference_caffenet/deploy.prototxt', '../models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel', caffe.TEST) params = ['fc6', 'fc7', 'fc8'] # fc_params = {name: (weights, biases)} fc_params = {pr: (net.params[pr][0].data, net.params[pr][1].data) for pr in params}for fc in params:print '{} weights are {} dimensional and biases are {} dimensional'.format(fc, fc_params[fc][0].shape, fc_params[fc][1].shape) fc6 weights are (4096, 9216) dimensional and biases are (4096,) dimensional fc7 weights are (4096, 4096) dimensional and biases are (4096,) dimensional fc8 weights are (1000, 4096) dimensional and biases are (1000,) dimensional

考慮到內(nèi)積參數(shù)的形狀。權(quán)重參數(shù)的尺寸為輸入尺寸××輸出尺寸,而偏置參數(shù)的尺寸是輸出的尺寸。

# Load the fully convolutional network to transplant the parameters. net_full_conv = caffe.Net('net_surgery/bvlc_caffenet_full_conv.prototxt', '../models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel',caffe.TEST) params_full_conv = ['fc6-conv', 'fc7-conv', 'fc8-conv'] # conv_params = {name: (weights, biases)} conv_params = {pr: (net_full_conv.params[pr][0].data, net_full_conv.params[pr][1].data) for pr in params_full_conv}for conv in params_full_conv:print '{} weights are {} dimensional and biases are {} dimensional'.format(conv, conv_params[conv][0].shape, conv_params[conv][1].shape) fc6-conv weights are (4096, 256, 6, 6) dimensional and biases are (4096,) dimensional fc7-conv weights are (4096, 4096, 1, 1) dimensional and biases are (4096,) dimensional fc8-conv weights are (1000, 4096, 1, 1) dimensional and biases are (1000,) dimensional

卷積層的權(quán)重參數(shù)排列在output ×× input ×× height ×× width維度中。為了將內(nèi)積的權(quán)重參數(shù)映射到卷積核上,我們可以將內(nèi)積權(quán)重向量展開,放到channel ×× height ×× width的濾波器矩陣當中,單實際上這些矩陣在內(nèi)存中(作為行主要陣列)是相同的,因此我們可以直接分配它們。
卷積層的偏差值依然與原來內(nèi)積層的偏差值相同。
接下來開始移植!

for pr, pr_conv in zip(params, params_full_conv):conv_params[pr_conv][0].flat = fc_params[pr][0].flat # flat unrolls the arraysconv_params[pr_conv][1][...] = fc_params[pr][1]

接下來,保存新的模型權(quán)重。

net_full_conv.save('net_surgery/bvlc_caffenet_full_conv.caffemodel')

最后,讓我們用前面示例的貓圖片來制作分類圖,并將“tiger cat”這一類的置信率可視化為概率熱圖。這里在451 ×× 451的輸入圖片的重疊區(qū)域上給出8-by-8的預測結(jié)果。

import numpy as np import matplotlib.pyplot as plt %matplotlib inline# load input and configure preprocessing im = caffe.io.load_image('images/cat.jpg') transformer = caffe.io.Transformer({'data': net_full_conv.blobs['data'].data.shape}) transformer.set_mean('data', np.load('../python/caffe/imagenet/ilsvrc_2012_mean.npy').mean(1).mean(1)) transformer.set_transpose('data', (2,0,1)) transformer.set_channel_swap('data', (2,1,0)) transformer.set_raw_scale('data', 255.0)# make classification map by forward and print prediction indices at each location out = net_full_conv.forward_all(data=np.asarray([transformer.preprocess('data', im)])) print out['prob'][0].argmax(axis=0) # show net input and confidence map (probability of the top prediction at each location) plt.subplot(1, 2, 1) plt.imshow(transformer.deprocess('data', net_full_conv.blobs['data'].data[0])) plt.subplot(1, 2, 2) plt.imshow(out['prob'][0,281]) [[282 282 281 281 281 281 277 282][281 283 283 281 281 281 281 282][283 283 283 283 283 283 287 282][283 283 283 281 283 283 283 259][283 283 283 283 283 283 283 259][283 283 283 283 283 283 259 259][283 283 283 283 259 259 259 277][335 335 283 259 263 263 263 277]] <matplotlib.image.AxesImage at 0x7f163dc96d10>

這個分類預測結(jié)果給出了多種不同結(jié)果:比如282對應“tiger cat”,281對應“tabby”,283對應“persian”,等等,其他結(jié)果還對應了其他一些哺乳類動物。
通過這種方式,全連接層可以被提取為圖像上的密集特征(詳情查看net_full_conv.blobs['fc6'].data),也許這甚至比分類圖本身更有用。
注意,這個模型不是完全適合與華東窗口檢測法,因為它是針對整幅圖像的分類而訓練的。盡管如此,它依然可以工作得很棒?;瑒哟翱诜ㄓ柧毢臀⒄{(diào)都可以通過定義滑動窗口的ground truth和loss來完成,從而為每個位置制作loss圖譜,并像往常一樣解決。(這是給讀者的練習)

總結(jié)

以上是生活随笔為你收集整理的Caffe官方教程翻译(10):Editing model parameters的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。