在 TensorFlow 中使用 SSIM 损失返回 NaN 值

Posted

技术标签:

【中文标题】在 TensorFlow 中使用 SSIM 损失返回 NaN 值【英文标题】:Using SSIM loss in TensorFlow returns NaN values 【发布时间】:2021-03-06 21:44:29 【问题描述】:

我正在用 MRI 图像训练一个网络,我想使用 SSIM 作为损失函数。直到现在我还在使用 MSE,一切正常。但是当我尝试使用 SSIM (tf.image.ssim) 时,我收到了一堆警告消息:

 /usr/local/lib/python3.7/dist-packages/matplotlib/image.py:397: UserWarning: Warning: converting a masked element to nan.
  dv = (np.float64(self.norm.vmax) -
/usr/local/lib/python3.7/dist-packages/matplotlib/image.py:398: UserWarning: Warning: converting a masked element to nan.
  np.float64(self.norm.vmin))
/usr/local/lib/python3.7/dist-packages/matplotlib/image.py:405: UserWarning: Warning: converting a masked element to nan.
  a_min = np.float64(newmin)
/usr/local/lib/python3.7/dist-packages/matplotlib/image.py:410: UserWarning: Warning: converting a masked element to nan.
  a_max = np.float64(newmax)
/usr/local/lib/python3.7/dist-packages/matplotlib/colors.py:933: UserWarning: Warning: converting a masked element to nan.
  dtype = np.min_scalar_type(value)
/usr/local/lib/python3.7/dist-packages/numpy/ma/core.py:713: UserWarning: Warning: converting a masked element to nan.
  data = np.array(a, copy=False, subok=subok)

我的代码仍然在运行,但没有生成任何图形。我不确定这里发生了什么或我应该去哪里看。我正在使用 tensorflow 2.4.0。

我在这里附上我的代码摘要:

generator = Generator()  #An u-net defined in tf.keras

gen_learningrate = 5e-4
generator_optimizer = tf.keras.optimizers.Adam(gen_learningrate, beta_1=0.9, beta_2=0.999, epsilon=1e-8)
# Generator loss

def generator_loss(gen_output, target):
    # SSIM loss
    loss = - tf.reduce_mean(tf.image.ssim(target, gen_output, 2)) 
    return loss

@tf.function
def train_step(input_image, target, epoch):
    with tf.GradientTape() as gen_tape, tf.GradientTape() as disc_tape:
        gen_output = generator(input_image, training=True)
        
        loss = generator_loss(gen_output, target)

    generator_gradients = gen_tape.gradient(loss, generator.trainable_variables)
    generator_optimizer.apply_gradients(zip(generator_gradients, 
                                                 generator.trainable_variables))

    return loss

def fit(train_ds, epochs, test_ds):
    for input_image, target in train_ds:
            loss = train_step(input_image,target,epoch) 

fit(train_dataset, EPOCHS, test_dataset)

我进行了一些探索,发现大多数使用 tf.image.ssim() 作为损失函数的人都使用了 tensorflow 1.0 中的 tf.train() 或 tf.keras 中的 model.fit()。我怀疑返回的 NaN 值与 GradientTape() 函数有关,但我不确定如何。

【问题讨论】:

【参考方案1】:

根据我的经验,此警告通常与尝试绘制坐标无限远的点有关。当然,您真的应该向我们展示更多代码,以便我们有效地帮助您。

【讨论】:

感谢您的回复。我已经用更多细节更新了我的问题。

以上是关于在 TensorFlow 中使用 SSIM 损失返回 NaN 值的主要内容,如果未能解决你的问题,请参考以下文章

使用预训练 vgg19 tensorflow,Keras 在 CNN 自动编码器中定义自定义损失(感知损失)

Tensorflow:损失变成'NaN'

报告训练数据集中特定样本的训练损失,而不是训练过程中的平均损失 (TensorFlow)

如何在 Keras 模型中使用 TensorFlow 的采样 softmax 损失函数?

TensorFlow 多个损失值

Tensorflow:损失减少,但准确度稳定