9

So I'm trying to implement this paper about a Siamese neural network: Learning a similarity metric discriminatively, with application to face verification, by Sumit Chopra, Raia Hadsell and Yann LeCun (2005). I'm using the CIFAR10 dataset instead, though, with 10 classes.

The specifications of one of the legs is reproduced for convenience. Notation: C_x is a convolution layer, S_x is a subsampling layer and F_x is a fully connected layer; with a shared index x:

  1. C1: feature maps: 15, kernel size = (7, 7)
  2. S2: feature maps: 15, field-of-view = (2, 2)
  3. C3: feature maps: 45, kernel size = (6, 6)
  4. S4: feature maps: 45, field-of-view = (4, 3)
  5. C5: feature maps: 250, kernel size = (5, 5)
  6. F6 (fully connected layer): no. of units = 50

What I've Tried

model = Sequential()

#C1
model.add(Convolution2D(15, 7, 7,
activation='relu',
border_mode='same',
input_shape=input_img_shape))
print("C1 shape: ", model.output_shape)

#S2
model.add(MaxPooling2D((2,2), border_mode='same'))
print("S2 shape: ", model.output_shape)
#...

#C5
model.add(Convolution2D(250, 5, 5, 
activation='relu', 
border_mode='same'))
print("C5 shape: ", model.output_shape)

#F6
model.add(Dense(50))

This throws a long error message, which I believe is a reshape error. A snippet of the error:

Exception: Input 0 is incompatible with layer dense_13: expected
ndim=2, found ndim=4

I know that the problem is isolated in that final Dense layer, because the code proceeds smoothly if I comment it out. But I'm not sure exactly how I should then shape/specify my final fully connected layer so that it's compatible with the prior convolution layer?

Some Places I've Looked

This is a related problem, though the implementation is slightly different (it seems that there isn't a 'Siamese' core layer in keras at the time of this writing). I'm aware that there are also implementations in Theano, which I'll bear in mind if I'm just not able to do it in keras.

Thanks!

Community
  • 1
  • 1
AndreyIto
  • 954
  • 1
  • 14
  • 35

2 Answers2

4

As mentioned by Matias Valdenegro, Keras already has an example of Siamese network. The example uses only dense layers, though.

Your problem is that you need to add a Flatten layer between the convolutional layers and the dense layers to have a correct shape, see this Keras CNN example

These 2 examples should help you build your Siamese network.

Community
  • 1
  • 1
sytrus
  • 757
  • 8
  • 11
  • Conceptually, could I ask why you'd need a "flatten" layer? This is new to me because I haven't seen it mentioned in the paper. Thanks! – AndreyIto Jul 26 '16 at 12:30
  • 1
    @AndreyIto this is more of an implementation detail: In Keras, the output of layer `Convolution2D` has 4 dimensions [(see source)](https://github.com/fchollet/keras/blob/master/keras/layers/convolutional.py#L248) whereas the input of `Dense` layer should be of dimension 2 [(see source)](https://github.com/fchollet/keras/blob/master/keras/layers/core.py#L567). So you need to flatten your data with `Flatten` layer before passing it through the `Dense` layer. – sytrus Jul 26 '16 at 14:04
2

You don't need a Siamese Layer, you just need to use the Keras functional API to create a model with two inputs and one output.

Seems that Keras examples already contain a model that is very similar to the one you are implementing.

Dr. Snoopy
  • 55,122
  • 7
  • 121
  • 140
  • Thanks for your input! Yup, I did come across this example, and it did help me with putting together the general structure, but it didn't address the specific problem of managing shapes between layers. But thanks anyway! – AndreyIto Jul 26 '16 at 12:31