When running this code:
def create_dense_net(nb_classes, img_input, depth=40, nb_block=3,
growth_rate=12, nb_filter=16, bottleneck=False, compression=1.0, p=None, wd=0, activation='softmax'):
assert activation == 'softmax' or activation == 'sigmoid'
assert (depth - 4) % nb_block == 0
nb_layers_per_block = int((depth - 4) / nb_block)
nb_layers = [nb_layers_per_block] * nb_block
x = Lambda(preprocess)(img_input)
x = conv(x, nb_filter, 3, wd, 0)
for i,block in enumerate(nb_layers):
x = dense_block(x, block, growth_rate, bottleneck=bottleneck, p=p, wd=wd)
if i != len(nb_layers)-1:
x = transition_block(x, compression=compression, p=p, wd=wd)
x = relu_bn(x)
x = GlobalAveragePooling2D()(x)
return Dense(nb_classes, activation=activation, kernel_regularizer=l2(wd))(x)
input_shape = (224,224,3)
img_input = Input(shape=input_shape)
x = create_dense_net(train_batches.num_class, img_input, depth=100, nb_filter=16, compression=0.5,
bottleneck=True, p=0.2, wd=1e-4)
model = Model(img_input, x)
model.compile(loss='sparse_categorical_crossentropy',
optimizer=keras.optimizers.SGD(0.1, 0.9, nesterov=True), metrics=["accuracy"])
nb_epoch = 1
model.fit_generator(train_batches, steps_per_epoch=int(train_batches.samples/train_batches.batch_size),
epochs=nb_epoch,
validation_data=val_batches,
validation_steps=int(val_batches.samples/val_batches.batch_size)
)
I get this error:
ValueError: Error when checking target: expected dense_1 to have shape (None, 1) but got array with shape (64, 120)
The number of classes in my batches are 120 and the batch size is 64 so the (64, 120) shape for the output array is correct. The final Dense layer is correctly initialized with 120 output classes as well as can be seen at the end of model.summary():
conv2d_99 (Conv2D) (None, 56, 56, 12) 5196 activation_98[0][0]
____________________________________________________________________________________________________
dropout_98 (Dropout) (None, 56, 56, 12) 0 conv2d_99[0][0]
____________________________________________________________________________________________________
merge_48 (Merge) (None, 56, 56, 340) 0 merge_47[0][0]
dropout_98[0][0]
____________________________________________________________________________________________________
batch_normalization_99 (BatchNor (None, 56, 56, 340) 1360 merge_48[0][0]
____________________________________________________________________________________________________
activation_99 (Activation) (None, 56, 56, 340) 0 batch_normalization_99[0][0]
____________________________________________________________________________________________________
global_average_pooling2d_1 (Glob (None, 340) 0 activation_99[0][0]
____________________________________________________________________________________________________
dense_1 (Dense) (None, 120) 40920 global_average_pooling2d_1[0][0]
====================================================================================================
Total params: 818,980
Trainable params: 795,468
Non-trainable params: 23,512
The model I use is based on this notebook: densenet-keras, which I have only modified slightly to increase the number of output classes from 10 to 120 and to adapt to Keras 2. I'm using Keras 2.0.5 with a Tensorflow back-end.
Could this be caused by a known bug and if not, how to debug it further?
Thanks,
Robert
I found what the issue is:
loss='sparse_categorical_crossentropy'
expects an integer output of size 1 iso of a one-hot encoded output of size 120. The issue was resolved by changing to:
loss='categorical_crossentropy'
@hillenr14
Sorry for commenting on a closed thread, but I've had a similar issue to yours. I am using the U-Net architecture and have grayscale images as my inputs, so they read as (total_imgs, rows, cols, channels) where channels = 1. I want there to be two output classes, but every time I try to change my last conv layer to 2, it is able to train the model, but gives me an error when I try to apply the model to the unseen test set (which are also grayscale images) so it expects only 1 channel, when I have specified the 2 class output. Changing my loss from binary_crossentropy to categorical_crossentropy doesn't work for me. Am I getting classes and channels confused?
Here is my training data:
imgdatas = np.ndarray((len(imgs), 256, 256 ,1), dtype=np.uint8)
#grascale
imglabels = np.ndarray((len(imgs), 256, 256, 2), dtype=np.uint8)
#if I change channels to 2 the model runs
This is my test data:
imgdatas = np.ndarray((len(imgs), 256, 256, 1), dtype=np.uint8)
#grayscale and gives error when I try to run it against the model
My model architecture looks like this:
input_1 (InputLayer) (None, 256, 256, 1) 0 __________________________________________________________________________________________________
conv2d_21 (Conv2D) (None, 256, 256, 64) 73792 concatenate_4[0][0] __________________________________________________________________________________________________
conv2d_22 (Conv2D) (None, 256, 256, 64) 36928 conv2d_21[0][0] __________________________________________________________________________________________________
conv2d_23 (Conv2D) (None, 256, 256, 2) 130 conv2d_22[0][0] ==================================================================
Total params: 31,034,498
Trainable params: 31,032,578
Non-trainable params: 1,920
This is the error:
Error when checking target expected conv2d_23 to have shape (256, 256, 2) but got array with shape (256, 256, 1)
The problem is, if I change the test data input into (256, 256, 2) it tells me that 2 is not a valid channel number. Which is why I think I'm just getting confused between the number of channels I have (1) and the classes I want the model to see (2).
How do I fix this problem?
Just update keras version to 2.1.2
pip install keras==2.1.2
I am using transfer learning with the help of inceptionv3
mobile = InceptionV3(weights='imagenet', include_top=False)
x = mobile.layers[-10].output
x= Dropout(0.4)(x)
x = Dense(128, activation='relu')(x)
predictions = Dense(7, activation='softmax')(x)
model = Model(inputs=mobile.input, outputs=predictions)
`ValueError Traceback (most recent call last)
13 validation_steps=val_steps,
14 epochs=30, verbose=1,
---> 15 callbacks=callbacks_list)
/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/engine/training.py in fit_generator(self, generator, steps_per_epoch, epochs, verbose, callbacks, validation_data, validation_steps, class_weight, max_queue_size, workers, use_multiprocessing, shuffle, initial_epoch)
2063 use_multiprocessing=use_multiprocessing,
2064 shuffle=shuffle,
-> 2065 initial_epoch=initial_epoch)
2066
2067 def evaluate_generator(self,
/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/engine/training_generator.py in fit_generator(model, generator, steps_per_epoch, epochs, verbose, callbacks, validation_data, validation_steps, class_weight, max_queue_size, workers, use_multiprocessing, shuffle, initial_epoch)
169
170 outs = model.train_on_batch(
--> 171 x, y, sample_weight=sample_weight, class_weight=class_weight)
172
173 if not isinstance(outs, list):
/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/engine/training.py in train_on_batch(self, x, y, sample_weight, class_weight)
1814 # Validate and standardize user data.
1815 x, y, sample_weights = self._standardize_user_data(
-> 1816 x, y, sample_weight=sample_weight, class_weight=class_weight)
1817
1818 if context.executing_eagerly():
/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/engine/training.py in _standardize_user_data(self, x, y, sample_weight, class_weight, batch_size, check_steps, steps_name, steps, validation_split)
991 x, y = next_element
992 x, y, sample_weights = self._standardize_weights(x, y, sample_weight,
--> 993 class_weight, batch_size)
994 return x, y, sample_weights
995
/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/engine/training.py in _standardize_weights(self, x, y, sample_weight, class_weight, batch_size)
1147 feed_output_shapes,
1148 check_batch_axis=False, # Don't enforce the batch size.
-> 1149 exception_prefix='target')
1150
1151 # Generate sample-wise weight values given the sample_weight
and
/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/engine/training_utils.py in standardize_input_data(data, names, shapes, check_batch_axis, exception_prefix)
314 ': expected ' + names[i] + ' to have ' +
315 str(len(shape)) + ' dimensions, but got array '
--> 316 'with shape ' + str(data_shape))
317 if not check_batch_axis:
318 data_shape = data_shape[1:]
ValueError: Error when checking target: expected dense_1 to have 4 dimensions, but got array with shape (32, 7)
`
Most helpful comment
I found what the issue is:
loss='sparse_categorical_crossentropy'
expects an integer output of size 1 iso of a one-hot encoded output of size 120. The issue was resolved by changing to:
loss='categorical_crossentropy'