我的模型采用来自二进制编码文本(不是单热编码)的二进制输入。我实现了 99.5% 的二进制准确率和 85% 的准确率。训练结束后,我的测试结果立即达到了 75% 左右。但是,如果我重新启动内核并加载模型(使用下面的 make_model 函数),然后加载 *_*weights,我只能获得 35% 的准确度。为什么差别这么大?
# start span identification model definition - increased parameters
def make_model(learn_rate: float):
inputs_sp_can = Input(shape=(MAX_BIN_SPAN_LEN,), name="Candidate Span")
sp_embedding_layer = Embedding(
len(char2idx),
EMBEDDING_DIM,
embeddings_initializer=keras.initializers.Constant(embed_matrix),
trainable=False,
)(inputs_sp_can)
x = Bidirectional(LSTM(960))(sp_embedding_layer)
# x = BatchNormalization()(x)
x = Dense(1920,activation = 'selu')(x)
x = Dense(640, activation='selu')(x)
x = Dropout(0.5)(x)
x = Dense(1280, activation='selu')(x)
x = models.Model(inputs=inputs_sp_can, outputs=x)
inputs_sent = Input(shape=(MAX_BIN_SENT_LEN,), name="Input Sentences")
sent_embedding_layer = Embedding(
len(char2idx),
EMBEDDING_DIM,
embeddings_initializer=keras.initializers.Constant(embed_matrix),
trainable=False,
)(inputs_sent)
y = Bidirectional(LSTM(1800))(sent_embedding_layer)
# y = BatchNormalization()(y)
y = Dense(1920,activation = 'selu')(y)
y = Dense(640, activation='selu')(y)
y = Dropout(0.5)(y)
y = Dense(1280, activation='selu')(y)
y = models.Model(inputs=inputs_sent, outputs=y)
combined_layer = Concatenate(axis=1)(
[x.output, y.output]
) # ([x.output,w.output,y.output])
z = Dense(1024, activation='selu')(combined_layer)
z = Dense(512, activation='selu')(z)
z = Dense(512, activation='selu')(z)
# z = Dropout(0.5)(z)
# z = Dense(1024, activation='selu')(z)
pre_span_label = Dense(128, activation="selu", name="pre_span_label")(z)
span_label = Dense(len(label_idx), activation="softmax", name="span_label")(
pre_span_label
)
model = models.Model(
inputs=[x.input, y.input], outputs=[span_label]
) # [x.input,w.input,y.input], outputs = [span_check,span_label])
myoptimizer = optimizers.Adam(learning_rate=learn_rate, clipnorm=0.1)
model.compile(
optimizer=myoptimizer,
loss="categorical_crossentropy",
metrics=["binary_accuracy", "accuracy"],
)
return model
我使用的学习率为 0.00015。拟合函数如下:
filepath = save_path + "Char_Tok_Models/Models/weights.{epoch:02d}.hdf5"
checkpoint = ModelCheckpoint(
filepath,
monitor="val_loss",
verbose=1,
save_best_only=False,
mode="max",
period=5
)
callbacks_list = [checkpoint]
history = model.fit(
[x_span_train, corr_sent_train],
corr_label_train,
validation_data=([x_span_val, corr_sent_val], [corr_label_val]),
epochs=25,
callbacks=callbacks_list,
batch_size=64,
) #
加载权重和评估模型的代码如下:
model = make_model(0.0002)
model.load_weights(save_path + "Char_Tok_Models/Models_Upd/weights.40.hdf5")
model.evaluate([x_span_test, corr_sent_test], corr_label_test)
我将非常感谢您的帮助。谢谢。
我改变了学习率并尝试在最后一层使用“sigmoid”激活。我的期望是推理应该有至少 80% 的准确度。
重新启动内核后重新加载模型时,可能会改变模式的准确性,以下是一些常见原因:
随机初始化:神经网络通常在训练开始时随机初始化其权重。每次重新启动内核并创建新模型时,这种随机性可能会导致不同的初始权重。因此,网络在训练期间可能会收敛到不同的权重集,从而导致不同的性能。
权重初始化:如果您使用某些权重初始化技术,例如 Xavier/Glorot 初始化或 He 初始化,它们也会引入随机性。如果重启内核后初始权重不同,会影响收敛。
要解决这些问题,您可以使用:
为随机数生成器添加种子:在脚本开头设置随机种子以确保可重复性。这可以帮助确保权重初始化和数据改组在运行中保持一致。
保存和加载模型权重:不保存和加载整个模型架构,只保存模型权重。这样,您可以初始化具有相同架构的模型并加载经过训练的权重以实现一致的性能。
执行此操作后,如果重新启动内核并加载权重时模型性能再次显着下降(从大约 75% 到 35%),则表明权重初始化或模型的方式可能存在问题正在加载和评估。您可以采取以下一些步骤来解决此问题:
检查重量装载:确保重量装载正确。您可以打印模型摘要或检查加载的权重的形状以验证它们是否与模型架构匹配。确保用于创建模型的 make_model 函数与训练期间使用的函数相同。
检查数据预处理:验证输入数据(x_span_test、corr_sent_test 和 corr_label_test)是否按照与训练期间相同的方式进行预处理。数据预处理中的任何差异都可能导致不同的结果。
检查超参数:确认超参数(例如学习率(在您的情况下为 0.0002))设置为与训练期间相同的值。超参数的微小变化都会影响模型的性能。