Reputation: 1576
I'd like to build a CNN that can be feed matrices with the constant number of rows but the varying number of columns. I started from this blog but it uses Flatten
layer at some point. According to this GitHub issue, the Flatten
layer cannot be used with not fully-shape-defined data. I used this answer to build a CNN like this:
from keras import Input, Model
from keras.layers import Conv2D, MaxPooling2D, Dense, Dropout, Lambda, Activation
from keras.optimizers import SGD
import keras.backend as K
input = Input(shape=(None, 60, 1))
x = Conv2D(list_of_neurons[0], (3, 3), padding='same', activation='relu')(input)
x = MaxPooling2D(pool_size=(2, 2))(x) # None x 30
x = Conv2D(list_of_neurons[1], (3, 3), padding='same', activation='relu')(x)
x = MaxPooling2D(pool_size=(2, 2))(x) # None x 15
x = Conv2D(list_of_neurons[2], (3, 3), padding='same', activation='relu')(x)
x = MaxPooling2D(pool_size=(3, 3))(x) # None x 5
x = Lambda(lambda k: K.batch_flatten(k))(x)
x = Dense(list_of_neurons[3])(x)
x = Activation("relu")(x)
x = Dropout(dropout)(x)
output = Dense(1, activation='sigmoid')(x)
self._model = Model(inputs=input, outputs=output)
self._model.compile(loss='binary_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
self._model.summary()
However, when I try to run a script an error occurs:
Traceback (most recent call last):
File "/home/kuba/Dropbox/MGR Jakub Kustra/implementacja/first_cnn.py", line 66, in <module>
mlp = MLP([60, 60, 120, 120], 0.3)
File "/home/kuba/Dropbox/MGR Jakub Kustra/implementacja/models.py", line 22, in __init__
x = Dense(list_of_neurons[3])(x)
File "/home/kuba/anaconda3/lib/python3.6/site-packages/keras/engine/topology.py", line 576, in __call__
self.build(input_shapes[0])
File "/home/kuba/anaconda3/lib/python3.6/site-packages/keras/layers/core.py", line 830, in build
constraint=self.kernel_constraint)
File "/home/kuba/anaconda3/lib/python3.6/site-packages/keras/legacy/interfaces.py", line 87, in wrapper
return func(*args, **kwargs)
File "/home/kuba/anaconda3/lib/python3.6/site-packages/keras/engine/topology.py", line 397, in add_weight
weight = K.variable(initializer(shape),
File "/home/kuba/anaconda3/lib/python3.6/site-packages/keras/initializers.py", line 204, in __call__
scale /= max(1., float(fan_in + fan_out) / 2)
TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
The error occurs in this line in initializers.py
:
def __call__(self, shape, dtype=None):
fan_in, fan_out = _compute_fans(shape)
scale = self.scale
if self.mode == 'fan_in':
scale /= max(1., fan_in)
elif self.mode == 'fan_out':
scale /= max(1., fan_out)
else:
scale /= max(1., float(fan_in + fan_out) / 2) # <<<<<<<< HERE
if self.distribution == 'normal':
stddev = np.sqrt(scale)
return K.truncated_normal(shape, 0., stddev,
dtype=dtype, seed=self.seed)
else:
limit = np.sqrt(3. * scale)
return K.random_uniform(shape, -limit, limit,
dtype=dtype, seed=self.seed)
the fan_in
variable is None
. I thought that a Dense
layer can be feed with the varying size data. How can I overcome this?
Upvotes: 2
Views: 741
Reputation: 40516
Unfortunately, your scenario is impossible to achieve because of a simple reason: your Flatten
is followed by a Dense
layer. In order to allocate tensor for a Dense
layer, why should now the input shape - as allocator should allocate a matrix of weights of shape (input_shape, output_shape)
. This where your error comes from.
The solution presented in the issue you provided solved a little bit different task. The problem there was connected to the fact that sometimes - shape of the batch needs to be specified, and this is the problem which batch_flatten
is aiming to solve.
Upvotes: 2