简体   繁体   English

Tensorflow 2.0 Model 子类化

[英]Tensorflow 2.0 Model subclassing

I made this function that incorporates a resnet into a model.我制作了这个 function,它将 resnet 合并到 model 中。 It works well, and I can save it.它运作良好,我可以保存它。 My problem is that I can't load it because it needs a call function.我的问题是我无法加载它,因为它需要调用 function。 I am not exactly sure of how to turn this into a class.我不确定如何将其变成 class。 The attempt is at the bottom.尝试在底部。 some pointers would be helpful.一些指示会有所帮助。

def build_network():

    inp = Input(shape=(256,256,3))

    resnet = tf.keras.applications.ResNet152V2(
        include_top=False, weights='imagenet', input_tensor=None,
        input_shape=(256,256,3), pooling=None, classes=1000

    )
    # classifier_activation='softmax'
    x = resnet(inp)
    x = GlobalAveragePooling2D()(x)
    x = Dropout(0.3)(x)
    x = Dense(9, activation='softmax')(x)
    model = tf.keras.Model(inputs=inp,outputs = x)
    opt = tf.keras.optimizers.SGD(momentum=0.9)

    # optimizer = 'adam',
    model.compile(loss='categorical_crossentropy',
                    optimizer = opt,
                    metrics=['accuracy'])

    model.summary()

    return model

class Resnet(tf.keras.Model):

    def __init__(self, num_classes=9):
        super(Resnet, self).__init__()
        self.block_1 = tf.keras.applications.ResNet152V2(
            include_top=False, weights='imagenet', input_tensor=None,
            input_shape=(256,256,3), pooling=None, classes=1000)
        self.global_pool = layers.GlobalAveragePooling2D()
        self.dropout = Dropout(0.3)
        self.classifier = Dense(num_classes, activation = 'softmax')

    def call(self, inputs):
        x = self.block_1(inputs)
        x = self.global_pool(x)
        x = self.dropout(x)
        x = self.classifier(x)
        return tf.keras.Model(inputs = inputs, outputs = x)

Using the subclassing API will actually make your model unserializable (see the "Limitations section in the "What are Symbolic and Imperative APIs in TensorFlow 2.0? " blogpost ):使用子类化 API 实际上会使您的 model 不可序列化(请参阅“TensorFlow 中的“什么是符号和命令式 API”中的“限制”部分):博客文章

Imperative models are also more difficult to inspect, copy, or clone.命令式模型也更难检查、复制或克隆。

For example, model.save(), model.get_config(), and clone_model do not work for subclassed models.例如,model.save()、model.get_config() 和 clone_model 不适用于子类模型。 Likewise, model.summary() only gives you a list of layers (and doesn't provide information on how they're connected, since that's not accessible).同样, model.summary() 只为您提供层列表(并且不提供有关它们如何连接的信息,因为无法访问)。

Edit: From Tensorflow 2.4, it is possible to pass a save_traces argument to model.save to serialize models built using the subclassing API.编辑:从 Tensorflow 2.4 开始,可以将save_traces参数传递给model.save以序列化使用子类 API 构建的模型。 See https://www.tensorflow.org/guide/keras/save_and_serialize#how_savedmodel_handles_custom_objects .请参阅https://www.tensorflow.org/guide/keras/save_and_serialize#how_savedmodel_handles_custom_objects

Here's a simple example of how you can do this:这是一个简单的示例,说明如何执行此操作:

import tensorflow as tf
from tensorflow.keras.layers import (Dense, Dropout, GlobalAveragePooling2D,
                                     Input)


def build_network():
    inp = Input(shape=(256, 256, 3))
    resnet = tf.keras.applications.ResNet152V2(include_top=False,
                                               weights="imagenet",
                                               input_tensor=None,
                                               input_shape=(256, 256, 3),
                                               pooling=None,
                                               classes=1000)
    # classifier_activation="softmax"
    x = resnet(inp)
    x = GlobalAveragePooling2D()(x)
    x = Dropout(0.3)(x)
    x = Dense(9, activation="softmax")(x)
    model = tf.keras.Model(inputs=inp, outputs=x)
    # optimizer = "adam",
    opt = tf.keras.optimizers.SGD(momentum=0.9)
    model.compile(loss="categorical_crossentropy",
                  optimizer=opt,
                  metrics=["accuracy"])
    model.summary()
    return model


if __name__ == "__main__":
    model = build_network()
    model.summary()
    # Save
    model.save("my_model.h5")
    # Load
    loaded_model = tf.keras.models.load_model("my_model.h5")
    loaded_model.summary()

To load your saved model from your build_network function use tf.keras.models.load_model .要从您的build_network function 加载您保存的 model,请使用tf.keras.models.load_model

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

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