【发布时间】:2019-04-08 08:29:46
【问题描述】:
我想在我的输入层之后定义一个预处理层,即它将使用之前计算的缩放器的均值和方差,并将其应用于我的输入,然后再将它们传递给密集网络。
Lambda 层在我的情况下不起作用,因为我想保存模型,目的是当应用于数据时,不需要处理输入,因为它将在网络的早期阶段完成。
对均值和 var 使用 K.variables 是可行的,但我想改用权重并设置 trainable=False。这样,它们将被保存在网络的权重中,而我不必每次都提供它们。
class PreprocessLayer(Layer):
"""
Defines a layer that applies the preprocessing from a scaler
Needed because lambda layers are too fragile to be saved in a model
"""
def __init__(self, batch_size, mean, var, **kwargs):
self.b = batch_size
self.m = mean
self.v = var
super(PreprocessLayer, self).__init__(**kwargs)
def build(self, input_shape):
self.mean = self.add_weight(name='mean',
shape=(self.b,input_shape[1]),
initializer=tf.constant_initializer(self.m),
trainable=False)
self.var = self.add_weight(name='var',
shape=(self.b,input_shape[1]),
initializer=tf.constant_initializer(self.v),
trainable=False)
super(PreprocessLayer, self).build(input_shape) # Be sure to call this at the end
def call(self, x):
return (x-self.mean)/self.var
def compute_output_shape(self, input_shape):
return (input_shape[0],input_shape[1])
def get_config(self):
config = super(PreprocessLayer, self).get_config()
config['mean'] = self.m
config['var'] = self.v
return config
我用
来称呼这一层L0 = PreprocessLayer(batch_size=20,mean=scaler.mean_,var=scaler.scale_)(IN)
问题出现在
shape=(self.b,input_shape[1]),
这给了我错误(当 batch_size 为 20 时)
tensorflow.python.framework.errors_impl.InvalidArgumentError: Incompatible shapes: [32,15] vs. [20,15]
[[Node: preprocess_layer_1/sub = Sub[T=DT_FLOAT, _device="/job:localhost/replica:0/task:0/device:CPU:0"](_arg_IN_0_0, preprocess_layer_1/mean/read)]]
据我了解,由于我的权重(mean 和 var)需要与输入 x 具有相同的形状,因此当 batch_size 不是训练大小的除数时,第一个轴会出现问题,因为它在训练期间会有不同的值培训。这会导致崩溃,因为形状必须在编译时确定,我不能将其留空。
有没有办法为 shape 的第一个值设置动态值?如果没有,是否可以解决此问题?
【问题讨论】:
-
为什么不在输入后使用
BatchNormalization层?因为你似乎在做同样的事情 -
我也不明白为什么您传递的
batch_size与input_shape[0]维度不同? -
因为我想掌握预处理中发生的事情,BatchNormalization 也可以批量处理,我想对整个数据集进行预处理。至于第二个问题是因为在编译时 input_shape = (None, 15)
-
如果你的
Input层之后有一个PreprocessLayer,即使这样也可以批量工作,根据你的batch_size。你能告诉我你们每批有多少样品吗?是32还是20?在您的PreprocessLayer中设置batch_size=batch_size_from_training,如果您仍然收到错误,请告诉我。 -
起初我使用了 20 的 batch_size(
PreprocessLayer和model.fit)然后我得到:tensorflow.python.framework.errors_impl.InvalidArgumentError: Incompatible shapes: [32,15] vs. [20,15]然后我把它改成了 32,错误是Incompatible shapes: [28,15] vs. [32,15]在这种情况下我想这是有道理的,因为我的训练大小是 152540 和 152540%32=28 (因此第一批需要更小,以便后面的大小可以是 32),但是我不明白在自 152540%20 = 0 以来的第一个案例
标签: python tensorflow keras layer