4'.deploy.prototxt
4'.deploy.prototxt
1:
神經(jīng)網(wǎng)絡(luò)中,我們通過最小化神經(jīng)網(wǎng)絡(luò)來訓(xùn)練網(wǎng)絡(luò),所以在訓(xùn)練時(shí)最后一層是損失函數(shù)層(LOSS),
在測試時(shí)我們通過準(zhǔn)確率來評價(jià)該網(wǎng)絡(luò)的優(yōu)劣,因此最后一層是準(zhǔn)確率層(ACCURACY)。
但是當(dāng)我們真正要使用訓(xùn)練好的數(shù)據(jù)時(shí),我們需要的是網(wǎng)絡(luò)給我們輸入結(jié)果,對于分類問題,我們需要獲得分類結(jié)果,如下右圖最后一層我們得到
的是概率,我們不需要訓(xùn)練及測試階段的LOSS,ACCURACY層了。
下圖是能過$CAFFE_ROOT/python/draw_net.py繪制$CAFFE_ROOT/models/caffe_reference_caffnet/train_val.prototxt?? , $CAFFE_ROOT/models/caffe_reference_caffnet/deploy.prototxt,分別代表訓(xùn)練時(shí)與最后使用時(shí)的網(wǎng)絡(luò)結(jié)構(gòu)。
?
我們一般將train與test放在同一個(gè).prototxt中,需要在data層輸入數(shù)據(jù)的source,
而在使用時(shí).prototxt只需要定義輸入圖片的大小通道數(shù)據(jù)參數(shù)即可,如下圖所示,分別是
$CAFFE_ROOT/models/caffe_reference_caffnet/train_val.prototxt?? , $CAFFE_ROOT/models/caffe_reference_caffnet/deploy.prototxt的data層
訓(xùn)練時(shí), solver.prototxt中使用的是rain_val.prototxt
?| 1 | ./build/tools/caffe/train -solver ./models/bvlc_reference_caffenet/solver.prototxt |
?使用上面訓(xùn)練的網(wǎng)絡(luò)提取特征,使用的網(wǎng)絡(luò)模型是deploy.prototxt
?| 1 | ./build/tools/extract_features.bin models/bvlc_refrence_caffenet.caffemodel models/bvlc_refrence_caffenet/deploy.prototxt |
????? 。。
?
2:
(1)介紹?*_train_test.prototxt文件與 *_deploy.prototxt文件的不http://blog.csdn.net/sunshine_in_moon/article/details/49472901????
(2)生成deploy文件的Python代碼:http://www.cnblogs.com/denny402/p/5685818.html???????
*_train_test.prototxt文件:這是訓(xùn)練與測試網(wǎng)絡(luò)配置文件
*_deploy.prototxt文件:這是模型構(gòu)造文件在博文http://www.cnblogs.com/denny402/p/5685818.html?????中給出了生成 deploy.prototxt文件的Python源代碼,但是每個(gè)網(wǎng)絡(luò)不同,修改起來比較麻煩,下面給出該博文中以mnist為例生成deploy文件的源代碼,可根據(jù)自己網(wǎng)絡(luò)的設(shè)置做出相應(yīng)修改:(下方代碼未測試)
[python] # -*- coding: utf-8 -*-from caffe import layers as L,params as P,to_proto root='/home/xxx/' deploy=root+'mnist/deploy.prototxt' #文件保存路徑def create_deploy():#少了第一層,data層conv1=L.Convolution(bottom='data', kernel_size=5, stride=1,num_output=20, pad=0,weight_filler=dict(type='xavier'))pool1=L.Pooling(conv1, pool=P.Pooling.MAX, kernel_size=2, stride=2)conv2=L.Convolution(pool1, kernel_size=5, stride=1,num_output=50, pad=0,weight_filler=dict(type='xavier'))pool2=L.Pooling(conv2, pool=P.Pooling.MAX, kernel_size=2, stride=2)fc3=L.InnerProduct(pool2, num_output=500,weight_filler=dict(type='xavier'))relu3=L.ReLU(fc3, in_place=True)fc4 = L.InnerProduct(relu3, num_output=10,weight_filler=dict(type='xavier'))#最后沒有accuracy層,但有一個(gè)Softmax層prob=L.Softmax(fc4)return to_proto(prob) def write_deploy(): with open(deploy, 'w') as f:f.write('name:"Lenet"\n')f.write('input:"data"\n')f.write('input_dim:1\n')f.write('input_dim:3\n')f.write('input_dim:28\n')f.write('input_dim:28\n')f.write(str(create_deploy())) if __name__ == '__main__':write_deploy()?
用代碼生成deploy文件還是比較麻煩。我們在構(gòu)建深度學(xué)習(xí)網(wǎng)絡(luò)時(shí),肯定會先定義好訓(xùn)練與測試網(wǎng)絡(luò)的配置文件——*_train_test.prototxt文件,我們可以通過修改*_train_test.prototxt文件 來生成 deploy 文件。以cifar10為例先簡單介紹一下兩者的區(qū)別。
?
(1)deploy 文件中的數(shù)據(jù)層更為簡單,即將*_train_test.prototxt文件中的輸入訓(xùn)練數(shù)據(jù)lmdb與輸入測試數(shù)據(jù)lmdb這兩層刪除,取而代之的是,
[python]?
(2)卷積層和全連接層中weight_filler{}與bias_filler{}兩個(gè)參數(shù)不用再填寫,因?yàn)檫@兩個(gè)參數(shù)的值,由已經(jīng)訓(xùn)練好的模型*.caffemodel文件提供。如下所示代碼,將*_train_test.prototxt文件中的weight_filler、bias_filler全部刪除。
layer {??# weight_filler、bias_filler刪除??
name: "ip2" ?
type: "InnerProduct" ?
bottom: "ip1" ? top: "ip2" ?
param { ???
lr_mult: 1?? #權(quán)重w的學(xué)習(xí)率倍數(shù) ?
} ?
param { ??? lr_mult: 2??? #偏置b的學(xué)習(xí)率倍數(shù) ?
} ?
inner_product_param { ??? num_output: 10 ???
weight_filler { ????? type: "gaussian" ????? std: 0.1 ??? } ???
bias_filler { ????? type: "constant" ??? } ?
}
}
刪除后變?yōu)?/p> [python]
2) 輸出層?
*_train_test.prototxt文件
[python]注意在兩個(gè)文件中輸出層的類型都發(fā)生了變化一個(gè)是SoftmaxWithLoss,另一個(gè)是Softmax。另外為了方便區(qū)分訓(xùn)練與應(yīng)用輸出,訓(xùn)練是輸出時(shí)是loss,應(yīng)用時(shí)是prob。
下面給出CIFAR10中的配置文件cifar10_quick_train_test.prototxt與其模型構(gòu)造文件? cifar10_quick.prototxt 直觀展示兩者的區(qū)別。
cifar10_quick_train_test.prototxt文件代碼
?| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 | cifar10_quick_train_test.prototxt文件代碼 name: "CIFAR10_quick" ?layer {?????????????? #該層去掉 ??name: "cifar" ???type: "Data" ???top: "data" ???top: "label" ???include { ?????phase: TRAIN ???} ???transform_param { ?????mean_file: "examples/cifar10/mean.binaryproto" ???} ???data_param { ?????source: "examples/cifar10/cifar10_train_lmdb" ?????batch_size: 100 ?????backend: LMDB ???} ?} ?layer {???????????? #該層去掉 ??name: "cifar" ???type: "Data" ???top: "data" ???top: "label" ???include { ?????phase: TEST ???} ???transform_param { ?????mean_file: "examples/cifar10/mean.binaryproto" ???} ???data_param { ?????source: "examples/cifar10/cifar10_test_lmdb" ?????batch_size: 100 ?????backend: LMDB ???} ?} ?layer {??????????????????????? #將下方的weight_filler、bias_filler全部刪除 ??name: "conv1" ???type: "Convolution" ???bottom: "data" ???top: "conv1" ???param { ?????lr_mult: 1 ???} ???param { ?????lr_mult: 2 ???} ???convolution_param { ?????num_output: 32 ?????pad: 2 ?????kernel_size: 5 ?????stride: 1 ?????weight_filler { ???????type: "gaussian" ???????std: 0.0001 ?????} ?????bias_filler { ???????type: "constant" ?????} ???} ?} ?layer { ???name: "pool1" ???type: "Pooling" ???bottom: "conv1" ???top: "pool1" ???pooling_param { ?????pool: MAX ?????kernel_size: 3 ?????stride: 2 ???} ?} ?layer { ???name: "relu1" ???type: "ReLU" ???bottom: "pool1" ???top: "pool1" ?} ?layer {???????????????????????? #weight_filler、bias_filler刪除 ??name: "conv2" ???type: "Convolution" ???bottom: "pool1" ???top: "conv2" ???param { ?????lr_mult: 1 ???} ???param { ?????lr_mult: 2 ???} ???convolution_param { ?????num_output: 32 ?????pad: 2 ?????kernel_size: 5 ?????stride: 1 ?????weight_filler { ???????type: "gaussian" ???????std: 0.01 ?????} ?????bias_filler { ???????type: "constant" ?????} ???} ?} ?layer { ???name: "relu2" ???type: "ReLU" ???bottom: "conv2" ???top: "conv2" ?} ?layer { ???name: "pool2" ???type: "Pooling" ???bottom: "conv2" ???top: "pool2" ???pooling_param { ?????pool: AVE ?????kernel_size: 3 ?????stride: 2 ???} ?} ?layer {???????????????????????? #weight_filler、bias_filler刪除 ??name: "conv3" ???type: "Convolution" ???bottom: "pool2" ???top: "conv3" ???param { ?????lr_mult: 1 ???} ???param { ?????lr_mult: 2 ???} ???convolution_param { ?????num_output: 64 ?????pad: 2 ?????kernel_size: 5 ?????stride: 1 ?????weight_filler { ???????type: "gaussian" ???????std: 0.01 ?????} ?????bias_filler { ???????type: "constant" ?????} ???} ?} ?layer { ???name: "relu3" ???type: "ReLU" ???bottom: "conv3" ???top: "conv3" ?} ?layer { ???name: "pool3" ???type: "Pooling" ???bottom: "conv3" ???top: "pool3" ???pooling_param { ?????pool: AVE ?????kernel_size: 3 ?????stride: 2 ???} ?} ?layer {?????????????????????? #weight_filler、bias_filler刪除 ??name: "ip1" ???type: "InnerProduct" ???bottom: "pool3" ???top: "ip1" ???param { ?????lr_mult: 1 ???} ???param { ?????lr_mult: 2 ???} ???inner_product_param { ?????num_output: 64 ?????weight_filler { ???????type: "gaussian" ???????std: 0.1 ?????} ?????bias_filler { ???????type: "constant" ?????} ???} ?} ?layer {????????????????????????????? # weight_filler、bias_filler刪除 ??name: "ip2" ???type: "InnerProduct" ???bottom: "ip1" ???top: "ip2" ???param { ?????lr_mult: 1 ???} ???param { ?????lr_mult: 2 ???} ???inner_product_param { ?????num_output: 10 ?????weight_filler { ???????type: "gaussian" ???????std: 0.1 ?????} ?????bias_filler { ???????type: "constant" ?????} ???} ?} ?layer {????????????????????????????????? #將該層刪除 ??name: "accuracy" ???type: "Accuracy" ???bottom: "ip2" ???bottom: "label" ???top: "accuracy" ???include { ?????phase: TEST ???} ?} ?layer {???????????????????????????????? #修改 ??name: "loss"?????? #---loss? 修改為? prob ???type: "SoftmaxWithLoss"???????????? # SoftmaxWithLoss 修改為 softmax ???bottom: "ip2" ???bottom: "label"????????? #去掉 ??top: "loss" ?} 以下為cifar10_quick.prototxt layer {?????????????? #將兩個(gè)輸入層修改為該層 ??name: "data" ???type: "Input" ???top: "data" ???input_param { shape: { dim: 1 dim: 3 dim: 32 dim: 32 } }????? #注意shape中變量值的修改,CIFAR10中的 *_train_test.protxt文件中沒有 crop_size ?} ?layer { ???name: "conv1" ???type: "Convolution" ???bottom: "data" ???top: "conv1" ???param { ?????lr_mult: 1?? #權(quán)重W的學(xué)習(xí)率倍數(shù) } ???param { ?????lr_mult: 2?? #偏置b的學(xué)習(xí)率倍數(shù) ??} ???convolution_param { ?????num_output: 32 ?????pad: 2?? #加邊為2 ????kernel_size: 5 ?????stride: 1 ???} ?} ?layer { ???name: "pool1" ???type: "Pooling" ???bottom: "conv1" ???top: "pool1" ???pooling_param { ?????pool: MAX??? #Max Pooling ????kernel_size: 3 ?????stride: 2 ???} ?} ?layer { ???name: "relu1" ???type: "ReLU" ???bottom: "pool1" ???top: "pool1" ?} ?layer { ???name: "conv2" ???type: "Convolution" ???bottom: "pool1" ???top: "conv2" ???param { ?????lr_mult: 1 ???} ???param { ?????lr_mult: 2 ???} ???convolution_param { ?????num_output: 32 ?????pad: 2 ?????kernel_size: 5 ?????stride: 1 ???} ?} ?layer { ???name: "relu2" ???type: "ReLU" ???bottom: "conv2" ???top: "conv2" ?} ?layer { ???name: "pool2" ???type: "Pooling" ???bottom: "conv2" ???top: "pool2" ???pooling_param { ?????pool: AVE?? #均值池化 ????kernel_size: 3 ?????stride: 2 ???} ?} ?layer { ???name: "conv3" ???type: "Convolution" ???bottom: "pool2" ???top: "conv3" ???param { ?????lr_mult: 1 ???} ???param { ?????lr_mult: 2 ???} ???convolution_param { ?????num_output: 64 ?????pad: 2 ?????kernel_size: 5 ?????stride: 1 ???} ?} ?layer { ???name: "relu3" ???type: "ReLU"? #使用ReLU激勵函數(shù),這里需要注意的是,本層的bottom和top都是conv3> ???bottom: "conv3" ???top: "conv3" ?} ?layer { ???name: "pool3" ???type: "Pooling" ???bottom: "conv3" ???top: "pool3" ???pooling_param { ?????pool: AVE ?kernel_size: 3 ?????stride: 2 ???} ?} ?layer { ???name: "ip1" ???type: "InnerProduct" ???bottom: "pool3" ???top: "ip1" ???param { ?????lr_mult: 1 ???} ???param { ?????lr_mult: 2 ???} ???inner_product_param { ?????num_output: 64 ???} ?} ?layer { ???name: "ip2" ???type: "InnerProduct" ???bottom: "ip1" ???top: "ip2" ???param { ?????lr_mult: 1 ???} ???param { ?????lr_mult: 2 ???} ???inner_product_param { ?????num_output: 10 ???} ?} layer { ???name: "prob" ???type: "Softmax" ???bottom: "ip2" ???top: "prob" ?} |
?3:
將train_val.prototxt 轉(zhuǎn)換成deploy.prototxt
1.刪除輸入數(shù)據(jù)(如:type:data...inckude{phase: TRAIN}),然后添加一個(gè)數(shù)據(jù)維度描述。
?[plain]
?[plain]
4:
生成deploy文件
如果要把訓(xùn)練好的模型拿來測試新的圖片,那必須得要一個(gè)deploy.prototxt文件,這個(gè)文件實(shí)際上和test.prototxt文件差不多,只是頭尾不相同而也。deploy文件沒有第一層數(shù)據(jù)輸入層,也沒有最后的Accuracy層,但最后多了一個(gè)Softmax概率層。
這里我們采用代碼的方式來自動生成該文件,以mnist為例。
deploy.py
# -*- coding: utf-8 -*-from caffe import layers as L,params as P,to_proto root=‘/home/xxx/‘ deploy=root+‘mnist/deploy.prototxt‘ #文件保存路徑 def create_deploy(): #少了第一層,data層 conv1=L.Convolution(bottom=‘data‘, kernel_size=5, stride=1,num_output=20, pad=0,weight_filler=dict(type=‘xavier‘)) pool1=L.Pooling(conv1, pool=P.Pooling.MAX, kernel_size=2, stride=2) conv2=L.Convolution(pool1, kernel_size=5, stride=1,num_output=50, pad=0,weight_filler=dict(type=‘xavier‘)) pool2=L.Pooling(conv2, pool=P.Pooling.MAX, kernel_size=2, stride=2) fc3=L.InnerProduct(pool2, num_output=500,weight_filler=dict(type=‘xavier‘)) relu3=L.ReLU(fc3, in_place=True) fc4 = L.InnerProduct(relu3, num_output=10,weight_filler=dict(type=‘xavier‘)) #最后沒有accuracy層,但有一個(gè)Softmax層 prob=L.Softmax(fc4) return to_proto(prob) def write_deploy(): with open(deploy, ‘w‘) as f: f.write(‘name:"Lenet"\n‘) f.write(‘input:"data"\n‘) f.write(‘input_dim:1\n‘) f.write(‘input_dim:3\n‘) f.write(‘input_dim:28\n‘) f.write(‘input_dim:28\n‘) f.write(str(create_deploy())) if __name__ == ‘__main__‘: write_deploy()運(yùn)行該文件后,會在mnist目錄下,生成一個(gè)deploy.prototxt文件。
這個(gè)文件不推薦用代碼來生成,反而麻煩。大家熟悉以后可以將test.prototxt復(fù)制一份,修改相應(yīng)的地方就可以了,更加方便。
5:Convert train_val.prototxt to deploy.prototxt
1 ReplyHere is a google groups link.
?
If you have preprocessing layers, things get a bit more tricky.
For example, in train_val.prototxt, which includes the “data” layer, I insert a layer to calculate the mean over the channels of input data,
layer { name: “mean” type: “Convolution” bottom: “data” top: “data” param { lr_mult: 0 decay_mult: 0 }
…}
between “data” layer and “conv1” layer (with bottom:”data” / top:”conv1″).
In deploy.prototxt,?the “mean” layer has to be retained, yet its container needs to be changed! i.e.
layer { name: “mean” type: “Convolution” bottom: “data” top: “mean“ param { lr_mult: 0 decay_mult: 0 }
…}
and the “conv1” layer needs to be changed accordingly, (?bottom:”mean”/ top:”conv1″ ).
It’s fine to use train_val.prototxt with “mean” layer using “data” container in the training phase, and use deploy.prototxt with “mean” layer using “mean” container in the testing phase in python. The learned caffemodel can be loaded correctly.
總結(jié)
以上是生活随笔為你收集整理的4'.deploy.prototxt的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Caffe部署中的几个train-tes
- 下一篇: 根据 *_train_test.prot