Python 如何复制tf.keras.models.Model子类?
我需要复制一个keras模型,除非模型不是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 =
atf.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,
)