Python Keras中自定义层的trainable_variables属性返回空列表
我试图在Python Keras中自定义层的trainable_variables属性返回空列表,python,tensorflow,machine-learning,keras,keras-layer,Python,Tensorflow,Machine Learning,Keras,Keras Layer,我试图在tensorflow/keras中构建我自己的自定义层,强制该层保持对称,最终得到的结果如下: import tensorflow as tf from tensorflow.python.framework.ops import enable_eager_execution enable_eager_execution() class MyDenseLayer(tf.keras.layers.Layer): def __init__(self, num_outputs):
tensorflow/keras
中构建我自己的自定义层,强制该层保持对称,最终得到的结果如下:
import tensorflow as tf
from tensorflow.python.framework.ops import enable_eager_execution
enable_eager_execution()
class MyDenseLayer(tf.keras.layers.Layer):
def __init__(self, num_outputs):
super(MyDenseLayer, self).__init__()
self.num_outputs = num_outputs
def build(self, input_shape):
X = tf.random.uniform([int(input_shape[-1]),self.num_outputs],minval=0,maxval=1,dtype=tf.dtypes.float32,)
k = tf.Variable(X, name="kernel")
self.kernel = 0.5 * (k+tf.transpose(k))
def call(self, input):
return tf.matmul(input, self.kernel)
layer = MyDenseLayer(5)
print(layer(tf.ones([3, 5])))
print(layer.trainable_variables)
到目前为止,一切顺利。我不明白的是:为什么最后一行
print(layer.trainable_variables)
给我一张空名单:
[]
我认为
层.trainable_variables
将向我显示矩阵的外观,以便我可以检查它是否对称。您需要使用add_weight
添加变量,然后调用build()
方法来创建此变量。或者,您可以传递输入(正如您在问题中所做的那样),而不是直接调用build()
,它将隐式调用build()
方法
将tensorflow导入为tf
从tensorflow.python.framework.ops导入启用\u渴望\u执行
启用\u渴望\u执行()
MyDenseLayer类(tf.keras.layers.Layer):
定义初始化(自、数值输出):
超级(MyDenseLayer,self)。\uuuu init\uuuuu()
self.num\u输出=num\u输出
def构建(自我,输入_形状):
def初始值设定项(*args,**kwargs):
X=tf.random.uniform([int(input_shape[-1]),self.num_outputs],minval=0,maxval=1,dtype=tf.dtypes.float32,)
内核=0.5*(X+tf.转置(X))
返回内核
self.kernel=self.add_weight(name='kernel',
形状=(输入形状[-1],self.num\u输出),
初始值设定项=初始值设定项,
可培训=真实)
超级(MyDenseLayer,self).构建(输入形状)
def调用(自我,输入):
返回tf.matmul(输入,self.kernel)
图层=MyDenseLayer(5)
层。构建((5,)#看起来不错。这一层在训练后保持对称吗?它似乎从一开始就是对称的,但会通过反向传播改变其属性。不是层,而是层的权重!层是指层输出的内容(调用方法的返回)。层的权重将保持与“构建方法”中定义的相同大小。它不会改变它的大小。图层的输出可能取决于批量大小(第一个维度)。好的,我明白了。我尝试使用修改后的构建并在一个现有的keras层()中实现它,但在MyDenseLayer中的输出形状和类的给定参数方面存在问题。关于如何在类中实现初始值设定项,您有什么建议吗?您认为这是一个好主意吗?要实现初始化器,只需将num\u输出
替换为单位
。但我认为这是错误的想法,因为你的初始值设定项的分布没有改变。它仍然是一致的[0,1],所以只需使用内置的一致初始值设定项。回到前面的问题,因为我不确定我是否理解正确:您认为反向传播后权重将保持对称吗?尺寸肯定会保持不变。