【问题标题】:Keras GaussianNoise layer no effect?Keras GaussianNoise 层没有效果?
【发布时间】:2019-09-08 14:44:05
【问题描述】:

我想使用 keras 的功能 API 在我的 CNN 中的图像中添加一些高斯噪声,但是在测试一些不同的 stddev 值时,我注意到高斯层对输入数据没有任何作用。 我使用以下代码进行测试:

import tensorflow as tf
import numpy as np
import cv2

stddev = 0.1
image = cv2.imread(<img_path>)
image = (image.astype('float32') - 127.5) / 127.5

input_layer = tf.keras.layers.Input(shape=(128,128,3))
gaus = tf.keras.layers.GaussianNoise(stddev)(input_layer)
model = tf.keras.models.Model(inputs=input_layer, outputs=gaus)

noisy_image = model(image)

print(f'Pixel value at 0,0: {image[0,0]}')
print(f'Pixel value at 0,0: {noisy_image.numpy()[0,0]}')
# Output
# Pixel value at 0,0: [ 0.09803922 -0.30980393 -0.56078434]
# Pixel value at 0,0: [ 0.09803922 -0.30980393 -0.56078434]

我为 stddev 输入什么值并不重要(尝试了从 0.001 到 10000 的所有值)。我预计这些值会略有不同(或当 stddev=1000 时差异很大)。我做错了吗?

也许我应该提到我在 Windows 10 上使用 tensorflow-gpu==2.0.0-rc0

【问题讨论】:

    标签: python tensorflow keras


    【解决方案1】:

    如果您检查the docs,它表示该层仅在训练期间处于活动状态,因为它应该用作正则化器。查看源代码证实了这一点。所以看起来你是否需要确保模型“知道”它处于训练模式。有几种方法可以做到这一点:

    • 如果你使用model.compile/model.fit接口,这应该是自动完成的。
    • 如果您将模型用作可调用对象,它应该接受 training 参数,您可以将其设置为 training=True 以在每次调用的基础上“激活”训练模式。 IE。 noisy_image = model(image, training=True)
    • 您可以使用tf.keras.backend.set_learning_phase(1) 来“全局”激活训练模式(稍后再次调用它并使用参数0 来停用)。

    【讨论】:

    • 我明白了,谢谢。将行更改为 noisy_image = model(image, training=True) 确实会更改输出。
    【解决方案2】:

    这些数据增强层仅在训练时处于活动状态,因此仅在图像上调用模型时不会产生任何影响。您可以看到它正在使用:

    import tensorflow as tf
    import numpy as np
    import cv2
    
    stddev = 0.1
    image = cv2.imread(<img_path>)
    image = (image.astype('float32') - 127.5) / 127.5
    
    input_layer = tf.keras.layers.Input(shape=(128,128,3))
    gaus = tf.keras.layers.GaussianNoise(stddev)(input_layer, training=True)
    model = tf.keras.models.Model(inputs=input_layer, outputs=gaus)
    
    noisy_image = model(image)
    
    print(f'Pixel value at 0,0: {image[0,0]}')
    print(f'Pixel value at 0,0: {noisy_image.numpy()[0,0]}')
    # Output
    # Pixel value at 0,0: [ 0.09803922 -0.30980393 -0.56078434]
    # Pixel value at 0,0: [ 0.09803922 -0.30980393 -0.56078434]
    

    但请确保在评估时删除 training=True,以免对性能产生负面影响。

    【讨论】:

      【解决方案3】:

      试试

      import matplotlib.pyplot as plt
      
      input_layer = tf.keras.layers.Input(shape=(128,128,3))
      gaus        = tf.keras.layers.GaussianNoise(stddev,name='output')(input_layer)
      model       = tf.keras.models.Model(inputs=input_layer, outputs=gaus)
      
      noisy_image = get_layer_outputs(model,'output',image,train_mode=True)
      plt.imshow(image[:,:,0],cmap='bwr')
      plt.show()
      plt.imshow(np.asarray(noisy_image)[0,:,:,0],cmap='bwr')
      plt.show()
      
      def get_layer_outputs(model,layer_name,input_data,train_mode=False):
          outs_tensor   = [layer.output for layer in model.layers if layer_name == layer.name]
          outs_function = K.function([model.input, K.learning_phase()], outs_tensor)
          return [outs_function([input_data,int(train_mode)])][0]
      

      GaussianNoise 仅适用于learning_phase=1 - 即在“火车模式”下;不确定通过model(...) 直接提供数据是否可以实现这一点。 W/ 以上,使用image=np.random.randn(128,128,3)stddev=1,我得到了

      【讨论】:

        猜你喜欢
        • 2021-04-06
        • 1970-01-01
        • 1970-01-01
        • 2019-03-12
        • 2016-10-28
        • 1970-01-01
        • 1970-01-01
        • 2013-09-20
        • 1970-01-01
        相关资源
        最近更新 更多