1

我正在尝试使用 tf.image.ssim() 作为我的损失函数来训练我的模型,并且我探索了人们是如何实现它的。他们来了:

  1. 在 RGB 图像的张量流中使用 SSIM 损失函数
  2. 在 Keras 中使用 SSIM 损失函数

我有几个问题:

  1. 在这两个线程中,tf.image.ssim当输入在 -1 和 1 之间归一化时,建议的动态范围为 2。但我进行了一次小的健全性检查,看看它是否有效。这是代码:
from PIL import Image
import numpy as np
from skimage.util import random_noise
import matplotlib.pyplot as plt
import tensorflow as tf

im = Image.open('E:\\DATA\\train_image_(124).png')
im_arr = np.asarray(im) # convert PIL Image to ndarray

noise_img = random_noise(im_arr, mode='gaussian', var=0.0005) # random_noise() method will convert image in [0, 255] to [0, 1.0]
noise_img = (255*noise_img).astype(np.uint8)

img = Image.fromarray(noise_img)

#normalizing between 0 and 1 and reshaping for SSIM calculation
x = np.reshape((np.asarray(im)/255), [256, 256, 1])
y = np.reshape((np.asarray(img)/255), [256, 256, 1])

#normalizing between -1 and 1 and reshaping for SSIM calculation
x_a = np.reshape((2*(np.asarray(im)/255) - 1), [256, 256, 1])
y_a = np.reshape((2*(np.asarray(img)/255) - 1), [256, 256, 1])

print('No norm: ', str(tf.image.ssim(np.reshape(im_arr, [256, 256, 1]), np.reshape(noise_img, [256, 256, 1]), 255).numpy()))
print('Norm_01: ', str(tf.image.ssim(x, y, 1).numpy()))
print('Norm_11: ', str(tf.image.ssim(x_a, y_a, 2).numpy()))

据我了解,所有 3 个打印语句都应该给出相同的 SSIM 值,但它们没有。当范围为 0 到 1 和 0 到 255 时,SSIM 结果相同,但范围为 - 1 到 1 时,结果不同。为了仔细检查,我也在 MATLAB 中计算了 SSIM,这几乎与前两种情况一致。那么,有没有其他方法可以计算 SSIM/使用 SSIM 作为 TF2 中的损失函数?我用compare_ssimskimage 做了同样的实验,但那个似乎有同样的结果。我错过了什么吗?

  1. 此外,当我tf.reduce_mean(tf.keras.losses.mean_squared_error(target, gen_output))用作损失函数时,一切都很好。但是当我tf.reduce_mean(tf.image.ssim(x, y, dynamic_range)用作损失函数时,我得到的是 NaN 值。上面提到的两个线程都使用 tensorflow 1.x 或model.fittensorflow2.x 进行训练,而我正在使用tf.GradientTape()它来计算梯度和更新权重。GradientTape 函数是否有可能负责返回 NaN 值?如果是这样,为什么以及可能的解决方案是什么?
4

0 回答 0