我正在尝试创建一个神经网络来分割图像中的特定对象。我已经手动创建了一个数据集,该数据集的大小为(30,30,3),而相应的二进制掩码为(30,30)。
为简单起见,我想使用sum((y_pred - y_true)**2)
这样的损失,其中y_pred和y_true是扁平化的补丁,而**2
则表示元素平方。
我有一个可以运行的代码,但是我对Keras并不陌生,不知道这种损失是否正在按我的预期进行。
准确度迅速下降到“ 0.00”并保持在该水平,因此对培训有些疑惑。
以下是用于设置模型的代码:
def createNetwork(self):
"""
Define the network with all layers and loss functions
"""
k_sz1 = (7,7)
out1 = 64
model = tf.keras.Sequential()
model.add(layers.Conv2D(out1, k_sz1, padding='same', input_shape=(30,30,3)))
model.add(layers.Activation('relu'))
k_sz2 = (5,5)
out2 = 32
model.add(layers.Conv2D(out2, k_sz2, padding='same'))
model.add(layers.Activation('relu'))
k_sz3 = (3,3)
out3 = 16
model.add(layers.Conv2D(out3, k_sz3, padding='same'))
p_sz4 = (3,3)
model.add(layers.MaxPooling2D(p_sz4))
model.add(layers.Flatten())
out5 = 1 # Number of classes
last_layer = layers.Dense(out5, activation=tf.nn.softmax)
model.add(last_layer)
# Define own loss
def elemLoss(layer):
"""
Define my own loss to handle segmentation loss
"""
def loss(y_true,y_pred):
return tf.reduce_sum((y_pred-y_true)**2,1) # tf.reduce_sum(x, 0)
# Return a function
return loss
model.compile(optimizer='adam', loss=elemLoss(last_layer),
metrics=['accuracy'])
return model
培训很简单:
def trainModel(self):
"""
Train the neural network on the attached training data and annotation
"""
# Callback to display the target and prediciton
b_sz = 16
nbr_of_epochs = 10
self.model.fit(x=self.train_data, y=self.train_anno, batch_size=b_sz,
epochs=nbr_of_epochs, validation_split=0.1)
培训的结果:
132/132 [==============================] - 2s 16ms/step - loss: 650116.2668 - acc: 0.0000e+00 - val_loss: 0.9523 - val_acc: 0.0000e+00
Epoch 2/10
132/132 [==============================] - 2s 13ms/step - loss: 649995.9129 - acc: 0.0000e+00 - val_loss: 0.9985 - val_acc: 0.0000e+00
Epoch 3/10
132/132 [==============================] - 2s 13ms/step - loss: 649995.9318 - acc: 0.0000e+00 - val_loss: 1.0000 - val_acc: 0.0000e+00
Epoch 4/10
132/132 [==============================] - 2s 13ms/step - loss: 649996.0000 - acc: 0.0000e+00 - val_loss: 1.0000 - val_acc: 0.0000e+00
Epoch 5/10
132/132 [==============================] - 2s 13ms/step - loss: 649996.0000 - acc: 0.0000e+00 - val_loss: 1.0000 - val_acc: 0.0000e+00
Epoch 6/10
132/132 [==============================] - 2s 13ms/step - loss: 649996.0000 - acc: 0.0000e+00 - val_loss: 1.0000 - val_acc: 0.0000e+00
Epoch 7/10
132/132 [==============================] - 2s 12ms/step - loss: 649996.0000 - acc: 0.0000e+00 - val_loss: 1.0000 - val_acc: 0.0000e+00
Epoch 8/10
132/132 [==============================] - 2s 13ms/step - loss: 649996.0000 - acc: 0.0000e+00 - val_loss: 1.0000 - val_acc: 0.0000e+00
Epoch 9/10
132/132 [==============================] - 2s 13ms/step - loss: 649996.0000 - acc: 0.0000e+00 - val_loss: 1.0000 - val_acc: 0.0000e+00
Epoch 10/10
132/132 [==============================] - 2s 13ms/step - loss: 649996.0000 - acc: 0.0000e+00 - val_loss: 1.0000 - val_acc: 0.0000e+00
当然,这只是一个玩具网络,但是它的行为应该比这更好。能够在训练过程中输入损失函数并观察预测和标签的样子会很好。我试图增加pdb.set_trace()
的损失,但是在训练过程中会忽略这一点。
RGB色块除以255.0。
对于大多数像素而言,将所有像素都设为0才是正确的。所以确实有问题。