ssim как пользовательская функция потерь в автоэнкодере (керас и / или тензор потока) - PullRequest
0 голосов
/ 04 июля 2018

Я сейчас программирую авто-кодер для сжатия изображений. Из предыдущего поста Теперь у меня есть окончательное подтверждение того, что я не могу использовать чистые функции Python в качестве функций потерь ни в Keras, ни в tenorflow. (И я постепенно начинаю понимать, почему; -)

Я бы хотел провести несколько экспериментов, используя ssim в качестве функции потерь и метрики. Теперь, кажется, мне повезло. Это уже реализовано в тензорном потоке, см .: https://www.tensorflow.org/api_docs/python/tf/image/ssim

tf.image.ssim ( img1, img2, max_val ) * +1010 *

Кроме того, bsautermeister любезно предоставил реализацию здесь по стеку: SSIM / MS-SSIM для TensorFlow .

Теперь у меня вопрос: как бы я использовал его как функцию потерь с набором данных mnist? Функция не принимает тензор, а только два изображения. И будет ли градиент вычисляться автоматически? Из того, что я понимаю, это должно быть, если функция реализована в тензорном потоке или керасе.

Буду очень признателен за минимальный рабочий пример (MWE) о том, как использовать любую из ранее упомянутых реализаций ssim в качестве функции потерь в керасе или тензорном потоке.

Может быть, мы можем использовать мой MWE для автоэнкодера, поставляемого с моим предыдущим вопросом: Пользовательские потери keras чистый питон (без сервера keras)

Если невозможно склеить мой авто-кодер keras вместе с реализациями ssim, возможно ли это с помощью авто-кодера, напрямую реализованного в tenorflow? У меня это тоже есть, и могу ли это предоставить?

Я работаю с python 3.5, keras (с тензорным бэкэндом) и, если необходимо, напрямую с тензорным потоком. В настоящее время я использую набор mnist (тот, что с цифрами).

Спасибо за любую помощь!

(П.С .: Кажется, что несколько человек работают над подобными вещами. Ответ на этот пост также может быть полезен для Keras - MS-SSIM как функция потери )

1 Ответ

0 голосов
/ 04 июля 2018

Я не могу служить с Keras, но в обычном TensorFlow вы просто переключаете L2 или любую другую стоимость с результатами SSIM, такими как

import tensorflow as tf
import numpy as np


def fake_img_batch(*shape):
    i = np.random.randn(*shape).astype(np.float32)
    i[i < 0] = -i[i < 0]
    return tf.convert_to_tensor(np.clip(i * 255, 0, 255))


fake_img_a = tf.get_variable('a', initializer=fake_img_batch(2, 224, 224, 3))
fake_img_b = tf.get_variable('b', initializer=fake_img_batch(2, 224, 224, 3))

fake_img_a = tf.nn.sigmoid(fake_img_a)
fake_img_b = tf.nn.sigmoid(fake_img_b)

# costs = tf.losses.mean_squared_error(fake_img_a, fake_img_b, reduction=tf.losses.Reduction.MEAN)
costs = tf.image.ssim(fake_img_a, fake_img_b, 1.)
costs = tf.reduce_mean(costs)

train = tf.train.AdamOptimizer(0.01).minimize(costs)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(sess.run(costs))
    for k in range(500):
        _, l = sess.run([train, costs])
        if k % 100 == 0:
            print('mean SSIM', l)

Проверить, есть ли у операции градиенты (реализовано), просто:

import tensorflow as tf
import numpy as np


def fake_img_batch(*shape):
    i = np.random.randn(*shape).astype(np.float32)
    i[i < 0] = -i[i < 0]
    return tf.convert_to_tensor(np.clip(i * 255, 0, 255))

x1 = tf.convert_to_tensor(fake_img_batch(2, 28, 28, 3))
x2 = tf.convert_to_tensor(fake_img_batch(2, 28, 28, 3))


y1 = tf.argmax(x1)  # not differentiable -> no gradients
y2 = tf.image.ssim(x1, x2, 255) # has gradients

with tf.Session() as sess:
    print(tf.gradients(y1, [x1]))  # will print [None] --> no gradient
    print(tf.gradients(y2, [x1, x2]))  # will print [<tf.Tensor 'gradients ...>, ...] --> has gradient
...