问题
What I want is, After loading a net, I will decompose some certain layers and save the new net. For example
Orignial net:
data -> conv1 -> conv2 -> fc1 -> fc2 -> softmax;
New net:
data -> conv1_1 -> conv1_2 -> conv2_1 -> conv2_2 -> fc1 -> fc2 -> softmax
Therefore, during this process, I stuck in the following situation:
1. How to new a certain layer with specified layer parameters in pycaffe
?
2. How to copy the layer parameters from existing layers(such as fc1
and fc2
above)?
I know by using caffe::net_spec
, we can define a new net manually. But caffe::net_spec
can not specify a layer from a existing one(e.g: fc1
).
回答1:
I didn't see how to load in previous nets with net_spec but you can always use the protobuf objects directly. (I use your network structure as an example)
import caffe.proto.caffe_pb2 as caffe_pb2
import google.protobuf as pb
from caffe import layers as L
net = caffe_pb2.NetParameter()
with open('net.prototxt', 'r') as f:
pb.text_format.Merge(f.read(), net)
#example of modifing the network:
net.layer[1].name = 'conv1_1'
net.layer[1].top[0] = 'conv1_1'
net.layer[2].name = 'conv1_2'
net.layer[2].top[0] = 'conv1_2'
net.layer[2].bottom[0] = 'conv1_1'
net.layer[3].bottom[0] = 'conv2_2'
#example of adding new layers (using net_spec):
conv2_1 = net.layer.add()
conv2_1.CopyFrom(L.Convolution(kernel_size=7, stride=1, num_output=48, pad=0).to_proto().layer[0])
conv2_1.name = 'conv2_1'
conv2_1.top[0] = 'conv2_1'
conv2_1.bottom.add('conv1_2')
conv2_2 = net.layer.add()
conv2_2.CopyFrom(L.Convolution(kernel_size=7, stride=1, num_output=48, pad=0).to_proto().layer[0])
conv2_2.name = 'conv2_2'
conv2_2.top[0] = 'conv2_2'
conv2_2.bottom.add('conv2_1')
# then write back out:
with open('net2.prototxt, 'w') as f:
f.write(pb.text_format.MessageToString(net))
Also see here as a guide on protocol buffers in python and here for the current caffe message formats.
来源:https://stackoverflow.com/questions/35423309/how-reconstruct-the-caffe-net-by-using-pycaffe