3

I am using python 3 with anaconda, and keras with over tensorflow, My goal is to create a network with a Conv layer of variable input size

I found here to use this code

i = Input((None, None, 1))
o = Conv2D(1, 3, 3)(i)
model = Model(i, o)
model.compile('sgd', 'mse')

I have used it to create my own model with this code (I need a flatten layer)

model = Sequential()
I = Input((None, None, 1))
c = Conv2D(filters=1, kernel_size=(1, 1))(I)
f = Flatten()(c)
o = Dense(10, activation="softmax")(f)
m = Model(I, o)
m.compile(loss=categorical_crossentropy, optimizer=SGD(), metrics=["accuracy"])

And I keep getting this error

ValueError: The shape of the input to "Flatten" is not fully defined (got (None, None, 1). Make sure to pass a complete "input_shape" or "batch_input_shape" argument to the first layer in your model.

Seems like the issue is with the input shape for the Flatten layer, When I remove it, it's fine.

How can I make it play well with the variable size?

Thanks

thebeancounter
  • 4,261
  • 8
  • 61
  • 109
  • You can't. Because you added a *Dense* layer and the shape of the inputs of a *Dense* layer should be known and constant. It works when you remove *Flatten* because *Dense* layer assumes the last dimension as its input shape and the other dimensions as batch shape, so in this case the *Dense* layers input shape would be (1) and the batch shape would be (None, None, None) – amin Dec 01 '20 at 11:22

3 Answers3

0

Dense needs fix-sized inputs/outputs because the number of weights variables of it must be fixed.

There are two solutions in your case.

  1. To use GAP(Global Average Pooling) instead of Flatten. GAP's outputs size is the number of channels of the previous layer. so, its size is fixed in your case.
  2. To employ the all convolution net that doesn't have dense layer. In this case, the output of the net is two dimensional, not one. So the size of y should be that size.

below was added for Allen M's request.
Here is a code sample:

# The original number of Conv filters are one.
# But I set it 16 to depict how GAP works.
# And B/H/W means BatchSize/Height/Width.

#1. using GAP
I = Input((None, None, 1)) # output shape=(B, H(None), W(None), 1)
c = Conv2D(filters=16, kernel_size=(1, 1))(I)  # output shape=(B, H, W, 16)
f = GlobalAveragePooling2D()(c) # output shape=(B, 16) <- space data(H/W) are aggregated by average
o = Dense(10, activation="softmax")(f) # output shape = (B, 10)
m = Model(I, o)

#2. all conv
I = Input((None, None, 1)) # output shape=(B, H, W, 1)
c = Conv2D(filters=16, kernel_size=(1, 1))(I) # output shape=(B, H, W, 16)
o = Conv2D(filters=10, kernel_size=(1, 1), activation="softmax")(c)
    # output shape=(B, H, W, 10)
m = Model(I, o)
# The output size of all conv is H * W * 10, where 10 is the number of classes.
# so the shape of y should be (B, H, W, 1) or (B, H, W) or (B, H, W, 10).
# That is pixel-wise classification or semantic segmentation.
nak326
  • 33
  • 7
  • Please edit your question to include the question’s code example with one or both of your suggested corrections. – Allen M Feb 27 '21 at 03:56
-2

Flatten method doesn't take input size as argument.

model = Sequential()
I = Input((None, None, 1))
c = Conv2D(filters=1, kernel_size=(1, 1))(I)
f = Flatten()
o = Dense(10, activation="softmax")(I)
m = Model(I, o)
m.compile(loss="categorical_crossentropy", optimizer=SGD(), metrics=["accuracy"])

This should solve your problem.

Alwin Aind
  • 39
  • 1
  • 1
  • 4
  • You didn't connect the Flatten() layer to anything, you just removed it from the model. – Dr. Snoopy Jun 11 '19 at 14:54
  • This did not solve the problem... Still getting the same error. BTW you changed the entire structure of the model, you connected the input to the conv layer and to the softmax layer – thebeancounter Jun 12 '19 at 08:40
-2

I think the problem is due to your variable input_sizes. It says here that you can't vary input_sizes if you're using a fully connected layer. See: How to train images, when they have different size ?

BlueSkyz
  • 163
  • 1
  • 6
  • I am aware of the regular ways of dealing images in variable sizes and trying to do something else, will try that without the FC layer – thebeancounter Jun 12 '19 at 08:25
  • Tried removing the FC layer, still the same issue, the Flatten layer is the problem. When I remove the Flatten layer, and still use the FC layer, it's running fine when I add a global average pulling before the FC layer. – thebeancounter Jun 12 '19 at 08:40