I am receiving nan
as my accuracy and loss outputs after each epoch for basic object detection in tensorflow. Also, my results (classification and bounding box coords) are nan
.
How do I get proper results?
Another side question, why are input, pooling layers, and flatten layers params zero when compiling model?
Link to my full code and training data at: https://github.com/arojas314/data-sharing.git
Model snippet:
'''
Feature extractor is the CNN that is made up of convolution and pooling layers.
'''
def feature_extractor(inputs):
x = tf.keras.layers.Conv2D(16, activation='relu', kernel_size=3, input_shape=(424, 424, 3))(inputs)
x = tf.keras.layers.AveragePooling2D((2, 2))(x)
x = tf.keras.layers.Conv2D(32,kernel_size=3,activation='relu')(x)
x = tf.keras.layers.AveragePooling2D((2, 2))(x)
x = tf.keras.layers.Conv2D(64,kernel_size=3,activation='relu')(x)
x = tf.keras.layers.AveragePooling2D((2, 2))(x)
return x
'''
dense_layers adds a flatten and dense layer.
This will follow the feature extraction layers
'''
def dense_layers(inputs):
x = tf.keras.layers.Flatten()(inputs)
x = tf.keras.layers.Dense(128, activation='relu')(x)
return x
'''
Classifier defines the classification output.
This has a set of fully connected layers and a softmax layer.
'''
def classifier(inputs):
classification_output = tf.keras.layers.Dense(2, activation='softmax', name = 'classification')(inputs)
# classification_output = tf.keras.layers.Dense(1, activation='softmax', name = 'classification')(inputs) # works but so should above
return classification_output
'''
This function defines the regression output for bounding box prediction.
Note that we have four outputs corresponding to (xmin, ymin, xmax, ymax)
'''
def bounding_box_regression(inputs):
bounding_box_regression_output = tf.keras.layers.Dense(units = '4', name = 'bounding_box')(inputs)
return bounding_box_regression_output
def final_model(inputs):
feature_cnn = feature_extractor(inputs)
dense_output = dense_layers(feature_cnn)
'''
The model branches here.
The dense layer's output gets fed into two branches:
classification_output and bounding_box_output
'''
classification_output = classifier(dense_output)
bounding_box_output = bounding_box_regression(dense_output)
model = tf.keras.Model(inputs = inputs, outputs = [classification_output, bounding_box_output])
return model
def define_and_compile_model(inputs):
model = final_model(inputs)
model.compile(optimizer='adam',
loss = {'classification' : 'sparse_categorical_crossentropy',
'bounding_box' : 'mse'
},
metrics = {'classification' : 'accuracy',
'bounding_box' : 'mse'
})
# Returns full and compiled model
return model
inputs = tf.keras.layers.Input(shape=(424, 424, 3))
# inputs = tf.keras.layers.Input(shape=(None, 424, 424, 3))
model = define_and_compile_model(inputs)
# print model layers
model.summary()
Fitting model:
# Combine train bbox and train labels into dictionary
trainTargets = {
"classification": training_labels,
"bounding_box": training_bboxes
}
testTargets = {
"classification": test_labels,
"bounding_box": test_bboxes
}
EPOCHS = 5 # 45
steps_per_epoch = trainTargets["bounding_box"].shape[0]//BATCH_SIZE # need number of training items only!
validation_steps = 1
history = model.fit(training_images, trainTargets,
steps_per_epoch=steps_per_epoch,
validation_data=(test_images, testTargets),
validation_steps=validation_steps, epochs=EPOCHS)