有时候,我们需要将网络使用caffe代码实现,人工手写容易出问题。可以使用Python完成网络编写。
卷积层:
def generate_conv_layer_no_bias(name, bottom, top, weight, num_output, kernel_h, kernel_w, pad_h, pad_w, std=0.01):
conv_layer_str = '''layer {
name: "%s"
bottom: "%s"
top: "%s"
type: "Convolution"
param {
name: "%s"
lr_mult: 1
decay_mult: 1
}
convolution_param {
num_output: %d
kernel_h: %d
kernel_w: %d
pad_h: %d
pad_w: %d
stride: 1
bias_term: false
weight_filler { type: "gaussian" std: %.5f }
}
}\n'''%(name, bottom, top, weight, num_output, kernel_h, kernel_w, pad_h, pad_w, std)
return conv_layer_str
激活函数
def generate_activation_layer(name, bottom, act_type="ReLU"):
act_layer_str = '''layer {
name: "%s"
bottom: "%s"
top: "%s"
type: "%s"
}\n'''%(name, bottom, bottom, act_type)
return act_layer_str
Eltwise层SUM
def generate_eltwise_layer(name, bottom0, bottom1, top):
eltwise_layer_str = '''layer {
name: "%s"
bottom: "%s"
bottom: "%s"
top: "%s"
type: "Eltwise"
eltwise_param {
operation: SUM
}
}\n'''%(name, bottom0, bottom1, top)
return eltwise_layer_str
个人定义层:
def generate_slice_layer(name, bottom, top, axis, num):
slice_layer_str = '''layer {
name: "%s"
bottom: "%s"
type: "Slice"\n'''%(name, bottom)
for i in range(num):
top_i = top + '_' + str(i+1)
slice_layer_str += ''' top: "%s"\n'''%(top_i)
slice_layer_str += ''' slice_param {
axis: %d\n'''%(axis)
for i in range(num - 1):
slice_layer_str += ''' slice_point: %s\n'''%(str(i+1))
slice_layer_str += ''' }
}\n'''
return slice_layer_str
def generate_concat_layer(name, bottom, top, last, axis, num):
concat_layer_str = '''layer {
name: "%s"
type: "Concat"\n'''%(name)
for i in range(num - 1):
bottom_i = bottom + '_' + str(i+1)
concat_layer_str += ''' bottom: "%s"\n'''%(bottom_i)
bottom_last = last + '_' + str(num)
concat_layer_str += ''' bottom: "%s"\n'''%(bottom_last)
concat_layer_str += ''' top: "%s"
concat_param {
axis: %d
}
}\n'''%(top, axis)
return concat_layer_str
将这些层连接起来:
def generate_SCNN(args):
network_str = generate_slice_layer('Slice1', args.bottom, 'slice1', 2, args.h)
std = math.sqrt(2. / (args.kw * args.channel * 5))
# Build SCNN downward
for i in range(1, args.h):
name = 'SCNN_D_' + str(i)
if i == 1:
bottom = 'slice1_1'
else:
bottom = name
top = 'SCNN_D_' + str(i) + '/message'
target = 'slice1_' + str(i + 1)
summation = 'SCNN_D_' + str(i + 1)
network_str += generate_conv_layer_no_bias(name, bottom, top, 'SCNN_D_w', args.channel, 1, args.kw, 0, (args.kw-1)/2, std)
network_str += generate_activation_layer(name+'/relu', top)
network_str += generate_eltwise_layer(name+'/sum', top, target, summation)
# Build SCNN upward
for i in range(args.h, 1, -1):
name = 'SCNN_U_' + str(i)
top = name+ '/message'
if i == args.h:
bottom = 'SCNN_D_' + str(i)
else:
bottom = 'SCNN_U_' + str(i)
if i == 2:
target = 'slice1_1'
else:
target = 'SCNN_D_' + str(i - 1)
summation = 'SCNN_U_' + str(i - 1)
network_str += generate_conv_layer_no_bias(name, bottom, top, 'SCNN_U_w', args.channel, 1, args.kw, 0, (args.kw-1)/2, std)
network_str += generate_activation_layer(name+'/relu', top)
network_str += generate_eltwise_layer(name+'/sum', top, target, summation)
network_str += generate_concat_layer('Concat1', 'SCNN_U', 'SCNN_U', 'SCNN_D', 2, args.h)
network_str += generate_slice_layer('Slice2', 'SCNN_U', 'slice2', 3, args.w)
# Build SCNN rightward
for i in range(1, args.w):
name = 'SCNN_R_' + str(i)
if i == 1:
bottom = 'slice2_1'
else:
bottom = name
top = 'SCNN_R_' + str(i) + '/message'
target = 'slice2_' + str(i + 1)
summation = 'SCNN_R_' + str(i + 1)
network_str += generate_conv_layer_no_bias(name, bottom, top, 'SCNN_R_w', args.channel, args.kw, 1, (args.kw-1)/2, 0, std)
network_str += generate_activation_layer(name+'/relu', top)
network_str += generate_eltwise_layer(name+'/sum', top, target, summation)
# Build SCNN leftward
for i in range(args.w, 1, -1):
name = 'SCNN_L_' + str(i)
top = name + '/message'
if i == args.w:
bottom = 'SCNN_R_' + str(i)
else:
bottom = 'SCNN_L_' + str(i)
if i == 2:
target = 'slice2_1'
else:
target = 'SCNN_R_' + str(i - 1)
summation = 'SCNN_L_' + str(i - 1)
network_str += generate_conv_layer_no_bias(name, bottom, top, 'SCNN_L_w', args.channel, args.kw, 1, (args.kw-1)/2, 0, std)
network_str += generate_activation_layer(name+'/relu', top)
network_str += generate_eltwise_layer(name+'/sum', top, target, summation)
network_str += generate_concat_layer('Concat2', 'SCNN_L', 'SCNN', 'SCNN_R', 3, args.w)
return network_str
def main():
args = parse_args()
scnn_pt = generate_SCNN(args)
fp = open(args.output, 'w')
fp.write(scnn_pt)
fp.close()
if __name__ == '__main__':
main()
其实就是将特定的参数参数传入到字符传中,写到文件中。
样例:https://download.csdn.net/download/ziyouyi111/10507394