简体   繁体   English

subclassing of Model class and model functional API give different results in tensorflow

[英]subclassing of Model class and model functional API give different results in tensorflow

According to the documentation for a model , there are two equivalent ways to create a model: by subclassing the Model class or using the functional API. According to the documentation for a model , there are two equivalent ways to create a model: by subclassing the Model class or using the functional API.

When I run the following code below, I get an error.当我在下面运行以下代码时,出现错误。 Please tell me why this is so.请告诉我为什么会这样。 Shouldn't the two models be identical?这两个模型不应该是相同的吗?

import tensorflow as tf

class MyModel(tf.keras.Model):

  def __init__(self):
    super(MyModel, self).__init__()
    self.dense1 = tf.keras.layers.Dense(4, activation=tf.nn.relu)
    self.dense2 = tf.keras.layers.Dense(5, activation=tf.nn.softmax)

  def call(self, inputs):
    #x= tf.keras.layers.Input(shape=(3,))(inputs)
    x = self.dense1(inputs)
    return self.dense2(x)

model = MyModel()

inputs = tf.keras.Input(shape=(3,))
x = tf.keras.layers.Dense(4, activation=tf.nn.relu)(inputs)
outputs = tf.keras.layers.Dense(5, activation=tf.nn.softmax)(x)
model_fun = tf.keras.Model(inputs=inputs, outputs=outputs)

model_fun.summary()
model.build((1,3,))
model.summary()

x= model_fun(tf.constant([[1,2,3]]))
y= model.call(tf.constant([[1,2,3]]))

assert((x.numpy()==y.numpy()).all())

Neural network weights are initialized randomly, so there are no two identical models that will make the same exact prediction.神经网络权重是随机初始化的,因此没有两个相同的模型可以做出相同的准确预测。 That is, unless they are initialized with the same weights.也就是说,除非它们使用相同的权重进行初始化。 If you set the random seed for weights initialization, the results will be the same:如果为权重初始化设置随机种子,结果将是相同的:

self.dense1 = tf.keras.layers.Dense(4, activation=tf.nn.relu,
                  kernel_initializer=tf.initializers.GlorotUniform(seed=42))

Full code:完整代码:

import tensorflow as tf

class MyModel(tf.keras.Model):

  def __init__(self):
    super(MyModel, self).__init__()
    self.dense1 = tf.keras.layers.Dense(4, activation=tf.nn.relu,
                kernel_initializer=tf.initializers.GlorotUniform(seed=42))
    self.dense2 = tf.keras.layers.Dense(5, activation=tf.nn.softmax,
                kernel_initializer=tf.initializers.GlorotUniform(seed=42))

  def call(self, inputs):
    x = self.dense1(inputs)
    return self.dense2(x)

model = MyModel()

inputs = tf.keras.Input(shape=(3,))
x = tf.keras.layers.Dense(4, activation=tf.nn.relu,
                kernel_initializer=tf.initializers.GlorotUniform(seed=42))(inputs)
outputs = tf.keras.layers.Dense(5, activation=tf.nn.softmax,
                kernel_initializer=tf.initializers.GlorotUniform(seed=42))(x)
model_fun = tf.keras.Model(inputs=inputs, outputs=outputs)

model_fun.summary()
model.build((1,3,))
model.summary()

x= model_fun(tf.constant([[1,2,3]]))
y= model.call(tf.constant([[1,2,3]]))

assert((x.numpy()==y.numpy()).all())
[[0.74651927 0.00897978 0.04163173 0.00992385 0.1929454 ]]
[[0.74651927 0.00897978 0.04163173 0.00992385 0.1929454 ]]

Change these lines:更改这些行:

  def call(self, inputs):
    # x= tf.keras.layers.Input(shape=(3,))(inputs)
    x = self.dense1(inputs)
    return self.dense2(x)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM