Как использовать определенный пиксель с картинки в качестве функции потерь Кераса? - PullRequest
0 голосов
/ 09 января 2020

Итак, у меня есть изображения размером 100x100x3 и проблема классификации с тремя категориями.

Итак, моя архитектура 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) для каждого изображения в функции потерь.
На самом деле я хочу иметь возможность изменить (0, 0, 0) на некоторые (x, y, z) в зависимости от моего значения y_pred для этого конкретного изображения.
Как мне это сделать?

1 Ответ

1 голос
/ 09 января 2020

Вы можете сделать следующее,

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) не дифференцируема (потому что она просто вход и не имеет никаких параметров).

...