keras icon indicating copy to clipboard operation
keras copied to clipboard

Squeeze net conversion

Open AliaMYH opened this issue 7 years ago • 3 comments

Is this module able to convert the caffe implementation of squeeze net into keras?

This is the train_val.prototxt:

layer { name: "data" type: "Data" top: "data" top: "label" include { phase: TRAIN } transform_param { crop_size: 227 mean_value: 104 mean_value: 117 mean_value: 123 }

} layer { name: "data" type: "Data" top: "data" top: "label" include { phase: TEST } transform_param { crop_size: 227 mean_value: 104 mean_value: 117 mean_value: 123 }

} layer { name: "conv1" type: "Convolution" bottom: "data" top: "conv1" convolution_param { num_output: 64 kernel_size: 3 stride: 2 weight_filler { type: "xavier" } } } layer { name: "relu_conv1" type: "ReLU" bottom: "conv1" top: "conv1" } layer { name: "pool1" type: "Pooling" bottom: "conv1" top: "pool1" pooling_param { pool: MAX kernel_size: 3 stride: 2 } } layer { name: "fire2/squeeze1x1" type: "Convolution" bottom: "pool1" top: "fire2/squeeze1x1" convolution_param { num_output: 16 kernel_size: 1 weight_filler { type: "xavier" } } } layer { name: "fire2/relu_squeeze1x1" type: "ReLU" bottom: "fire2/squeeze1x1" top: "fire2/squeeze1x1" } layer { name: "fire2/expand1x1" type: "Convolution" bottom: "fire2/squeeze1x1" top: "fire2/expand1x1" convolution_param { num_output: 64 kernel_size: 1 weight_filler { type: "xavier" } } } layer { name: "fire2/relu_expand1x1" type: "ReLU" bottom: "fire2/expand1x1" top: "fire2/expand1x1" } layer { name: "fire2/expand3x3" type: "Convolution" bottom: "fire2/squeeze1x1" top: "fire2/expand3x3" convolution_param { num_output: 64 pad: 1 kernel_size: 3 weight_filler { type: "xavier" } } } layer { name: "fire2/relu_expand3x3" type: "ReLU" bottom: "fire2/expand3x3" top: "fire2/expand3x3" } layer { name: "fire2/concat" type: "Concat" bottom: "fire2/expand1x1" bottom: "fire2/expand3x3" top: "fire2/concat" } layer { name: "fire3/squeeze1x1" type: "Convolution" bottom: "fire2/concat" top: "fire3/squeeze1x1" convolution_param { num_output: 16 kernel_size: 1 weight_filler { type: "xavier" } } } layer { name: "fire3/relu_squeeze1x1" type: "ReLU" bottom: "fire3/squeeze1x1" top: "fire3/squeeze1x1" } layer { name: "fire3/expand1x1" type: "Convolution" bottom: "fire3/squeeze1x1" top: "fire3/expand1x1" convolution_param { num_output: 64 kernel_size: 1 weight_filler { type: "xavier" } } } layer { name: "fire3/relu_expand1x1" type: "ReLU" bottom: "fire3/expand1x1" top: "fire3/expand1x1" } layer { name: "fire3/expand3x3" type: "Convolution" bottom: "fire3/squeeze1x1" top: "fire3/expand3x3" convolution_param { num_output: 64 pad: 1 kernel_size: 3 weight_filler { type: "xavier" } } } layer { name: "fire3/relu_expand3x3" type: "ReLU" bottom: "fire3/expand3x3" top: "fire3/expand3x3" } layer { name: "fire3/concat" type: "Concat" bottom: "fire3/expand1x1" bottom: "fire3/expand3x3" top: "fire3/concat" } layer { name: "pool3" type: "Pooling" bottom: "fire3/concat" top: "pool3" pooling_param { pool: MAX kernel_size: 3 stride: 2 } } layer { name: "fire4/squeeze1x1" type: "Convolution" bottom: "pool3" top: "fire4/squeeze1x1" convolution_param { num_output: 32 kernel_size: 1 weight_filler { type: "xavier" } } } layer { name: "fire4/relu_squeeze1x1" type: "ReLU" bottom: "fire4/squeeze1x1" top: "fire4/squeeze1x1" } layer { name: "fire4/expand1x1" type: "Convolution" bottom: "fire4/squeeze1x1" top: "fire4/expand1x1" convolution_param { num_output: 128 kernel_size: 1 weight_filler { type: "xavier" } } } layer { name: "fire4/relu_expand1x1" type: "ReLU" bottom: "fire4/expand1x1" top: "fire4/expand1x1" } layer { name: "fire4/expand3x3" type: "Convolution" bottom: "fire4/squeeze1x1" top: "fire4/expand3x3" convolution_param { num_output: 128 pad: 1 kernel_size: 3 weight_filler { type: "xavier" } } } layer { name: "fire4/relu_expand3x3" type: "ReLU" bottom: "fire4/expand3x3" top: "fire4/expand3x3" } layer { name: "fire4/concat" type: "Concat" bottom: "fire4/expand1x1" bottom: "fire4/expand3x3" top: "fire4/concat" } layer { name: "fire5/squeeze1x1" type: "Convolution" bottom: "fire4/concat" top: "fire5/squeeze1x1" convolution_param { num_output: 32 kernel_size: 1 weight_filler { type: "xavier" } } } layer { name: "fire5/relu_squeeze1x1" type: "ReLU" bottom: "fire5/squeeze1x1" top: "fire5/squeeze1x1" } layer { name: "fire5/expand1x1" type: "Convolution" bottom: "fire5/squeeze1x1" top: "fire5/expand1x1" convolution_param { num_output: 128 kernel_size: 1 weight_filler { type: "xavier" } } } layer { name: "fire5/relu_expand1x1" type: "ReLU" bottom: "fire5/expand1x1" top: "fire5/expand1x1" } layer { name: "fire5/expand3x3" type: "Convolution" bottom: "fire5/squeeze1x1" top: "fire5/expand3x3" convolution_param { num_output: 128 pad: 1 kernel_size: 3 weight_filler { type: "xavier" } } } layer { name: "fire5/relu_expand3x3" type: "ReLU" bottom: "fire5/expand3x3" top: "fire5/expand3x3" } layer { name: "fire5/concat" type: "Concat" bottom: "fire5/expand1x1" bottom: "fire5/expand3x3" top: "fire5/concat" } layer { name: "pool5" type: "Pooling" bottom: "fire5/concat" top: "pool5" pooling_param { pool: MAX kernel_size: 3 stride: 2 } } layer { name: "fire6/squeeze1x1" type: "Convolution" bottom: "pool5" top: "fire6/squeeze1x1" convolution_param { num_output: 48 kernel_size: 1 weight_filler { type: "xavier" } } } layer { name: "fire6/relu_squeeze1x1" type: "ReLU" bottom: "fire6/squeeze1x1" top: "fire6/squeeze1x1" } layer { name: "fire6/expand1x1" type: "Convolution" bottom: "fire6/squeeze1x1" top: "fire6/expand1x1" convolution_param { num_output: 192 kernel_size: 1 weight_filler { type: "xavier" } } } layer { name: "fire6/relu_expand1x1" type: "ReLU" bottom: "fire6/expand1x1" top: "fire6/expand1x1" } layer { name: "fire6/expand3x3" type: "Convolution" bottom: "fire6/squeeze1x1" top: "fire6/expand3x3" convolution_param { num_output: 192 pad: 1 kernel_size: 3 weight_filler { type: "xavier" } } } layer { name: "fire6/relu_expand3x3" type: "ReLU" bottom: "fire6/expand3x3" top: "fire6/expand3x3" } layer { name: "fire6/concat" type: "Concat" bottom: "fire6/expand1x1" bottom: "fire6/expand3x3" top: "fire6/concat" } layer { name: "fire7/squeeze1x1" type: "Convolution" bottom: "fire6/concat" top: "fire7/squeeze1x1" convolution_param { num_output: 48 kernel_size: 1 weight_filler { type: "xavier" } } } layer { name: "fire7/relu_squeeze1x1" type: "ReLU" bottom: "fire7/squeeze1x1" top: "fire7/squeeze1x1" } layer { name: "fire7/expand1x1" type: "Convolution" bottom: "fire7/squeeze1x1" top: "fire7/expand1x1" convolution_param { num_output: 192 kernel_size: 1 weight_filler { type: "xavier" } } } layer { name: "fire7/relu_expand1x1" type: "ReLU" bottom: "fire7/expand1x1" top: "fire7/expand1x1" } layer { name: "fire7/expand3x3" type: "Convolution" bottom: "fire7/squeeze1x1" top: "fire7/expand3x3" convolution_param { num_output: 192 pad: 1 kernel_size: 3 weight_filler { type: "xavier" } } } layer { name: "fire7/relu_expand3x3" type: "ReLU" bottom: "fire7/expand3x3" top: "fire7/expand3x3" } layer { name: "fire7/concat" type: "Concat" bottom: "fire7/expand1x1" bottom: "fire7/expand3x3" top: "fire7/concat" } layer { name: "fire8/squeeze1x1" type: "Convolution" bottom: "fire7/concat" top: "fire8/squeeze1x1" convolution_param { num_output: 64 kernel_size: 1 weight_filler { type: "xavier" } } } layer { name: "fire8/relu_squeeze1x1" type: "ReLU" bottom: "fire8/squeeze1x1" top: "fire8/squeeze1x1" } layer { name: "fire8/expand1x1" type: "Convolution" bottom: "fire8/squeeze1x1" top: "fire8/expand1x1" convolution_param { num_output: 256 kernel_size: 1 weight_filler { type: "xavier" } } } layer { name: "fire8/relu_expand1x1" type: "ReLU" bottom: "fire8/expand1x1" top: "fire8/expand1x1" } layer { name: "fire8/expand3x3" type: "Convolution" bottom: "fire8/squeeze1x1" top: "fire8/expand3x3" convolution_param { num_output: 256 pad: 1 kernel_size: 3 weight_filler { type: "xavier" } } } layer { name: "fire8/relu_expand3x3" type: "ReLU" bottom: "fire8/expand3x3" top: "fire8/expand3x3" } layer { name: "fire8/concat" type: "Concat" bottom: "fire8/expand1x1" bottom: "fire8/expand3x3" top: "fire8/concat" } layer { name: "fire9/squeeze1x1" type: "Convolution" bottom: "fire8/concat" top: "fire9/squeeze1x1" convolution_param { num_output: 64 kernel_size: 1 weight_filler { type: "xavier" } } } layer { name: "fire9/relu_squeeze1x1" type: "ReLU" bottom: "fire9/squeeze1x1" top: "fire9/squeeze1x1" } layer { name: "fire9/expand1x1" type: "Convolution" bottom: "fire9/squeeze1x1" top: "fire9/expand1x1" convolution_param { num_output: 256 kernel_size: 1 weight_filler { type: "xavier" } } } layer { name: "fire9/relu_expand1x1" type: "ReLU" bottom: "fire9/expand1x1" top: "fire9/expand1x1" } layer { name: "fire9/expand3x3" type: "Convolution" bottom: "fire9/squeeze1x1" top: "fire9/expand3x3" convolution_param { num_output: 256 pad: 1 kernel_size: 3 weight_filler { type: "xavier" } } } layer { name: "fire9/relu_expand3x3" type: "ReLU" bottom: "fire9/expand3x3" top: "fire9/expand3x3" } layer { name: "fire9/concat" type: "Concat" bottom: "fire9/expand1x1" bottom: "fire9/expand3x3" top: "fire9/concat" } layer { name: "drop9" type: "Dropout" bottom: "fire9/concat" top: "fire9/concat" dropout_param { dropout_ratio: 0.5 } } layer { name: "conv10_new" type: "Convolution" bottom: "fire9/concat" top: "conv10_new" param { lr_mult: 5 decay_mult: 1 } param { lr_mult: 10 decay_mult: 0 } convolution_param { num_output: 100 kernel_size: 1 weight_filler { type: "gaussian" mean: 0.0 std: 0.01 } } } layer { name: "relu_conv10" type: "ReLU" bottom: "conv10_new" top: "conv10_new" } layer { name: "pool10" type: "Pooling" bottom: "conv10_new" top: "pool10" pooling_param { pool: AVE global_pooling: true } } layer { name: "loss" type: "SoftmaxWithLoss" bottom: "pool10" bottom: "label" top: "loss"

} layer { name: “softmax” type: "Softmax" bottom: "pool10" top: “softmax”

} layer { name: "accuracy" type: "Accuracy" bottom: "pool10" bottom: "label" top: "accuracy"

} layer { name: "accuracy_top5" type: "Accuracy" bottom: "pool10" bottom: "label" top: "accuracy_top5"

accuracy_param { top_k: 5 } }

AliaMYH avatar Mar 04 '17 14:03 AliaMYH

You can try it. If it only has "classical" layers like Conv, RELU, Pooling, etc. then it should work without a problem.

MarcBS avatar Mar 04 '17 16:03 MarcBS

I'm currently trying to convert squeeze net and I get the following error

Alias-MacBook-Air:caffe Alia$ python caffe2keras.py -load_path '/Users/Alia/Documents/Spring 2017/Thesis/converting/' -prototxt 'converter.prototxt' -caffemodel 'squeezenet_v1.1.caffemodel' Using TensorFlow backend. Converting model... CREATING MODEL Traceback (most recent call last): File "caffe2keras.py", line 45, in main(args) File "caffe2keras.py", line 34, in main model = convert.caffe_to_keras(args.load_path+'/'+args.prototxt, args.load_path+'/'+args.caffemodel, debug=args.debug) File "/Users/Alia/Desktop/converter/keras/keras/caffe/convert.py", line 43, in caffe_to_keras debug) File "/Users/Alia/Desktop/converter/keras/keras/caffe/convert.py", line 259, in create_model net_node[layer_nb] = Activation('softmax', name=name)(input_layers) File "/Users/Alia/Desktop/converter/keras/keras/engine/topology.py", line 569, in call self.add_inbound_node(inbound_layers, node_indices, tensor_indices) File "/Users/Alia/Desktop/converter/keras/keras/engine/topology.py", line 632, in add_inbound_node Node.create_node(self, inbound_layers, node_indices, tensor_indices) File "/Users/Alia/Desktop/converter/keras/keras/engine/topology.py", line 164, in create_node output_tensors = to_list(outbound_layer.call(input_tensors[0], mask=input_masks[0])) File "/Users/Alia/Desktop/converter/keras/keras/layers/core.py", line 250, in call return self.activation(x) File "/Users/Alia/Desktop/converter/keras/keras/activations.py", line 17, in softmax 'Here, ndim=' + str(ndim)) ValueError: Cannot apply softmax to a tensor that is not 2D or 3D. Here, ndim=4

Any advice or insight?

AliaMYH avatar Apr 20 '17 16:04 AliaMYH

Hi Alia, The softmax layer in keras expects a tensor with the shape (batch_size, num_classes) however, the output from pool10 layer in case of squeezenet is (batch_size, num_filters, height, width). I recently submitted a PR that handles this, basically, it reshapes a 4-dim output to a 2-dim one.

akshaychawla avatar Apr 24 '17 05:04 akshaychawla