I am trying to create a FCN using tensorflow keras. When calling model.fit I get the following error:
(0) Invalid argument: assertion failed: [`predictions` contains negative values] [Condition x >= 0 did not hold element-wise:] [x (confusion_matrix/Cast:0) = ] [0 1 0...]
[[{{node confusion_matrix/assert_non_negative_1/assert_less_equal/Assert/AssertGuard/else/_10/Assert}}]]
[[confusion_matrix/ones_like/_110]]
(1) Invalid argument: assertion failed: [`predictions` contains negative values] [Condition x >= 0 did not hold element-wise:] [x (confusion_matrix/Cast:0) = ] [0 1 0...]
[[{{node confusion_matrix/assert_non_negative_1/assert_less_equal/Assert/AssertGuard/else/_10/Assert}}]]
0 successful operations.
0 derived errors ignored. [Op:__inference_train_function_3344]
Function call stack:
train_function -> train_function
I am using: tensorflow - 2.2.0 and tf.keras -2.3.0-tf
The model is encoder-decoder type.
Here it is the encoder, VGG16 based:
```def get_vgg16_encoder(input_format, pretrained='imagenet'):
inputs = Input(shape=input_format, name="block_input")
x = Conv2D(filters=64, kernel_size=(3,3), activation='relu',
padding='same', name='block1_conv1', input_shape=input_format)(inputs)
x = Conv2D(filters=64, kernel_size=(3, 3), activation='relu',
padding='same', name='block1_conv2')(x)
x = MaxPooling2D(pool_size=(2, 2), strides=(2, 2), name='block1_pool',)(x)
pool_layer1 = x
x = Conv2D(filters=128, kernel_size=(3,3), activation='relu',
padding='same', name='block2_conv1')(x)
x = Conv2D(filters=128, kernel_size=(3, 3), activation='relu',
padding='same', name='block2_conv2')(x)
x = MaxPooling2D(pool_size=(2, 2), strides=(2, 2), name='block2_pool',)(x)
pool_layer2 = x
x = Conv2D(filters=256, kernel_size=(3,3), activation='relu',
padding='same', name='block3_conv1')(x)
x = Conv2D(filters=256, kernel_size=(3, 3), activation='relu',
padding='same', name='block3_conv2')(x)
x = Conv2D(filters=256, kernel_size=(3, 3), activation='relu',
padding='same', name='block3_conv3')(x)
x = MaxPooling2D(pool_size=(2, 2), strides=(2, 2), name='block3_pool',)(x)
pool_layer3 = x
x = Conv2D(filters=512, kernel_size=(3,3), activation='relu',
padding='same', name='block4_conv1')(x)
x = Conv2D(filters=512, kernel_size=(3, 3), activation='relu',
padding='same', name='block4_conv2')(x)
x = Conv2D(filters=512, kernel_size=(3, 3), activation='relu',
padding='same', name='block4_conv3')(x)
x = MaxPooling2D(pool_size=(2, 2), strides=(2, 2), name='block4_pool',)(x)
pool_layer4 = x
x = Conv2D(filters=512, kernel_size=(3,3), activation='relu',
padding='same', name='block5_conv1')(x)
x = Conv2D(filters=512, kernel_size=(3, 3), activation='relu',
padding='same', name='block5_conv2')(x)
x = Conv2D(filters=512, kernel_size=(3, 3), activation='relu',
padding='same', name='block5_conv3')(x)
x = MaxPooling2D(pool_size=(2, 2), strides=(2, 2), name='block5_pool')(x)
pool_layer5 = x
pool_layers = [pool_layer1, pool_layer2, pool_layer3, pool_layer4, pool_layer5]
if pretrained == 'imagenet':
Model(inputs, x).load_weights(WEIGHTS_URL, by_name=True)
return (inputs, pool_layers)```
And this is the decoder:
```POOL_5 = 4
POOL_4 = 3
POOL_3 = 2
def get_fcn_8s(n_classes, encoder):
inputs, pool_layers = encoder
output = pool_layers[POOL_5]
output = Conv2D(filters=1024, kernel_size=(7, 7), activation='relu',
padding='same', name='block14_conv2')(output)
output = Dropout(0.5)(output)
output = Conv2D(filters=1024, kernel_size=(1, 1), activation='relu',
padding='same', name='block15_conv2')(output)
output = Dropout(0.5)(output)
output = Conv2D(n_classes, (1, 1), kernel_initializer='he_normal',
name='block16_conv2')(output)
output = Conv2DTranspose(n_classes, kernel_size=(4, 4), strides=(
2, 2), use_bias=False, name='block1_conv2t')(output)
output_4 = pool_layers[POOL_4]
output_4 = Conv2D(n_classes, (1, 1), kernel_initializer='he_normal',
name='block17_conv2')(output_4)
output, output_4= crop(output, output_4, inputs)
output = Add(name='block1_add')([output, output_4])
output = Conv2DTranspose(n_classes, kernel_size=(4, 4), strides=(
2, 2), use_bias=False, name='block2_conv2t')(output)
output_3 = pool_layers[POOL_3]
output_3 = Conv2D(n_classes, (1, 1), kernel_initializer='he_normal',
name='block18_conv2')(output_3)
output, output_3= crop(output, output_3, inputs)
output = Add(name='block2_add')([output_3, output])
output = Conv2DTranspose(n_classes, kernel_size=(8, 8), strides=(
8, 8), use_bias=False, name='block3_conv2t')(output)
#output = ZeroPadding2D(((2,2), (0, 0)))(output)
output = Activation('softmax', name='block_actv')(output)
model = Model(inputs, output)
return model
```
The input format is (540,960, 3) and the output format is: (540, 960, 2), having 2 classes.
I generate the input using a Sequence class.
class DataGeneration(Sequence):
"""Helper to iterate over the data (as Numpy arrays)."""
def __init__(self, batch_size, img_size, frames_paths, annotations_paths):
self.batch_size = batch_size
self.img_size = img_size
self.frames_paths = frames_paths
self.annotations_paths = annotations_paths
def __len__(self):
return len(self.frames_paths) // self.batch_size
def __getitem__(self, idx):
"""Returns tuple (input, target) correspond to batch #idx."""
i = idx * self.batch_size
batch_frames_paths = self.frames_paths[i : i + self.batch_size]
batch_ann_paths = self.annotations_paths[i : i + self.batch_size]
batch_size = len(batch_frames_paths)
x = np.zeros((batch_size,) + self.img_size + (3,), dtype="float32")
for j, path in enumerate(batch_frames_paths):
img = load_img(path, target_size=self.img_size)
img = np.array(img)
# #x[j] = preprocess_input(img.astype('float32'), data_format='channels_last',
# # mode='torch')
x[j] = img / 255.0
y = np.zeros((batch_size,) + self.img_size + (1,), dtype="uint8")
for j, path in enumerate(batch_ann_paths):
img = load_img(path, target_size=self.img_size, color_mode="grayscale")
y[j] = np.expand_dims(img, 2)
y = y / 255
y = to_categorical(y, 2)
return x, y
As loss function I use categorical_crossentropy, adam optimizer and meanIoU as metrics.