我目前正在编写一个用于图像压缩的自动编码器。来自 previous post我现在最终确认我不能在 Keras 和 tensorflow 中使用纯 Python 函数作为损失函数。 (我正在慢慢开始理解为什么 ;-)
我想用 ssim 做一些实验作为损失函数和度量。现在看来我可能是幸运的。在 tensorflow 中已经有它的实现,参见:https://www.tensorflow.org/api_docs/python/tf/image/ssim
tf.image.ssim( img1, img2, 最大值 )
此外,bsautermeister 在 stackoverflow 上提供了一个实现:SSIM / MS-SSIM for TensorFlow .
我现在的问题是:对于 mnist 数据集,我如何将它用作损失函数?该函数不接受张量,只接受两个图像。而且,梯度会自动计算吗?据我了解,如果该功能是在 tensorflow 或 keras 后端中实现的。
我将非常感谢关于如何在 keras 或 tensorflow 中使用任何前面提到的 ssim 实现作为损失函数的最小工作示例 (MWE)。
也许我们可以将我的 MWE 用于我上一个问题提供的自动编码器: keras custom loss pure python (without keras backend)
如果无法将我的 keras 自动编码器与 ssim 实现粘合在一起,是否可以使用直接在 tensorflow 中实现的自动编码器?我也有,可以提供吗?
我正在使用 python 3.5、keras(带有 tensorflow 后端),如果需要,还可以直接使用 tensorflow。 目前我正在使用 mnist dataset (有数字的那个)。
感谢您的帮助!
(附:几个人似乎在做类似的事情。这篇文章的答案可能对 Keras - MS-SSIM as loss function 也有用)
请您参考如下方法:
我不能用 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
