在Keras中编写自己的损失以进行像素分割

时间:2019-06-01 10:34:53

标签: keras deep-learning semantic-segmentation

我正在尝试创建一个神经网络来分割图像中的特定对象。我已经手动创建了一个数据集,该数据集的大小为(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才是正确的。所以确实有问题。

0 个答案:

没有答案