【问题标题】:How to add Gaussian noise with varying std during training?如何在训练期间添加具有不同标准的高斯噪声?
【发布时间】:2023-03-12 13:33:01
【问题描述】:

我正在使用 keras 和 tensorflow 训练 CNN。我想在训练期间将高斯噪声添加到我的输入数据中,并在进一步的步骤中降低噪声的百分比。我现在所做的,我使用:

from tensorflow.python.keras.layers import Input, GaussianNoise, BatchNormalization
inputs = Input(shape=x_train_n.shape[1:])
bn0 = BatchNormalization(axis=1, scale=True)(inputs)
g0 = GaussianNoise(0.5)(bn0) 

GaussianNoise 采用的变量是噪声分布的标准偏差,我无法为其分配动态值,我该如何添加例如噪声,然后根据我所处的时期减小该值?

【问题讨论】:

  • 如果答案有帮助,请不要犹豫,通过投票/接受来告知。
  • 感谢您的回复我已经投票了,如何修改标准很有帮助。但我仍然希望得到一个答案,如何使用噪声百分比而不是使用标准。

标签: python tensorflow keras


【解决方案1】:

您可以简单地设计一个自定义 callback,在训练一个 epoch 之前更改 stddev

参考:

https://www.tensorflow.org/api_docs/python/tf/keras/layers/GaussianNoise

https://www.tensorflow.org/guide/keras/custom_callback

from tensorflow.keras.layers import Input, Dense, Add, Activation
from tensorflow.keras.models import Model
import tensorflow as tf
import numpy as np
import random


from tensorflow.python.keras.layers import Input, GaussianNoise, BatchNormalization
inputs = Input(shape=100)
bn0 = BatchNormalization(axis=1, scale=True)(inputs)
g0 = GaussianNoise(0.5)(bn0) 
d0 = Dense(10)(g0)
model = Model(inputs, d0)

model.compile('adam', 'mse')
model.summary()


class MyCustomCallback(tf.keras.callbacks.Callback):

  def on_epoch_begin(self, epoch, logs=None):
    self.model.layers[2].stddev = random.uniform(0, 1)
    print('updating sttdev in training')
    print(self.model.layers[2].stddev)


X_train = np.zeros((10,100))
y_train = np.zeros((10,10))

noise_change = MyCustomCallback()
model.fit(X_train, 
          y_train, 
          batch_size=32, 
          epochs=5, 
          callbacks = [noise_change])

Model: "model_5"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_6 (InputLayer)         [(None, 100)]             0         
_________________________________________________________________
batch_normalization_5 (Batch (None, 100)               400       
_________________________________________________________________
gaussian_noise_5 (GaussianNo (None, 100)               0         
_________________________________________________________________
dense_5 (Dense)              (None, 10)                1010      
=================================================================
Total params: 1,410
Trainable params: 1,210
Non-trainable params: 200
_________________________________________________________________
Epoch 1/5
updating sttdev in training
0.984045691131548
1/1 [==============================] - 0s 1ms/step - loss: 1.6031
Epoch 2/5
updating sttdev in training
0.02821459469022025
1/1 [==============================] - 0s 742us/step - loss: 1.5966
Epoch 3/5
updating sttdev in training
0.6102984511769268
1/1 [==============================] - 0s 1ms/step - loss: 1.8818
Epoch 4/5
updating sttdev in training
0.021155188690323512
1/1 [==============================] - 0s 1ms/step - loss: 1.2032
Epoch 5/5
updating sttdev in training
0.35950227285165115
1/1 [==============================] - 0s 2ms/step - loss: 1.8817

<tensorflow.python.keras.callbacks.History at 0x7fc67ce9e668>

【讨论】:

  • 很好的解决方案(+1)。但是,由于 OP 有兴趣更改 stddev 在每个纪元开始时 的值,因此最好修改您的解决方案并改用 Callbackon_epoch_begin 方法(目前,您的解决方案在每批开始时应用更改;这可能会使读者感到困惑)。此外,请删除所有其他冗余方法(如on_test_batch_begin等),使其更加简洁明了。
  • 请注意,至少在 tf1 中这是行不通的。你需要使用 K.variable
猜你喜欢
  • 2020-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-12
  • 1970-01-01
  • 2013-10-14
  • 2016-01-24
  • 2016-02-07
相关资源
最近更新 更多