python-3.xkerasimage-recognitionsiamese-network

Input problem with siamese network with customize datagenerator


Hello everyone and thank you in advance for the help.

I'm trying to implement a siamese network (for the first time) for my image recognition project, but i'm not able to overcome this error:

"Error when checking model input: the list of Numpy arrays that you are passing to your model is not the size the model expected. Expected to see 2 array(s), but instead got the following list of 1 arrays"

I think my datagenerator is the problem, but I don't know how to fix it.

Here are some information:

##################### MODEL

  input_dim = (200, 200, 1)
  img_a = Input(shape = input_dim)
  img_b = Input(shape = input_dim)
  base_net = build_base_network(input_dim)

  features_a = base_net(img_a)
  features_b = base_net(img_b)

  distance = Lambda(euclidean_distance, output_shape = eucl_dist_output_shape)([features_a, features_b])
  model = Model(inputs=[img_a, img_b], outputs=distance)


##################### NETWORK

def build_base_network(input_shape):

  seq = Sequential()

  #Layer_1
  seq.add(Conv2D(96, (11, 11), subsample=(4, 4), input_shape=(input_shape), init='glorot_uniform', dim_ordering='tf'))
  seq.add(Activation('relu'))
  seq.add(BatchNormalization())
  seq.add(MaxPooling2D((3,3), strides=(2, 2)))
  seq.add(Dropout(0.4))

  .
  .
  .
  .

  #Flatten
  seq.add(Flatten())
  seq.add(Dense(1024, activation='relu'))
  seq.add(Dropout(0.5))
  seq.add(Dense(1024, activation='relu'))
  seq.add(Dropout(0.5))

  return seq

##################### LAST PART OF DATAGENERATOR
 .
 .
 .
  if len(Pair_equal) > len(Pair_diff):
    Pair_equal = Pair_equal[0:len(Pair_diff)]
    y_equal = y_equal[0:len(y_diff)]

  elif len(Pair_equal) < len(Pair_diff):
    Pair_diff = Pair_diff[0:len(Pair_equal)]
    y_diff = y_diff[0:len(y_equal)]


  Pair_equal = np.array(Pair_equal) #contains pairs of the same image
  Pair_diff = np.array(Pair_diff) #contains pairs of different images
  y_equal = np.array(y_equal)
  y_diff = np.array(y_diff)

  X = np.concatenate([Pair_equal, Pair_diff], axis=0)
  y = np.concatenate([y_equal, y_diff], axis=0)

  return X, y

##################### SHAPES

(16, 2, 200, 200, 1) --> Pair_equal
(16, 2, 200, 200, 1) --> Pair_diff
(16,) --> y_equal
(16,) --> y_diff
     

If you need anything else ask and I will provide it.


Solution

  • you can solve changing what your generator return in

    return [X[:,0,...], X[:,1,...]], y
    

    your it's a siamese network that expects 2 inputs and produces 1 output but in general this is valid for all the keras models that expect multiple inputs (or also outputs).

    to feed this kind of model you have to pass an array for each input. in your case, an array of image_a and another for image_b. each array (in case of multiple input/output) must be put inside a list