4'.deploy.prototxt
4'.deploy.prototxt
1:
神經網絡中,我們通過最小化神經網絡來訓練網絡,所以在訓練時最后一層是損失函數層(LOSS),
在測試時我們通過準確率來評價該網絡的優劣,因此最后一層是準確率層(ACCURACY)。
但是當我們真正要使用訓練好的數據時,我們需要的是網絡給我們輸入結果,對于分類問題,我們需要獲得分類結果,如下右圖最后一層我們得到
的是概率,我們不需要訓練及測試階段的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,分別代表訓練時與最后使用時的網絡結構。
?
我們一般將train與test放在同一個.prototxt中,需要在data層輸入數據的source,
而在使用時.prototxt只需要定義輸入圖片的大小通道數據參數即可,如下圖所示,分別是
$CAFFE_ROOT/models/caffe_reference_caffnet/train_val.prototxt?? , $CAFFE_ROOT/models/caffe_reference_caffnet/deploy.prototxt的data層
訓練時, solver.prototxt中使用的是rain_val.prototxt
?| 1 | ./build/tools/caffe/train -solver ./models/bvlc_reference_caffenet/solver.prototxt |
?使用上面訓練的網絡提取特征,使用的網絡模型是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文件:這是訓練與測試網絡配置文件
*_deploy.prototxt文件:這是模型構造文件在博文http://www.cnblogs.com/denny402/p/5685818.html?????中給出了生成 deploy.prototxt文件的Python源代碼,但是每個網絡不同,修改起來比較麻煩,下面給出該博文中以mnist為例生成deploy文件的源代碼,可根據自己網絡的設置做出相應修改:(下方代碼未測試)
[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層,但有一個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文件還是比較麻煩。我們在構建深度學習網絡時,肯定會先定義好訓練與測試網絡的配置文件——*_train_test.prototxt文件,我們可以通過修改*_train_test.prototxt文件 來生成 deploy 文件。以cifar10為例先簡單介紹一下兩者的區別。
?
(1)deploy 文件中的數據層更為簡單,即將*_train_test.prototxt文件中的輸入訓練數據lmdb與輸入測試數據lmdb這兩層刪除,取而代之的是,
[python]?
(2)卷積層和全連接層中weight_filler{}與bias_filler{}兩個參數不用再填寫,因為這兩個參數的值,由已經訓練好的模型*.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?? #權重w的學習率倍數 ?
} ?
param { ??? lr_mult: 2??? #偏置b的學習率倍數 ?
} ?
inner_product_param { ??? num_output: 10 ???
weight_filler { ????? type: "gaussian" ????? std: 0.1 ??? } ???
bias_filler { ????? type: "constant" ??? } ?
}
}
刪除后變為
[python]2) 輸出層?
*_train_test.prototxt文件
[python]注意在兩個文件中輸出層的類型都發生了變化一個是SoftmaxWithLoss,另一個是Softmax。另外為了方便區分訓練與應用輸出,訓練是輸出時是loss,應用時是prob。
下面給出CIFAR10中的配置文件cifar10_quick_train_test.prototxt與其模型構造文件? cifar10_quick.prototxt 直觀展示兩者的區別。
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 {?????????????? #將兩個輸入層修改為該層 ??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?? #權重W的學習率倍數 } ???param { ?????lr_mult: 2?? #偏置b的學習率倍數 ??} ???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激勵函數,這里需要注意的是,本層的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 轉換成deploy.prototxt
1.刪除輸入數據(如:type:data...inckude{phase: TRAIN}),然后添加一個數據維度描述。
?[plain]
?[plain]
4:
生成deploy文件
如果要把訓練好的模型拿來測試新的圖片,那必須得要一個deploy.prototxt文件,這個文件實際上和test.prototxt文件差不多,只是頭尾不相同而也。deploy文件沒有第一層數據輸入層,也沒有最后的Accuracy層,但最后多了一個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層,但有一個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()運行該文件后,會在mnist目錄下,生成一個deploy.prototxt文件。
這個文件不推薦用代碼來生成,反而麻煩。大家熟悉以后可以將test.prototxt復制一份,修改相應的地方就可以了,更加方便。
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.
總結
以上是生活随笔為你收集整理的4'.deploy.prototxt的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Caffe部署中的几个train-tes
- 下一篇: 根据 *_train_test.prot