Tensorflow自定义层权重不是训练,而是偏差

2024-04-25 14:52:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经写了一些自定义图层,我已经意识到我的偏差值将得到训练,但我的权重没有得到训练。我将在这里使用一个非常简化的代码来说明这个问题

class myWeights(Layer):
    def __init__(self, units, **kwargs): 
        self.units = units
        super(myWeights, self).__init__(**kwargs)      
    def build(self, input_shape):
        self.w = self.add_weight(shape=(input_shape[-1], self.units),
                         initializer='GlorotUniform',
                         trainable=True)
        self.b = self.add_weight(shape=(self.units,),
                         initializer='random_normal',
                         trainable=True)
        super(myWeights, self).build(input_shape)
    def call(self, inputs):
        return tf.matmul(inputs, self.w) + self.b
    def compute_output_shape(self, input_shape):
        return(input_shape[0],self.units)

现在我设置MNIST数据进行训练。我还播下了一粒种子,这样你就可以复制了

tf.random.set_seed(1234)
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train=tf.keras.utils.normalize(x_train, axis=1)
x_test=tf.keras.utils.normalize(x_test, axis=1)

我使用函数式API构建模型

inp=Input(shape=(x_train.shape[1:]))
flat=Flatten()(inp)
hid=myWeights(32)(flat)
out=Dense(10, 'softmax')(hid)
model=Model(inp,out)
model.compile(optimizer='adam',
         loss='sparse_categorical_crossentropy',
         metrics=['accuracy'])

现在,当我使用

print(model.layers[2].get_weights())

我看到的输出如下所示,为了便于阅读,我对其进行了重新格式化

  • [array([[ 0.00652369, -0.02321771, 0.01399945, ..., -0.07599965, -0.04356881, -0.0333882 ], [-0.03132245, -0.05264733, 0.05576386, ..., -0.03755575, 0.07358163, -0.02338506], [-0.01808248, 0.04092623, 0.02177643, ..., 0.00971264, 0.07631209, 0.0495184 ], ..., [-0.03780914, 0.00219346, 0.04460619, ..., -0.06703794, 0.03407502, -0.01071112], [-0.0012739 , -0.0683699 , -0.06152753, ..., 0.05373723, 0.03079057, 0.00855774], [ 0.06245673, -0.07649396, 0.06748571, ..., -0.06948434, -0.01416317, -0.08318184]], dtype=float32), *
  • array([ 0.05734033, 0.04822996, 0.04391507, -0.01550511, 0.05383257, 0.05043739, -0.04092903, -0.0081823 , -0.06425817, 0.02402171, -0.00374672, -0.06069579, -0.08422226, 0.02909392, -0.02071654, 0.0422841 , -0.05020861, 0.01267704, 0.0365625 , -0.01743891, -0.01030697, 0.00639807, -0.01493454, 0.03214667, 0.03262959, 0.07799669, 0.05789128, 0.01754347, -0.07558075, 0.0466203 , -0.05332188, 0.00270758], dtype=float32)]*

经过与

model.fit(x_train,y_train, epochs=3, verbose=1)
print(model.layers[2].get_weights())

我发现以下输出

  • [array([[ 0.00652369, -0.02321771, 0.01399945, ..., -0.07599965, -0.04356881, -0.0333882 ], [-0.03132245, -0.05264733, 0.05576386, ..., -0.03755575, 0.07358163, -0.02338506], [-0.01808248, 0.04092623, 0.02177643, ..., 0.00971264, 0.07631209, 0.0495184 ], ..., [-0.03780914, 0.00219346, 0.04460619, ..., -0.06703794, 0.03407502, -0.01071112], [-0.0012739 , -0.0683699 , -0.06152753, ..., 0.05373723, 0.03079057, 0.00855774], [ 0.06245673, -0.07649396, 0.06748571, ..., -0.06948434, -0.01416317, -0.08318184]], dtype=float32), *
  • array([-0.250459 , -0.21746232, 0.01250297, 0.00065066, -0.09093136, 0.04943814, -0.13446714, -0.11985168, 0.23259214, -0.14288908, 0.03274751, 0.1462888 , -0.2206902 , 0.14455307, 0.17767513, 0.11378342, -0.22250313, 0.11601174, -0.1855521 , 0.0900097 , 0.21218981, -0.03386492, -0.06818825, 0.34211585, -0.24891953, 0.08827516, 0.2806849 , 0.07634751, -0.32905066, -0.1860122 , 0.06170518, -0.20212872], dtype=float32)]*

我可以看到偏差值已经改变,但权重值是静态的。我完全不知道为什么会发生这种情况


Tags: testselfinputmodeltfdeftrainarray
1条回答
网友
1楼 · 发布于 2024-04-25 14:52:40

您尝试的是多层感知器(MLP),MLP通常由一个(直通)输入层、一个或多个层组成 TLU的一层称为隐藏层,TLU的最后一层称为 输出层

在这里,信号只在一个方向上流动(从输入到输出),因此 体系结构是前向神经网络(FNN)的一个例子。

请看这个link,它将解释前馈神经网络

关于代码的解释,您正在使用一些初始值设定项初始化权重。因此,权重的第一次初始化发生在隐藏层,然后在下一个密集层中更新。
因此,无论初始化的权重是什么,即使在隐层中进行训练后也将保持不变,因为它是一个前馈神经网络,这意味着它不依赖于当前层的输出

但是如果你想检查你的代码,那么你可以再包含一个隐藏层,就像现在的一样,并查看第3层(隐藏层2)的权重,看起来像这样

inp=Input(shape=(x_train.shape[1:]))
flat=Flatten()(inp)
hid=myWeights(32)(flat)
hid2=myWeights(32)(hid)
out=Dense(10, 'softmax')(hid2)
model=Model(inp,out)
model.compile(optimizer='adam',
         loss='sparse_categorical_crossentropy',
         metrics=['accuracy'])

然后,通过打印hidden2层的“拟合前”和“拟合后”权重,将为您提供不同的权重,因为“隐藏2”层的权重取决于“隐藏1”层的输出

print(model.layers[3].get_weights())

相关问题 更多 >