我正在尝试使用 tf.image.ssim() 作为我的损失函数来训练我的模型,并且我探索了人们是如何实现它的。他们来了:
我有几个问题:
- 在这两个线程中,
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_ssim
skimage 做了同样的实验,但那个似乎有同样的结果。我错过了什么吗?
- 此外,当我
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.fit
tensorflow2.x 进行训练,而我正在使用tf.GradientTape()
它来计算梯度和更新权重。GradientTape 函数是否有可能负责返回 NaN 值?如果是这样,为什么以及可能的解决方案是什么?