一. 生成prototxt文件
这里使用python接口生成prototxt文件,比直接编辑prototxt文件更简洁一些。直接上例子:
from caffe import layers as L
from caffe import params as P
n = caffe.NetSpec()
n.data, n.dummy = L.ImageData(batch_size=batch_size, source=input_data, scale=1./255, ntop=2)
n.silence = L.Silence(n.dummy,ntop=0)
n.conv1a = L.Convolution(n.data, kernel_size=3, num_output=16, stride=2, pad=1, weight_filler=dict(type='xavier'))
n.relu1a = L.ReLU(n.conv1a, in_place=True, negative_slope= 0.2)
n.conv1b = L.Convolution(n.relu1a, kernel_size=3, num_output=16, stride=1, pad=1, weight_filler=dict(type='xavier'))
基本可以大概看出语法。 基本公式为:
n.layername = L.LayerType(bottom, params)
我发现 n['layer_name'] = L.layerType(bottom, **kwards)
也可以。
注意点一
参数部分,除了属于layer_param和与该layer类型一致的param部分可以直接写在里面的,其他要另外列出。比如:
n.L3_upsampled = L.Deconvolution(n.L3_disp6, convolution_param = dict(kernel_size=2, num_output=8, stride=2, pad=0, weight_filler=dict(type='xavier')))
这里Deconvolution layer 参数部分由于是convolution_layer, 类型与layer原类型不同,所以不能像上面的convolution layer一样写, 而要单独列出,可以看出其中的weight_filler也是这样单独列出的。
注意点二
如果top数不为1, 需要增加一个参数: ntop.
eg:
n.data, n.dummy = L.ImageData(batch_size=batch_size, source=input_data, scale=1./255, ntop=2)
注意点三
对于caffe中重复的参数,可以用列表传递。
二. Train and Test
- test
model_def = '../model/test.prototxt'
model_weights = '../snapshot/flow_iter_10800.caffemodel'
net = caffe.Net(model_def, model_weights, caffe.TEST)
这样得到了一个net对象
- train
solver = caffe.AdamSolver('./model/solver.prototxt')
当然Solver有好几种,也都类似。这里得到的solver, 同样包含net对象,即solver.net
, 类型同上面test得到的net.
这个net对象就可有用了. 划重点,不知道有什么用的对象,用dir(object)
查看属性
>>> dir(solver.net)
'backward',
'blob_loss_weights',
'blobs',
'bottom_names',
'copy_from',
'forward',
'forward_all',
'forward_backward_all',
'inputs',
'layers',
'load_hdf5',
'outputs',
'params',
'reshape',
'save',
'save_hdf5',
'set_input_arrays',
'share_with',
'top_names'] #此处截取后半段,
划重点:
1. net.blobs 包含net所有层的数据.
net.blobs['conv1'].data
即可获得conv1层的数据。
2. net.params 包含net所有层的参数,比如weight和bias.
net.params['conv1'][0].data
即可获得conv1层的weight。
这里的到的数据都是numpy的数组。
如果要重新赋值的话只需要将这些数据重新赋值即可。
前向传播
net.forward()
net前向传播一次
反向传播
net.backward()
net反向传播一次
前向传播加反向传播
solver.step(n)
net 前向一次,反向一次,进行n步。