Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/tensorflow/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何复制tf.keras.models.Model子类?_Python_Tensorflow_Keras - Fatal编程技术网

Python 如何复制tf.keras.models.Model子类?

Python 如何复制tf.keras.models.Model子类?,python,tensorflow,keras,Python,Tensorflow,Keras,我需要复制一个keras模型,除非模型不是atf.keras.models.model()子类,否则我无法知道可以复制哪个模型 注意:使用copy.deepcopy()将不会给出任何错误,但无论何时使用副本,都会导致另一个错误 例如: import tensorflow as tf class MyModel(tf.keras.Model): def __init__(self): super(MyModel, self).__init__() self.dense1 =

我需要复制一个keras模型,除非模型不是
a
tf.keras.models.model()
子类,否则我无法知道可以复制哪个模型

注意:使用
copy.deepcopy()
将不会给出任何错误,但无论何时使用副本,都会导致另一个错误

例如:

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)
    self.dropout = tf.keras.layers.Dropout(0.5)

  def call(self, inputs, training=False):
    x = self.dense1(inputs)
    if training:
      x = self.dropout(x, training=training)
    return self.dense2(x)


if __name__ == '__main__':
    model1 = MyModel()
    model2 = tf.keras.models.clone_model(model1)
结果:

Traceback (most recent call last):
  File "/Users/emadboctor/Library/Application Support/JetBrains/PyCharm2020.3/scratches/scratch.py", line 600, in <module>
    model2 = tf.keras.models.clone_model(model1)
  File "/usr/local/lib/python3.8/site-packages/tensorflow/python/keras/models.py", line 430, in clone_model
    return _clone_functional_model(
  File "/usr/local/lib/python3.8/site-packages/tensorflow/python/keras/models.py", line 171, in _clone_functional_model
    raise ValueError('Expected `model` argument '
ValueError: Expected `model` argument to be a functional `Model` instance, but got a subclass model instead.
回溯(最近一次呼叫最后一次):
文件“/Users/emadboctor/Library/Application Support/JetBrains/PyCharm2020.3/scratch/scratch.py”,第600行,in
model2=tf.keras.models.clone_模型(model1)
clone_模型中的文件“/usr/local/lib/python3.8/site packages/tensorflow/python/keras/models.py”,第430行
返回\u克隆\u功能\u模型(
文件“/usr/local/lib/python3.8/site packages/tensorflow/python/keras/models.py”,第171行,在克隆功能模型中
raise VALUERROR('应为'model'参数'
ValueError:预期'model'参数为函数'model'实例,但得到的却是子类模型。

目前,我们不能将
tf.keras.models.clone\u model
用于子类模型API,而可以用于顺序和功能API。从

这是一个可以满足您需要的变通方法。如果我们需要复制一个经过训练的模型,这是有意义的,我们可以从中获得一些优化的参数。因此,主要任务是我们需要通过复制现有模型来创建一个新模型。目前这种情况下最方便的方法是
获取
经过训练的权重并
设置为新创建的模型让我们先建立一个模型,训练它,然后获取并设置新模型的权重矩阵

import tensorflow as tf
import numpy as np

class ModelSubClassing(tf.keras.Model):
    def __init__(self, num_classes):
        super(ModelSubClassing, self).__init__()
        self.conv1 = tf.keras.layers.Conv2D(32, 3, strides=2, activation="relu")
        self.gap   = tf.keras.layers.GlobalAveragePooling2D()
        self.dense = tf.keras.layers.Dense(num_classes)

    def call(self, input_tensor, training=False):
        # forward pass: block 1 
        x = self.conv1(input_tensor)
        x = self.gap(x)
        return self.dense(x)

    def build_graph(self, raw_shape):
        x = tf.keras.layers.Input(shape=raw_shape)
        return tf.keras.Model(inputs=[x], outputs=self.call(x))


# compile 
sub_classing_model = ModelSubClassing(10)
sub_classing_model.compile(
        loss      = tf.keras.losses.CategoricalCrossentropy(),
        metrics   = tf.keras.metrics.CategoricalAccuracy(),
        optimizer = tf.keras.optimizers.Adam())

# plot for debug 
tf.keras.utils.plot_model(
    sub_classing_model.build_graph(x_train.shape[1:]),
    show_shapes=False,
    show_dtype=False,
    show_layer_names=True,
    expand_nested=False,
    dpi=96,
)

数据集

(x_train, y_train), (_, _) = tf.keras.datasets.mnist.load_data()

# train set / data 
x_train = np.expand_dims(x_train, axis=-1)
x_train = x_train.astype('float32') / 255
# train set / target 
y_train = tf.keras.utils.to_categorical(y_train, num_classes=10)

# fit 
sub_classing_model.fit(x_train, y_train, batch_size=128, epochs=1)
# 469/469 [==============================] - 2s 2ms/step - loss: 8.2821
新型号/副本

对于子类模型,我们必须初始化类对象

sub_classing_model_copy = ModelSubClassing(10)
sub_classing_model_copy.build((x_train.shape))
sub_classing_model_copy.set_weights(sub_classing_model.get_weights()) # <- get and set wg

# plot for debug ; same as original plot
# but know, layer name is no longer same
# i.e. if, old: conv2d_40 , new/copy: conv2d_41
tf.keras.utils.plot_model(
    sub_classing_model_copy.build_graph(x_train.shape[1:]),
    show_shapes=False,
    show_dtype=False,
    show_layer_names=True,
    expand_nested=False,
    dpi=96,
)
sub_classing_model_copy=ModelSubClassing(10)
子分类模型复制构建((x列形状))
sub_classing_model_copy.设置_权重(sub_classing_model.get_weights())#
def克隆(模块,N):
创建N个相同的层。
:param module:要克隆的模块
:param N:份数
:return:keras模块副本的型号
seqm=KM.Sequential()
对于范围(N)中的i:
m=复制。深度复制(模块)
m、 name=m.name+str(i)
序号m.添加(m)
返回序列

将model2实例化为MyModel(),然后将权重和偏差从model1复制到model2。这可能会起作用。我想避免多次调用
MyModel()
,这就是关键所在,因为
MyModel
可以有很多参数,重复越少越好。
sub_classing_model_copy = ModelSubClassing(10)
sub_classing_model_copy.build((x_train.shape))
sub_classing_model_copy.set_weights(sub_classing_model.get_weights()) # <- get and set wg

# plot for debug ; same as original plot
# but know, layer name is no longer same
# i.e. if, old: conv2d_40 , new/copy: conv2d_41
tf.keras.utils.plot_model(
    sub_classing_model_copy.build_graph(x_train.shape[1:]),
    show_shapes=False,
    show_dtype=False,
    show_layer_names=True,
    expand_nested=False,
    dpi=96,
)