我想在输入层之后定义一个预处理层,即它将使用之前计算的缩放器的平均值和方差,并将其应用于我的输入,然后将其传递到密集网络。在
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
我把这层称为
^{pr2}$问题出现在
shape=(self.b,input_shape[1]),
这给了我错误(当批量大小为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)]]
据我所知,由于我的权重(平均值和var)需要与输入x具有相同的形状,所以当批处理大小不是训练大小的除数时,第一个轴会产生问题,因为在训练期间它会有不同的值。这会导致崩溃,因为形状必须在编译时确定,我不能将其留空。在
有没有办法让shape的第一个值有一个动态值?如果没有,解决这个问题的方法?在
我不认为您需要添加}作为权重。您可以在
mean
和{call
函数中计算它们。我也不太明白为什么要用这个来代替BatchNormalization
,但是无论如何,也许你可以试试这个代码eps
是为了避免被0除。在我不能保证这会奏效,但也许可以试试。在
对于任何有相同问题的人-这是一个余数不同于时代结束时的批处理大小(由于培训和测试大小不是批大小的倍数),这是我的解决办法。在
由于余数的大小始终小于批处理大小,因此我在call函数中所做的是将权重切片如下:
这是可行的,但这意味着如果使用大于初始化层的批处理大小来评估模型,则错误将再次弹出。在
这就是为什么我在
__init__
中输入:self.b = max(32,batch_size)
。在因为predict()默认使用batch_size=32
相关问题 更多 >
编程相关推荐