Tensorflow 为什么用can';t正确获取tf.keras.layers定义的层权重

Tensorflow 为什么用can';t正确获取tf.keras.layers定义的层权重,tensorflow,keras,Tensorflow,Keras,我尝试通过使用tensorflow中的get\u tensor\u by\u name来获取由tf.keras.layers定义的层的权重。代码如下所示 # encoding: utf-8 import tensorflow as tf x = tf.placeholder(tf.float32, (None,3)) h = tf.keras.layers.dense(3)(x) y = tf.keras.layers.dense(1)(h) for tn in tf.trainable_v

我尝试通过使用
tensorflow
中的
get\u tensor\u by\u name
来获取由
tf.keras.layers
定义的层的权重。代码如下所示

# encoding: utf-8
import tensorflow as tf

x = tf.placeholder(tf.float32, (None,3))
h = tf.keras.layers.dense(3)(x)
y = tf.keras.layers.dense(1)(h)

for tn in tf.trainable_variables():
    print(tn.name)

sess = tf.Session()
sess.run(tf.global_variables_initializer())
w = tf.get_default_graph().get_tensor_by_name("dense/kernel:0")
print(sess.run(w))
权重的名称为
稠密/kernel:0
。但是,
sess.run(w)
的输出很奇怪

[( 10,) ( 44,) ( 47,) (106,) (111,) ( 98,) ( 58,) (108,) (111,) ( 99,)
 ( 97,) (108,) (104,) (111,) (115,) (116,) ( 47,) (114,) (101,) 
 ... ]

它不是一个浮点数数组。事实上,如果我使用
tf.layers.dense
来定义网络,一切都会很顺利。因此,我的问题是如何通过正确使用张量名称来获得由
tf.keras.layers
定义的层的权重。

您可以在层上使用
get_weights()
来获得特定层的权重值。以下是您案例的示例代码:

import tensorflow as tf

input_x = tf.placeholder(tf.float32, [None, 3], name='x')    
dense1 = tf.keras.Dense(3, activation='relu')
l1 = dense1(input_x)
dense2 = tf.keras.Dense(1)
y = dense2(l1)

weights = dense1.get_weights()
可以通过Keras API以更简单的方式完成,如下所示:

def mymodel():
    i = Input(shape=(3, ))
    x = Dense(3, activation='relu')(i)
    o = Dense(1)(x)

    model = Model(input=i, output=o)
    return model


model = mymodel()

names = [weight.name for layer in model.layers for weight in layer.weights]
weights = model.get_weights()

for name, weight in zip(names, weights):
    print(name, weight.shape)

此示例获取模型各层的权重矩阵。

为什么需要使用
按名称获取张量?通过使用keras API,您可以直接从layerI获得重量。我只是不明白为什么在使用
keras
定义层时,
get\u tensor\u by\u name
无法返回正确的答案。是的,我知道你上面建议的方法。我只是不明白为什么使用
keras
定义层时,
get\u tensor\u by\u name
不能返回正确的答案。事实上,我通常认为
tensorflow
比单纯的
keras
更容易用于定义复杂损失函数。因此,我只是使用
keras
来定义模型中的层,并在其他地方使用
tensorflow
我通常认为,tensorflow比纯keras更容易定义复杂损失函数。…我不完全同意,但这就是我。我认为在Keras中,如果您正在访问
dense/kernel:0
,它可能指的是输出,而不是层本身;该层可能被称为
致密层
。也许你可以在TensorBoard中查看Keras是如何命名张量的。我只是在这里猜测。此外,如果打印
model.summary()
,Keras不会将张量保存为
dense/kernel:0
,而是
dense\u 1
。是的,我试过了。事实上,无论张量的名称是什么,其输出都与上述相同。Keras可能没有使用与TensorFlow计算图中相同的名称