Keras Lambda 层中什么时候生成随机数?

Geo*_* M. 2 lambda keras tensorflow

我想将简单的数据增强(输入向量乘以随机标量)应用于在 Keras 中实现的完全连接的神经网络。Keras 具有很好的图像增强功能,但尝试使用它对于我的输入(1 张量)来说似乎很笨拙且缓慢,其训练数据集适合我的计算机内存。

相反,我想象我可以使用 Lambda 层来实现这一点,例如:

x = Input(shape=(10,))
y = x
y = Lambda(lambda z: random.uniform(0.5,1.0)*z)(y)
y = Dense(units=5, activation='relu')(y)
y = Dense(units=1, activation='sigmoid')(y)
model = Model(x, y)
Run Code Online (Sandbox Code Playgroud)

我的问题是什么时候会生成这个随机数。这是否会修复单个随机数:

  • 整个训练过程?
  • 每批?
  • 每个训练数据点?

Dan*_*ler 6

使用它会创建一个根本不会改变的常量,因为random.uniform它不是 keras 函数。您在图中定义了此操作,constant * tensor并且该因子将是常数。

您需要“来自 keras”或“来自 tensorflow”的随机函数。例如,您可以将K.random_uniform((1,), 0.5, 1.).

这将按批次更改。您可以通过对这段代码进行多次训练来测试它,并查看损失的变化。

from keras.layers import *
from keras.models import Model
from keras.callbacks import LambdaCallback

import numpy as np


ins = Input((1,))
outs = Lambda(lambda x: K.random_uniform((1,))*x)(ins)
model = Model(ins,outs)

print(model.predict(np.ones((1,1))))
print(model.predict(np.ones((1,1))))
print(model.predict(np.ones((1,1))))

model.compile('adam','mae')
model.fit(np.ones((100000,1)), np.ones((100000,1)))
Run Code Online (Sandbox Code Playgroud)

如果你想让它改变每个训练样本,然后得到一个固定的批量大小和生成每个样品随机数的张量:K.random_uniform((batch_size,), .5, 1.)


如果您在自己的生成器中执行此操作,您可能应该会获得更好的性能model.fit_generator(),但是:

class MyGenerator(keras.utils.Sequence):
    def __init__(self, inputs, outputs, batchSize, minRand, maxRand):
        self.inputs = inputs
        self.outputs = outputs
        self.batchSize = batchSize
        self.minRand = minRand
        self.maxRand = maxRand

    #if you want shuffling
    def on_epoch_end(self):
        indices = np.array(range(len(self.inputs)))
        np.random.shuffle(indices)
        self.inputs = self.inputs[indices]
        self.outputs = self.outputs[indices] 

    def __len__(self):
        leng,rem = divmod(len(self.inputs), self.batchSize)
        return (leng + (1 if rem > 0 else 0))

    def __getitem__(self,i):
        start = i*self.batchSize
        end = start + self.batchSize

        x = self.inputs[start:end] * random.uniform(self.minRand,self.maxRand)
        y = self.outputs[start:end]

        return x,y
Run Code Online (Sandbox Code Playgroud)