LSTM Seq2Seq地址解析模型准确率卡在80%,如何提升至95%?
问题描述
我正在训练LSTM Seq2Seq模型解决地址解析问题,任务是将原始地址字符串(例如"184 Park Ave, NYC, NY")拆解为独立组件:{number: 184, street: Park Ave, city: NYC, region: NY}。
我采用LSTM模型接收原始地址字符串的字符嵌入序列(长度=80),输出独立地址组件序列(长度=153)。词表大小为41,每个字符、数字或特殊字符(含空格)均映射为0到41之间的数值。
以下是加载训练和测试数据集的代码:
test1 = list() train2 = list() test2 = list() X_train, X_test, y_train, y_test = np.load("X_train.npy"), np.load("X_test.npy"), np.load("y_train.npy"), np.load("y_test.npy"), with tensorflow.device('/device:GPU:0'): for seq1, seq2, seq3, seq4 in zip(X_train, y_train, X_test, y_test): train1.append(to_categorical(seq1, num_classes=40+1)) test1.append(to_categorical(seq3, num_classes=40+1)) train2.append(to_categorical(seq2, num_classes=40+1)) test2.append(to_categorical(seq4, num_classes=40+1)) train1, test1, train2, test2 = np.array(train1), np.array(test1), np.array(train2), np.array(test2) print(train1.shape, test1.shape, train2.shape, test2.shape)
输出结果为:(100000, 80, 41) (100000, 80, 41) (100000, 153, 41) (100000, 153, 41)
在这些序列上训练模型时,训练约1万条样本后训练准确率达到*~80%*,之后模型突然停止提升。模型代码如下:
model = Sequential() model.add(LSTM(100, input_shape=(n_in_seq_length, 41))) model.add(RepeatVector(n_out_seq_length)) model.add(LSTM(100)) model.add(RepeatVector(n_out_seq_length)) model.add(LSTM(100, return_sequences=True)) model.add(TimeDistributed(Dense(41, activation='softmax'))) model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) print(model.summary()) with tensorflow.device('/device:GPU:0'): model.fit(train1, train2, epochs=1, batch_size=n_batch)
已经尝试过GRU、普通RNN,以及多种模型架构和隐层数量调整,均未改善性能。目标是将模型训练到约*95%*的准确率,请问如何提升模型的训练准确率?
解决方案
- 首先修复核心架构错误:当前的Seq2Seq结构存在致命问题,第二个LSTM层没有开启
return_sequences=True,会把153步的输入序列直接压缩为单个100维向量,后续第二次RepeatVector只是把同一个静态向量重复153次,完全丢失了序列的时序对应关系,这是准确率卡在80%的核心原因。标准Seq2Seq的解码器部分所有LSTM层都要开启return_sequences=True,不能中途把序列压成单向量。 - 增加注意力机制:字符级地址解析属于强对齐任务,输入和输出的字符存在明确的对应关系,仅靠编码器压缩的单向量存在信息瓶颈,加入Bahdanau或者Luong注意力层,让解码器每一步都可以关注输入序列的对应位置,能大幅提升细粒度预测准确率。
- 调整编码器结构:把编码器换成双向LSTM,可以同时捕获地址字符串的前后文信息,比单向LSTM的特征提取能力强很多,隐层维度可以从100上调到256,增加模型容量。
- 优化训练配置:当前只设置了训练1个epoch,10万样本的训练量远远不够,至少跑20个epoch以上,同时给Adam优化器加学习率衰减,比如训练到10轮后学习率从1e-3降到1e-4,避免后期震荡不收敛。
- 可以换任务范式:地址解析本质上是序列标注任务,不需要用Seq2Seq生成输出序列,直接给输入的每个字符打BIO标签(比如B-number、I-number、B-street等),模型直接输出每个字符对应的标签,不需要生成153位的长序列,收敛速度和准确率都会高很多,95%的目标很容易达到。
- 其他优化点:可以给LSTM层加0.2左右的Dropout防止过拟合,加入标签平滑减少模型过置信度的问题,训练时加入验证集早停,避免过拟合训练集。
内容的提问来源于stack exchange,提问作者Martin Mashalov
相关产品推荐
相关产品推荐

