读取修改caffemodel文件里的网络模型参数

[背景]
老师要我和学长实现一个多分辨率的检测网。想法是在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 np
import _init_paths
import collections
from collections import OrderedDict
caffe.set_mode_cpu
net0 = 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

你可能感兴趣的:(神经网络基础)