[背景]
老師要我和學長實現一個多解析度的檢測網。想法是在pvanet的基礎上,從conv2-3生出一個分支子網路,分支網的rpn和fc還有分類器都是照搬pvanet主幹網。用淺層特徵去檢測小目標,也就是單獨用小目標訓練分支網路,最後把分支網和主幹pvanet合并。所以用到caffemodel的讀取和修改。
1.caffemodel檔案中參數的讀取
caffemodel是二進位檔案,caffe有提供python介面進行讀取。讀取時需要網路結構檔案如test.prototxt和模型檔案如pvanet_frcnn_384_iter_5000.caffemodel。
# -*- coding:utf-8 -*-import numpy as npimport _init_pathsimport collectionsfrom collections import OrderedDictcaffe.set_mode_cpunet0 = caffe.Net('test23-4-24.prototxt',\ 'pvanet_frcnn_384_iter_5000.caffemodel',caffe.TEST) #TEST/TRAIN #我的python指令碼,prototxt,caffemodel檔案放在同級目錄下了,你的檔案路徑按需修改conv1_w = net0.params['conv1_1/conv'][0].data#模型參數都存在了net.params這個有序字典裡,對這就是python裡的那個字典,所以對模型參數的操作和對python字典操作一樣。['conv1_1/conv']是鍵名,[0]是權的維度keys0 = net0.params.keys()print net0.params.keys()for key0 in keys0: # 輸出所有層名,參數 print key0 try: print net1.params[key1][0].data except IndexError: continue try: print net1.params[key1][1].data except IndexError: continue try: print net1.params[key1][2].data except IndexError: continue finally: print '\n'
2.修改參數並儲存為新的模型檔案
一般改參數的值不太可能用到,倒是修改層,複製一些層參數給新的層可能用到。下面是把訓練好的分支網路參數併到pvanet主幹網的模型裡。[注]pvanet訓練時,指定一個模型檔案後,如果網路裡有模型中沒有的層,那這些層參數的初始化是隨機的,但是訓練得到的caffemodel是和網路結構匹配的。
net1 = caffe.Net('test_branch1.prototxt','branch1.caffemodel',caffe.TEST)keys1 = net1.params.keys()for key1 in keys1: net0.params.setdefault(key1, newparams[key1]) #net0 net1共有的層參數用net0的,net1專屬的新層,層名和參數一起加入net0 #net0的參數另存新檔新caffemodel net0.save('test_tree.caffemodel')
相關參考部落格:
http://blog.csdn.net/jiongjiongxia123/article/details/60965743
這裡有一個把fc層改為conv層的部落格很好用:http://nbviewer.jupyter.org/github/BVLC/caffe/blob/master/examples/net_surgery.ipynb