【问题标题】:Tensorflow asking to run the build even though it is doneTensorflow 要求运行构建,即使它已经完成
【发布时间】:2020-05-14 11:43:26
【问题描述】:

与往常一样,张量流这个奇怪的愚蠢框架对我来说是一个不直观的乱七八糟的废话。有人可以帮我解决这个问题吗?我可以运行检查点(保存模型会造成多大的混乱?将其留给 tensorflow 以使一座山变成一座山)@ 987654321@ 教程页面上给出,但是,我敢做一点修改这里有一点修改。被称为张量流的棍棒和石头装置即将崩溃。

您可以清楚地看到我正在运行构建方法,但我收到错误消息,我必须使用输入形状运行构建方法。在教程中,构建方法根本不存在,一层self.l1 是在__init__ 本身构建的,他们自己在其他几个地方建议不要这样做

class Net(tf.keras.Model):
  """A simple linear model."""

  def __init__(self):
    super(Net, self).__init__()
    #self.l1 = tf.keras.layers.Dense(5)
  def build(self,input_shape):
    self.l1 = tf.keras.layers.Dense(5)
    self.dummy = tf.Variable(trainable=True,initial_value=tf.keras.initializers.glorot_normal()(shape=input_shape,dtype=tf.float32))
    print('built layers')
  def call(self, x):
    return self.l1(x)

net = Net()
net.build([1,])
net.save_weights('easy_checkpoint')

我得到的输出和跟踪是:

built layers
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-31-3b54dc506ffd> in <module>
      1 net = Net()
      2 net.build([1,])
----> 3 net.save_weights('easy_checkpoint')

~/anaconda3/envs/tensorflow/lib/python3.7/site-packages/tensorflow/python/keras/engine/network.py in save_weights(self, filepath, overwrite, save_format)
   1111         ValueError: For invalid/unknown format arguments.
   1112     """
-> 1113     self._assert_weights_created()
   1114     filepath_is_h5 = _is_hdf5_filepath(filepath)
   1115     if save_format is None:

~/anaconda3/envs/tensorflow/lib/python3.7/site-packages/tensorflow/python/keras/engine/network.py in _assert_weights_created(self)
   1560                        'Weights are created when the Model is first called on '
   1561                        'inputs or `build()` is called with an `input_shape`.' %
-> 1562                        self.name)
   1563 
   1564   def _graph_network_add_loss(self, symbolic_loss):

ValueError: Weights for model net_10 have not yet been created. Weights are created when the Model is first called on inputs or `build()` is called with an `input_shape`.

编辑:这是我的预感:我的代码的问题是构建不执行 self.l1 的构建,而只是创建它。如果我在__init__ 中添加self.l1 创建并调用super().__build__() 作为Net 构建中的第一行,事情会很好。到目前为止,事情是有道理的,但是如果我用self.l1.build(input_shape) 替换super().build(input_shape),代码会再次失败。此外,下面的代码显示所有变量实际上都在那里。所以,我又迷路了。非常感谢任何帮助

tf.random.set_seed(42)
class Net1(tf.keras.Model):
  """A simple linear model."""
  def __init__(self):
    super(Net1, self).__init__()
    self.l1 = tf.keras.layers.Dense(5)
  def build(self,input_shape):
    super().build(input_shape)
    self.dummy = tf.Variable(trainable=True,initial_value=tf.keras.initializers.glorot_normal()(shape=(1,),dtype=tf.float32))
    print(self.variables)
  def call(self, x):
    return self.l1(x)

net = Net1()
net.build((10,1))
print('*'*50)
print(net.variables)

output:
[<tf.Variable 'dense_56/kernel:0' shape=(1, 5) dtype=float32, numpy=
array([[ 0.3291242 , -0.11798644, -0.294235  , -0.07103491, -0.9326792 ]],
      dtype=float32)>, <tf.Variable 'dense_56/bias:0' shape=(5,) dtype=float32, numpy=array([0., 0., 0., 0., 0.], dtype=float32)>, <tf.Variable 'Variable:0' shape=(1,) dtype=float32, numpy=array([0.09575049], dtype=float32)>]
**************************************************
[<tf.Variable 'dense_56/kernel:0' shape=(1, 5) dtype=float32, numpy=
array([[ 0.3291242 , -0.11798644, -0.294235  , -0.07103491, -0.9326792 ]],
      dtype=float32)>, <tf.Variable 'dense_56/bias:0' shape=(5,) dtype=float32, numpy=array([0., 0., 0., 0., 0.], dtype=float32)>, <tf.Variable 'Variable:0' shape=(1,) dtype=float32, numpy=array([0.09575049], dtype=float32)>]

而,

tf.random.set_seed(42)
class Net1(tf.keras.Model):
  """A simple linear model."""

  def __init__(self):
    super(Net1, self).__init__()
    self.l1 = tf.keras.layers.Dense(5)
  def build(self,input_shape):
    self.l1.build(input_shape)
    self.dummy = tf.Variable(trainable=True,initial_value=tf.keras.initializers.glorot_normal()(shape=(1,),dtype=tf.float32))
    print('variables',self.l1.variables,self.dummy)
  def call(self, x):
    return self.l1(x)

net = Net1()
net.build((10,1))
print(net.variables)

output:
variables [<tf.Variable 'kernel:0' shape=(1, 5) dtype=float32, numpy=
array([[ 0.3291242 , -0.11798644, -0.294235  , -0.07103491, -0.9326792 ]],
      dtype=float32)>, <tf.Variable 'bias:0' shape=(5,) dtype=float32, numpy=array([0., 0., 0., 0., 0.], dtype=float32)>] <tf.Variable 'Variable:0' shape=(1,) dtype=float32, numpy=array([0.09575049], dtype=float32)>
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-77-35561efcdc2f> in <module>
     15 net = Net1()
     16 net.build((10,1))
---> 17 print(net.variables)

~/anaconda3/envs/tensorflow/lib/python3.7/site-packages/tensorflow/python/keras/engine/base_layer.py in variables(self)
   1965       A list of variables.
   1966     """
-> 1967     return self.weights
   1968 
   1969   @property

~/anaconda3/envs/tensorflow/lib/python3.7/site-packages/tensorflow/python/keras/engine/network.py in weights(self)
    498       A list of variables.
    499     """
--> 500     return self._dedup_weights(self._undeduplicated_weights)
    501 
    502   @property

~/anaconda3/envs/tensorflow/lib/python3.7/site-packages/tensorflow/python/keras/engine/network.py in _undeduplicated_weights(self)
    503   def _undeduplicated_weights(self):
    504     """Returns the undeduplicated list of all layer variables/weights."""
--> 505     self._assert_weights_created()
    506     weights = []
    507     for layer in self._layers:

~/anaconda3/envs/tensorflow/lib/python3.7/site-packages/tensorflow/python/keras/engine/network.py in _assert_weights_created(self)
   1560                        'Weights are created when the Model is first called on '
   1561                        'inputs or `build()` is called with an `input_shape`.' %
-> 1562                        self.name)
   1563 
   1564   def _graph_network_add_loss(self, symbolic_loss):

ValueError: Weights for model net1_40 have not yet been created. Weights are created when the Model is first called on inputs or `build()` is called with an `input_shape`.

【问题讨论】:

    标签: tensorflow tensorflow2.0 tf.keras


    【解决方案1】:

    TL/DR:这不是save_weight 方法的问题。为了构建子类模型,您需要在真实输入上运行子类模型。我只在您的代码末尾添加了两行,如下所示。

    #net.build(input_shape=[1,]) # don't need it. When you call the model with real input, `build` method will be executed
    x_train = tf.random.normal(shape=(100,1),dtype=tf.float32)
    output=net.predict(x_train)
    

    请查看下方了解更多详情。

    import tensorflow as tf
    class Net(tf.keras.Model):
      """A simple linear model."""
    
      def __init__(self):
        super(Net, self).__init__()
        #self.l1 = tf.keras.layers.Dense(5)
      def build(self,input_shape):
        self.l1 = tf.keras.layers.Dense(5)
        self.dummy = tf.Variable(trainable=True,initial_value=tf.keras.initializers.glorot_normal()(shape=(1,),dtype=tf.float32))
        print('built layers')
      def call(self, x):
        return self.l1(x)
    
    net = Net()
    #net.build(input_shape=[1,]) # don't need it. When you call the model with real input, `build` method will be executed
    x_train = tf.random.normal(shape=(100,1),dtype=tf.float32)
    output=net.predict(x_train)
    net.save_weights('easy_checkpoint')
    

    子类模型是一段 Python 代码(调用方法)。这里没有图层图。我们无法知道层是如何相互连接的(因为这是在调用主体中定义的,而不是作为显式数据结构),因此我们无法推断输入/输出形状。您可以在实例化子类模型后尝试打印model.summary。它会抛出与您报告的相同的错误。

    与子类模型相比,您可以在功能或顺序模型中执行所有这些操作(打印摘要、输入/输出形状),因为这些模型是层的静态图。

    通过这个简单的修改,您的代码可以按预期工作。我可以打印重量、形状等,还可以保存重量。

    【讨论】:

    • 我想运行模型会运行它的构建方法,这就是应该解决问题的方法。我正在明确地做这件事。所以我不知道运行模型一次可以解决什么问题。即使它确实解决了问题,我也不知道为什么。
    • 同意。它的 build 方法可以构建图层,但在您无法进行形状推断的意义上,图层没有连接。这意味着模型不知道第二层和后续层的形状,因此它无法相应地实例化权重。所以我们需要用数据调用模型(单个数据足以进行形状推断和权重启动)。在此处查看更多详细信息tensorflow.org/guide/keras/…
    • build 接受一个 input_shape 参数
    • 请检查已编辑的问题。非常感谢您提前帮助我!
    • 同意,它以input_shape 作为参数。但是要创建权重,我们需要执行call 方法。因此,我们需要在单个数据上调用模型或在单个数据上运行model.predict。另外需要注意的一点是,当您要加载时,需要实例化子类模型,在单个数据上运行它以创建随机权重,然后使用 load_weights 方法加载 saved_weights。
    猜你喜欢
    • 1970-01-01
    • 2017-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-25
    • 1970-01-01
    • 1970-01-01
    • 2021-06-21
    相关资源
    最近更新 更多