首页 > 解决方案 > 如何使用图像中的特定像素作为损失函数keras?

问题描述

所以我有 100x100x3 的图像,它有 3 个类别的分类问题。

所以我的CNN架构如下:

visible = Input(shape=(100, 100, 3))
conv_1 = Conv2D(filters=32, kernel_size=(3, 3), strides=(1, 1), padding='same')(visible)
flatten_1 = Flatten()(conv_1)
dense_1 = Dense(100)(flatten_1)
dense_2 = Dense(3)(dense_1)
act_6 = Activation('softmax')(dense_2)
model = Model(inputs=visible, outputs=act_6)

现在我定义我的自定义损失函数如下:

def custom_loss(visible):
    def loss_fun(y_true, y_pred):
        return sparse_categorical_crossentropy(y_true, y_pred) + visible[?, 0, 0, 0]
    return loss_fun

sgd = SGD(lr=0.1, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss=custom_loss(visible), optimizer=sgd)

当然,上面的代码会因为“?”而报错。
如您所见,我想将每个图像的 (0, 0, 0) 处的图像像素值添加到损失函数中。
事实上,我希望能够根据特定图像的 y_pred 将 (0, 0, 0) 更改为一些 (x, y, z)。
我怎样才能做到这一点?

标签: pythonkerasloss-function

解决方案


您可以执行以下操作,

def custom_loss(visible):
    def loss_fun(y_true, y_pred):
        # Getting the classes
        classes = tf.argmax(y_pred, axis=1)
        # The different x,y,z combinations for each class (None, 3) sized array
        # We are doing a gather operation to select correct combination of x,y,z for a given class
        inds = tf.gather(tf.constant([[0,1,2],[1,3,1],[7,8,1]], dtype=tf.int32), classes)
        # We concatenate the batch dimnsion to the front [0, 1, 2, ....]
        final_inds = tf.concat([tf.cumsum(tf.ones_like(classes, dtype=tf.int32))[:,tf.newaxis], inds], axis=1)

        # Get the related ids from visible
        return sparse_categorical_crossentropy(y_true, y_pred) + tf.reduce_mean(tf.gather_nd(visible,final_inds))
    return loss_fun

PS:请记住,损失的第二部分(来自visible)是不可微的(因为它只是一个输入并且没有任何参数)。


推荐阅读