I'm trying to solve classification problem. I don't know why I'm getting this error:
ValueError: Input 0 of layer sequential_9 is incompatible with the layer: : expected min_ndim=4, found ndim=3. Full shape received: [None, None, None]
This is the main code:
model = createModel()
filesPath=getFilesPathWithoutSeizure(i, indexPat)
history=model.fit_generator(generate_arrays_for_training(indexPat, filesPath, end=75)##problem here
def createModel():
input_shape=(1,11, 3840)
model = Sequential()
#C1
model.add(Conv2D(16, (5, 5), strides=( 2, 2), padding='same',activation='relu',data_format= "channels_first", input_shape=input_shape))
model.add(keras.layers.MaxPooling2D(pool_size=( 2, 2),data_format= "channels_first", padding='same'))
model.add(BatchNormalization())
#C2
model.add(Conv2D(32, ( 3, 3), strides=(1,1), padding='same',data_format= "channels_first", activation='relu'))#incertezza se togliere padding
model.add(keras.layers.MaxPooling2D(pool_size=(2, 2),data_format= "channels_first", padding='same'))
model.add(BatchNormalization())
#c3
model.add(Conv2D(64, (3, 3), strides=( 1,1), padding='same',data_format= "channels_first", activation='relu'))#incertezza se togliere padding
model.add(keras.layers.MaxPooling2D(pool_size=(2, 2),data_format= "channels_first", padding='same'))
model.add(BatchNormalization())
model.add(Flatten())
model.add(Dropout(0.5))
model.add(Dense(256, activation='sigmoid'))
model.add(Dropout(0.5))
model.add(Dense(2, activation='softmax'))
opt_adam = keras.optimizers.Adam(lr=0.00001, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0)
model.compile(loss='categorical_crossentropy', optimizer=opt_adam, metrics=['accuracy'])
return model
Error:
history=model.fit_generator(generate_arrays_for_training(indexPat, filesPath, end=75), #end=75),#It take the first 75%
File "/home/user1/.local/lib/python3.8/site-packages/tensorflow/python/util/deprecation.py", line 324, in new_func
return func(*args, **kwargs)
File "/home/user1/.local/lib/python3.8/site-packages/tensorflow/python/keras/engine/training.py", line 1815, in fit_generator
return self.fit(
File "/home/user1/.local/lib/python3.8/site-packages/tensorflow/python/keras/engine/training.py", line 108, in _method_wrapper
return method(self, *args, **kwargs)
File "/home/user1/.local/lib/python3.8/site-packages/tensorflow/python/keras/engine/training.py", line 1098, in fit
tmp_logs = train_function(iterator)
File "/home/user1/.local/lib/python3.8/site-packages/tensorflow/python/eager/def_function.py", line 780, in __call__
result = self._call(*args, **kwds)
File "/home/user1/.local/lib/python3.8/site-packages/tensorflow/python/eager/def_function.py", line 823, in _call
self._initialize(args, kwds, add_initializers_to=initializers)
File "/home/user1/.local/lib/python3.8/site-packages/tensorflow/python/eager/def_function.py", line 696, in _initialize
self._stateful_fn._get_concrete_function_internal_garbage_collected( # pylint: disable=protected-access
File "/home/user1/.local/lib/python3.8/site-packages/tensorflow/python/eager/function.py", line 2855, in _get_concrete_function_internal_garbage_collected
graph_function, _, _ = self._maybe_define_function(args, kwargs)
File "/home/user1/.local/lib/python3.8/site-packages/tensorflow/python/eager/function.py", line 3213, in _maybe_define_function
graph_function = self._create_graph_function(args, kwargs)
File "/home/user1/.local/lib/python3.8/site-packages/tensorflow/python/eager/function.py", line 3065, in _create_graph_function
func_graph_module.func_graph_from_py_func(
File "/home/user1/.local/lib/python3.8/site-packages/tensorflow/python/framework/func_graph.py", line 986, in func_graph_from_py_func
func_outputs = python_func(*func_args, **func_kwargs)
File "/home/user1/.local/lib/python3.8/site-packages/tensorflow/python/eager/def_function.py", line 600, in wrapped_fn
return weak_wrapped_fn().__wrapped__(*args, **kwds)
File "/home/user1/.local/lib/python3.8/site-packages/tensorflow/python/framework/func_graph.py", line 973, in wrapper
raise e.ag_error_metadata.to_exception(e)
ValueError: in user code:
/home/user1/.local/lib/python3.8/site-packages/tensorflow/python/keras/engine/training.py:806 train_function *
return step_function(self, iterator)
/home/user1/.local/lib/python3.8/site-packages/tensorflow/python/keras/engine/training.py:796 step_function **
outputs = model.distribute_strategy.run(run_step, args=(data,))
/home/user1/.local/lib/python3.8/site-packages/tensorflow/python/distribute/distribute_lib.py:1211 run
return self._extended.call_for_each_replica(fn, args=args, kwargs=kwargs)
/home/user1/.local/lib/python3.8/site-packages/tensorflow/python/distribute/distribute_lib.py:2585 call_for_each_replica
return self._call_for_each_replica(fn, args, kwargs)
/home/user1/.local/lib/python3.8/site-packages/tensorflow/python/distribute/distribute_lib.py:2945 _call_for_each_replica
return fn(*args, **kwargs)
/home/user1/.local/lib/python3.8/site-packages/tensorflow/python/keras/engine/training.py:789 run_step **
outputs = model.train_step(data)
/home/user1/.local/lib/python3.8/site-packages/tensorflow/python/keras/engine/training.py:747 train_step
y_pred = self(x, training=True)
/home/user1/.local/lib/python3.8/site-packages/tensorflow/python/keras/engine/base_layer.py:975 __call__
input_spec.assert_input_compatibility(self.input_spec, inputs,
/home/user1/.local/lib/python3.8/site-packages/tensorflow/python/keras/engine/input_spec.py:191 assert_input_compatibility
raise ValueError('Input ' + str(input_index) + ' of layer ' +
ValueError: Input 0 of layer sequential_9 is incompatible with the layer: : expected min_ndim=4, found ndim=3. Full shape received: [None, None, None]
Keras actually always hides
0-th
dimension, also known asbatch
dimension. Everywhere where you putinput_shape = (A, B, C)
actually batch dimension should not be mentioned there,(A, B, C)
should be a shape of one object (or image in your case). For example if you sayinput_shape = (1,11, 3840)
then it actually means that data for training or prediction should be a numpy array of shape something like(7, 1,11, 3840)
, i.e. training has7
objects in the batch. So this7
is size of batch, number of objects to train in parallel.So if your one object (e.g. image) is of shape
(11, 3840)
then you have to writeinput_shape = (11, 3840)
everywhere, without mentioning batch size.Why is Keras hiding
0-th
batch dimension? Because keras is expecting different size of batch, today you may provide 7 objects, tomorrow 9 and same network will work for both. But shape of one object which is(11, 3840)
should never change and provided data for training generated by functiongenerate_arrays_for_training()
should be always of size(BatchSize, 11, 3840)
, whereBatchSize
can vary, you may generate batch of1
or7
or9
objects-images each of shape(11, 3840)
.If your images for all layers should be 3-dimensional, with 1 channel then you have to expand dims of your generated training data, do
X = np.expand_dims(X, 0)
using this function so that your training X data is of shape(1, 1, 11, 3840)
, e.g. batch with 1 object, only then you can haveinput_shape = (1, 11, 3840)
.Also I see that you're writing everywhere
data_format= "channels_first"
, by default all functions arechannels_last
, in order not to write this everywhere you can reshape your generated bygenerate_arrays_for_training()
data just once, if it isX
of shape(1, 1, 11, 3840)
then you doX = X.transpose(0, 2, 3, 1)
. And you channels will become last dimension.Transposing moves one dimension to another place. But for your case as you have just
1
channel than instead of transposing you can just reshape e.g.X
of shape(1, 1, 11, 3840)
can be reshaped byX = X.reshape(1, 11, 3840, 1)
and it will become of shape(1, 11, 3840, 1)
. This is only needed if you want not to write"channels_first"
everywhere, but if you don't want to beautify your code than transposing/reshaping is not needed at all!As I remember from my past Keras somehow doesn't like dimensions of size 1, it basically tries to remove them in several different functions, i.e. if keras sees array of shape
(1, 2, 1, 3, 1, 4)
it almost always tries to reshape it to be(2, 3, 4)
. Thusnp.expand_dims()
gets actually ignored. Probably the only solution in that case would be to generate batch of size 2 images at least.You may also read my long answer, although it is a bit unrelated, it may help you to understand how training/prediction in Keras works, especially you may read last paragraphs, numbered
1-12
.Update: As appeared to be the problem was solved due to help of next modifications:
In data generating function it was needed to do expanding dims twice, i.e.
X = np.expand_dims(np.expand_dims(X, 0), 0)
.In data generating function another was needed
X = X.transpose(0, 2, 3, 1)
.In code of network input shape set to be
input_shape = (11, 3840, 1)
.In code of network all substrings
data_format = "channels_first"
were removed.