Tensorflow 如何为自定义keras图层创建可训练重量变量

Tensorflow 如何为自定义keras图层创建可训练重量变量,tensorflow,machine-learning,keras,layer,Tensorflow,Machine Learning,Keras,Layer,我正在实现自定义平均池层,每个神经元计算其输入的平均值,然后将结果乘以可学习系数并添加可学习偏差项,最后应用激活函数 from tensorflow.keras.layers import Layer from keras import backend as K class Average_Pooling_Layer(Layer): def __init__(self, output_dimension, **kwargs): super(Average_Pooli

我正在实现自定义平均池层,每个神经元计算其输入的平均值,然后将结果乘以可学习系数并添加可学习偏差项,最后应用激活函数

from tensorflow.keras.layers import Layer

from keras import backend as K


class Average_Pooling_Layer(Layer):
    def __init__(self, output_dimension, **kwargs):
        super(Average_Pooling_Layer, self).__init__(**kwargs)
        self.output_dimension = output_dimension

    def build(self, input_shape):

        self.weights = self.add_weight(name='weights2',
                              shape=(input_shape[0], 
                               int(self.output_dimension[0]), 
                               int(self.output_dimension[1]), 
                               int(self.output_dimension[2])),
                               initializer='uniform',
                               trainable=True)
    super(Average_Pooling_Layer, self).build(input_shape)

   def call(self, inputs):
        return K.tanh((inputs * self.weights))

    def compute_output_shape(self, input_shape):
        return (input_shape)
代码使用

model = tf.keras.Sequential()
stride = 1
c1 = model.add(Conv2D(6, kernel_size=[5,5], strides=(stride,stride), padding="valid", input_shape=(32,32,1), 
                  activation = 'tanh'))
s2_before_activation = model.add(AveragePooling2D(pool_size=(2, 2), strides=(2, 2)))
s2 = model.add(Average_Pooling_Layer(output_dimension = (14, 14, 6)))
我得到的错误是“未能将类型转换为张量。内容:(维度(无),14, 14, 6)。将铸造元素考虑为支持类型。”“没有”是批大小,这是我从前一层得到的。


如何解决此问题?

您的错误是由数据类型引起的
input_shape[0]
返回
而不是
int

您可以将
input\u shape[0]
替换为
tf.TensorShape(input\u shape).as\u list()[0]
。但是您的数据维度不正确,您必须根据需要调整和修改它

编辑


如果错误为“无法设置属性”,则应重命名权重变量,而不是
self.weights
。例如,更改为<>代码>自已.Weyths<新/<代码> .< /p>仍然相同的错误:未能将类型对象转换为张量。内容:(没有,14, 14, 6)。将铸造元素考虑为支持类型。“我的输出维度是14, 14, 6,我想是这样的。correct@VamshiPulluri首先,层重量的形状应与批次大小无关,因此,您不应该使用
[0]
索引。第二,当激活前的
s2\u的形状
输出为
(无,16,16,6)
时,您希望在
平均池层
中实现什么功能,并让它输出为
(无,14,14,6)
?所以我认为你的数据维度不对。谢谢你的第二点。将其编辑为包含
c1
valid
填充。我实际上是在为LeNet5 NN创建池层。池层的每个神经元计算其输入的平均值,然后将结果乘以可学习系数并添加可学习偏差项,最后应用激活函数。因此,
s2\u激活前
计算
平均值
。现在,
s2
乘以
learnable权重
并加上
偏差
项(这在代码中还不熟悉),至于第一点,当我保持形状为
shape=(int(self.output\u维度[0]),int(self.output\u维度[1]),int(self output\u维度[2]))
build
方法的
self.weights
中,我得到了错误,因为“无法设置属性”@VamshiPulluri我已经在答案中回答了这个问题。