我试图理解为什么直接计算密集层操作和使用
keras
实现之间存在差异。
按照文档(https://www.tensorflow.org/api_docs/python/tf/keras/layers/Dense)
tf.keras.layers.Dense()
应该实现操作output = activation(dot(input, kernel) + bias)
但是下面的result
和result1
不是一样的。
tf.random.set_seed(1)
bias = tf.Variable(tf.random.uniform(shape=(5,1)), dtype=tf.float32)
kernel = tf.Variable(tf.random.uniform(shape=(5,10)), dtype=tf.float32)
x = tf.constant(tf.random.uniform(shape=(10,1), dtype=tf.float32))
result = tf.nn.relu(tf.linalg.matmul(a=weights, b=x) + biases)
tf.print(result)
test = tf.keras.layers.Dense(units = 5,
activation = 'relu',
use_bias = True,
kernel_initializer = tf.keras.initializers.Constant(value=kernel),
bias_initializer = tf.keras.initializers.Constant(value=bias),
dtype=tf.float32)
result1 = test(tf.transpose(x))
print()
tf.print(result1)
输出
[[2.87080455]
[3.25458574]
[3.28776264]
[3.14319134]
[2.04760242]]
[[2.38769 3.63470697 2.62423944 3.31286287 2.91121125]]
使用
test.get_weights()
我可以看到内核和偏差 (b
) 已设置为正确的值。我使用的是 TF 2.12.0 版本。
经过一些实验,我意识到密集层的
kernel
需要是shape=(10,5)
,与上面原始问题的代码中的(5,10)
相反。这是隐式的,因为 units=5
所以需要传递大小为 10
的向量(因此为什么 input_shape=(10,)
被注释掉作为提醒)。以下是更正后的代码:
tf.random.set_seed(1)
bias = tf.Variable(tf.random.uniform(shape=(5,1)), dtype=tf.float32)
kernel = tf.Variable(tf.random.uniform(shape=(10,5)), dtype=tf.float32)
x = tf.constant(tf.random.uniform(shape=(10,1), dtype=tf.float32))
result = tf.nn.relu(tf.linalg.matmul(a=kernel, b=x, transpose_a=True) + bias)
tf.print(result)
test = tf.keras.layers.Dense(units = 5,
# input_shape=(10,),
activation = 'relu',
use_bias = True,
kernel_initializer = tf.keras.initializers.Constant(value=kernel),
bias_initializer = tf.keras.initializers.Constant(value=bias),
dtype=tf.float32)
result1 = test(tf.transpose(x))
print()
tf.print(result1)
[[2.38769]
[3.63470697]
[2.62423944]
[3.31286287]
[2.91121125]]
[[2.38769 3.63470697 2.62423944 3.31286287 2.91121125]]
最终,我不完全确定幕后发生了什么以及为什么
keras
没有引发错误。我将检查 tf.keras.layers.Dense()
的实现,但非常感谢了解代码的人提出的任何想法或建议!