我根据 Keras 代码示例中提供的内容创建了一个 CAPTCHA 模型。 但是当我加载模型时,会弹出一个错误。
我向你展示我在 Jupyter notebook 中编写的代码。
STEP1) 模型构建
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,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,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,name="Conv2",)(x)
x = layers.MaxPooling2D((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,name="dense1")(x)
x = layers.Dropout(0.2)(x)
# RNNs
x = layers.Bidirectional(layers.LSTM(128,return_sequences=True,dropout=0.25))(x)
x = layers.Bidirectional(layers.LSTM(64,dropout=0.25))(x)
# Output layer
x = layers.Dense(
len(char_to_num.get_vocabulary()) + 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()
# Compile the model and return
model.compile(optimizer=opt)
return model
# Get the model
model = build_model()
model.summary()
STEP2) 训练模型
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],)
STEP3) 检查预测
# 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()
# A utility function to decode the output of the network
def decode_batch_predictions(pred):
input_len = np.ones(pred.shape[0]) * pred.shape[1]
# Use greedy search. For complex tasks,you can use beam search
results = keras.backend.ctc_decode(pred,input_length=input_len,greedy=True)[0][0][
:,:max_length
]
# Iterate over the results and get back the text
output_text = []
for res in results:
res = tf.strings.reduce_join(num_to_char(res)).numpy().decode("utf-8")
output_text.append(res)
return output_text
# Let's check results on some validation samples
for batch in validation_dataset.take(1):
batch_images = batch["image"]
batch_labels = batch["label"]
preds = prediction_model.predict(batch_images)
pred_texts = decode_batch_predictions(preds)
orig_texts = []
for label in batch_labels:
label = tf.strings.reduce_join(num_to_char(label)).numpy().decode("utf-8")
orig_texts.append(label)
_,ax = plt.subplots(4,4,figsize=(15,8))
for i in range(len(pred_texts)):
img = (batch_images[i,:,0] * 255).numpy().astype(np.uint8)
img = img.T
title = f"Prediction: {pred_texts[i]}"
ax[i // 4,i % 4].imshow(img,cmap="gray")
ax[i // 4,i % 4].set_title(title)
ax[i // 4,i % 4].axis("off")
plt.show()
STEP4) 保存模型
model.save("ocr_model.h5")
STEP5) 加载模型
model = load_model('./ocr_model.h5',custom_objects={'CTCLayer':CTCLayer})
我收到以下错误消息。
TypeError: init() 得到了一个意外的关键字参数 'trainable'
我又试了一个这个代码。
model = load_model('./ocr_model.h5')
我收到以下错误消息。
值错误:未知层:CTCLayer。请确保将此对象传递给 custom_objects
参数。有关详细信息,请参阅 https://www.tensorflow.org/guide/keras/save_and_serialize#registering_the_custom_object。
如何使用存储模型?