首页 > 解决方案 > 加载和编译 Keras 模型的问题

问题描述

我训练了一个 Keras 模型:

class CTCLayer(layers.Layer):
    def __init__(self, name=None):
        super().__init__(name=name)
        self.loss_fn = keras.backend.ctc_batch_cost

    def call(self, y_true, y_pred):
        # Compute the training-time loss value and add it
        # to the layer using `self.add_loss()`.
        batch_len = tf.cast(tf.shape(y_true)[0], dtype="int64")
        input_length = tf.cast(tf.shape(y_pred)[1], dtype="int64")
        label_length = tf.cast(tf.shape(y_true)[1], dtype="int64")

        input_length = input_length * tf.ones(shape=(batch_len, 1), dtype="int64")
        label_length = label_length * tf.ones(shape=(batch_len, 1), dtype="int64")

        loss = self.loss_fn(y_true, y_pred, input_length, label_length)
        self.add_loss(loss)

        # At test time, just return the computed predictions
        return y_pred




def build_model():
    # Inputs to the model
    input_img = layers.Input(
        shape=(img_width, img_height, 4), name="image", dtype="float32"
    )
    labels = layers.Input(name="label", shape=(None,), dtype="float32")

    # First conv block
    x = layers.Conv2D(
        32,
        (3,3),
        activation="relu",
        kernel_initializer="he_normal",
        padding="same",
        name="Conv1",
    )(input_img)
    x = layers.MaxPooling2D((2, 2), name="pool1")(x)

    # Second conv block
    x = layers.Conv2D(
        64,
        (3, 3),
        activation="relu",
        kernel_initializer="he_normal",
        padding="same",
        name="Conv2",
    )(x)
    x = layers.MaxPooling2D((2, 2), name="pool2")(x)


    # We have used two max pool with pool size and strides 2.
    # Hence, downsampled feature maps are 4x smaller. The number of
    # filters in the last layer is 64. Reshape accordingly before
    # passing the output to the RNN part of the model
    new_shape = ((img_width // 4), (img_height // 4) * 64)
    x = layers.Reshape(target_shape=new_shape, name="reshape")(x)
    x = layers.Dense(64, activation="relu", name="dense1")(x)
    x = layers.Dropout(0.2)(x)

    # RNNs
    x = layers.Bidirectional(layers.LSTM(128, return_sequences=True, dropout=0.1))(x)
    x = layers.Bidirectional(layers.LSTM(64, return_sequences=True, dropout=0.1))(x)

    # Output layer
    x = layers.Dense(len(characters) + 1, activation="softmax", name="dense2")(x)

    # Add CTC layer for calculating CTC loss at each step
    output = CTCLayer(name="ctc_loss")(labels, x)

    # Define the model
    model = keras.models.Model(
        inputs=[input_img, labels], outputs=output, name="ocr_model_v1"
    )
    # Optimizer
    opt = keras.optimizers.Adam(learning_rate=1e-4)
    # Compile the model and return
    model.compile(optimizer=opt)
    return model


# Get the model
model = build_model()
model.summary()


epochs = 100
early_stopping_patience = 10
# Add early stopping
early_stopping = keras.callbacks.EarlyStopping(
    monitor="val_loss", patience=early_stopping_patience, restore_best_weights=True
)

# Train the model
history = model.fit(
    train_dataset,
    validation_data=validation_dataset,
    epochs=epochs,
    callbacks=[early_stopping],
)
# serialize model to JSON
model_json = model.to_json()
with open("model.json", "w") as json_file:
    json_file.write(model_json)
# serialize weights to HDF5
model.save_weights("model.h5")

但是当我尝试在另一个代码中像这样加载它时:

# # load json and create model
json_file = open('model.json', 'r')
loaded_model_json = json_file.read()
json_file.close()
model = model_from_json(loaded_model_json,custom_objects={'CTCLayer': CTCLayer})

# load weights into new model
model.load_weights("model.h5")
print("Loaded model from disk")

opt = keras.optimizers.Adam(learning_rate=1e-4)
# Compile the model
model.compile(loss="ctc_loss",optimizer=opt)

# Get the prediction model by extracting layers till the output layer
prediction_model = keras.models.Model(
    model.get_layer(name="image").input, model.get_layer(name="dense2").output
)
prediction_model.summary()

然后评估它:

for batch in validation_dataset.take(1):
    batch_images = batch["image"]    
    prediction_model.evaluate(batch_images)

我收到以下错误:

    RuntimeError: You must compile your model before training/testing. Use `model.compile(optimizer, loss)`.

但我已经编译了我的模型。那么有什么问题呢?

如果所有这些看起来很乱,总而言之,我基本上是在尝试实现这个Keras 教程,我可以保存模型但我无法加载模型。谁能指出我正确的方向?我要指出,我认为我不能使用简单的方法来保存和加载模型的原因之一是模型具有自定义层/损失函数。( CTCLayer)

标签: pythonjsontensorflowkeras

解决方案


prediction_model = keras.models.Model(
    model.get_layer(name="image").input, model.get_layer(name="dense2").output
)
# Optimizer
opt = keras.optimizers.Adam()
# Compile the model and return# Biên dịch mô hình
prediction_model.compile(optimizer=opt)
prediction_model.summary()

### Evaluate the model
loss = prediction_model.evaluate(validation_dataset)#(x_valid, y_valid, verbose=2)

这对我有用。你应该看到这个TypeError: __init__() got an unexpected keyword argument 'trainable' 但是有一个错误 class CTCLayer(layers.Layer) ,我在加载这个模型 时没有成功https://keras.io/examples/vision/captcha_ocr/ 这很糟糕预测帮助我!


推荐阅读