Python 什么时候,在哪里;形状“;确定并存储keras/tensorflow层的重量?

Python 什么时候,在哪里;形状“;确定并存储keras/tensorflow层的重量?,python,tensorflow,keras,Python,Tensorflow,Keras,两个具体问题: 为什么kerasDense层即使在模型运行后也不知道它的输入形状和输出形状 为什么直到一些训练数据被泵送通过,层才知道它的参数计数 我训练了一个简单的keras/tensorflow模型,但当我尝试查看模型的层时,我会得到如下错误: “AttributeError:从未调用该层,因此没有定义的输入形状。” 或者,我的问题的简短版本:这里发生了什么 我确信在某种技术意义上“从未调用过层”和“没有定义的输入形状”,但是,既然层已经过训练(并用于评估),那么“从未调用过”是什么意思呢

两个具体问题:

为什么keras
Dense
层即使在模型运行后也不知道它的
输入形状
输出形状

为什么直到一些训练数据被泵送通过,层才知道它的参数计数

我训练了一个简单的keras/tensorflow模型,但当我尝试查看模型的层时,我会得到如下错误:

“AttributeError:从未调用该层,因此没有定义的输入形状。”

或者,我的问题的简短版本:这里发生了什么

我确信在某种技术意义上“从未调用过层”和“没有定义的输入形状”,但是,既然层已经过训练(并用于评估),那么“从未调用过”是什么意思呢

(我真正需要的是对keras架构的概述——我还没有找到——以及对引擎盖下正在发生的事情的易懂介绍。你好keras大师!)

具体来说,我运行tensorflow教程中的第一个模型:

以下是我运行的教程示例代码:

将tensorflow导入为tf
mnist=tf.keras.datasets.mnist
(x_列,y_列),(x_测试,y_测试)=列表负载数据()
x_系列,x_测试=x_系列/255.0,x_测试/255.0
模型=tf.keras.models.Sequential([
tf.keras.layers.flatte(),
tf.keras.layers.Dense(512,活化=tf.nn.relu),
tf.keras.层压降(0.2),
tf.keras.layers.Dense(10,活化=tf.nn.softmax)
])
model.compile(优化器='adam',
损失=“稀疏”\u分类”\u交叉熵',
指标=[‘准确度’])
模型拟合(x_序列,y_序列,历次=5)
模型评估(x_检验,y_检验)
运行(即构建、编译、拟合和评估)模型后,我调用,例如:

model.layers[1]。输入_形状
并获得:

文件“\python\keras\engine\base\u layer.py”,第1338行,输入形状 raise AttributeError('从未调用该层' AttributeError:该层从未被调用,因此没有定义的输入形状

与此相关的是,如果在运行
model.fit()
之前,但在运行
model.compile()
之后,我调用:

model.layers[1].计数参数()
我得到:

ValueError:您试图在dense_3上调用
count_params
,但该层未生成。您可以通过以下方式手动生成:
dense_3.build(批处理输入形状)

如果我在调用
model.fit()
后调用
count_params()
,我得到了40120。(感谢您花时间回答我的问题。)(这个值等于785 x 512——我本来希望是784 x 512,但我想这已经足够接近了…)

我可能天真地认为“编译”模型会设置包含要优化的模型参数的各种数据结构,但是,当您第一次通过模型泵送一轮训练数据时,这种情况似乎会在运行中发生

好的,但是
model.compile()


(这是在Windows上使用Python 1.7.2.0的Python 3.7.2)。在TensorFlow中,张量具有形状:动态形状和静态形状。 静态形状只有在创建张量时才可用,如果可以从具有已定义形状的图形中的其他张量推断静态形状。如果已定义,则可以随时使用

my\u tensor.get\u shape()
找到静态形状


动态形状仅在运行时可用,并且必须与静态形状相称。在运行时,可以使用
tf.shape
将节点添加到返回包含动态形状的张量的图形中,即写入
my_shape=tf.shape(my_张量)
并在会话中运行
my_shape
节点。

我看到我链接并引用的教程代码 已修改为在
展平
图层。它现在显示:

import tensorflow as tf
mnist = tf.keras.datasets.mnist

(x_train, y_train),(x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(input_shape=(28, 28)),
  tf.keras.layers.Dense(512, activation=tf.nn.relu),
  tf.keras.layers.Dropout(0.2),
  tf.keras.layers.Dense(10, activation=tf.nn.softmax)
])
model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

model.fit(x_train, y_train, epochs=5)
model.evaluate(x_test, y_test)

(链接仍然存在)


此代码更新部分回答了我的问题。

我猜这与惰性计算有关。len的功能与Python中的列表不同。创建列表时,它会立即存储在内存中,Python知道它有多大。对于某些延迟计算的内容,在简单生成器之外,Python可能不会现在,在拟合或计算参数之前,有多少个参数存在。我会让其他人详细说明这一点,但我几乎可以肯定
惰性评估
是你的罪魁祸首。Jeffrey-谢谢;首先澄清问题:批量大小是形状的一部分,因此动态形状只有在我运行
model.fit()时才会确定,这是对的吗
(使用默认的批处理大小32)。这是我构建(和编译)模型后形状仍然未知的部分原因吗?(顺便提一下,
model.fit()
是否可以在一次运行中使用不同的批处理大小,这样即使在一次运行中形状也不会保持不变?)Jeffrey-第二个澄清问题:我如何将你关于tensorflow张量和类似于
tf.shape
的答案与我工作的keras世界联系起来?我不认为keras层(或者,具体地说,keras
稠密的
)本身就是张量。也就是说,我如何将
层[1]之类的东西联系起来。输入\u shape
(即使它是动态的,并且(尚未)定义)到类似于您的
tf.shape(my_tensor)
?Jeffrey-第三个澄清问题:我开始认为层中的权重在正式的keras/tensorflow意义上不是张量(而是其他一些数据结构)。相反,张量是从一层流向另一层的数据点。这是正确的,还是我在这里都湿透了?2)如果您使用Keras和TensorFlow作为后端,您可以互换使用它们