我目前正在尝试使用yaml脚本训练一个西班牙语到英语的模型。我的数据集相当大,但作为起步,我首先尝试使用10,000个训练集和1000-2000个验证集来达到良好的效果。然而,经过几天的尝试后,我觉得我需要帮助,因为我的验证准确率在训练过程中不断下降,而我的训练准确率却在上升。
我的数据来自ModelFront的ES-EN冠状病毒评论数据集,链接在此 https://console.modelfront.com/#/evaluations/5e86e34597c1790017d4050a。我发现这些平行句子相当准确。我使用了数据集中前10,000个平行行,跳过了包含任何数字的句子。然后,我从中提取了接下来的1000或2000个用于我的验证集,再接下来的1000个用于测试集,仅包含没有数字的句子。查看数据后,数据看起来很干净,且句子在各自的行中对齐得很好。
接着,我使用sentencepiece构建了一个词汇模型。通过spm_train命令,我将英语和西班牙语的训练集输入,参数中以逗号分隔,并输出了一个单一的esen.model。此外,我选择使用单字和16000的词汇大小
关于我的yaml配置文件:我指定了以下内容
我的源和目标训练数据(我为英语和西班牙语提取的10,000个数据,transforms []中包含“sentencepiece”)
我的源和目标验证数据(2,000个英语和西班牙语数据,transforms []中包含“sentencepiece”)
我的词汇模型esen.model,用于我的源和目标词汇模型
编码器:rnn解码器:rnn类型:LSTMLayers:2bidir:true
优化:Adam学习率:0.001
训练步骤:5000验证步骤:1000
其他日志数据。
在使用onmt_translate开始训练后,我的训练准确率从7.65开始,到5000步结束时上升到70多。然而,在这段时间内,我的验证准确率从24下降到19。
然后,我使用bleu来评分我的测试集,得到了大约0.67的BP。
我注意到,在尝试使用学习率为1的sgd后,我的验证准确率持续上升,但最终困惑度开始回升。
我想知道我是否做错了什么,导致我的验证准确率下降而训练准确率上升?我是否只需要继续训练?是否有人可以推荐其他改进此模型的方法?我已经盯着它看了几天。任何建议都将不胜感激。谢谢。
!spm_train --input=data/spanish_train,data/english_train --model_prefix=data/esen --character_coverage=1 --vocab_size=16000 --model_type=unigram
## 样本将被写入的位置save_data: en-sp/run/example## 词汇表将被写入的位置src_vocab: en-sp/run/example.vocab.srctgt_vocab: en-sp/run/example.vocab.tgt## 模型将被保存的位置save_model: drive/MyDrive/ESEN/model3_bpe_adam_001_layer2/model# 防止覆盖文件夹中已存在的文件overwrite: False# Corpus opts:data: taus_corona: path_src: data/spanish_train path_tgt: data/english_train transforms: [sentencepiece, filtertoolong] weight: 1 valid: path_src: data/spanish_valid path_tgt: data/english_valid transforms: [sentencepiece]skip_empty_level: silentsrc_subword_model: data/esen.modeltgt_subword_model: data/esen.model# General optsreport_every: 100train_steps: 5000valid_steps: 1000save_checkpoint_steps: 1000world_size: 1gpu_ranks: [0]# Optimizeroptim: adamlearning_rate: 0.001# Modelencoder_type: rnndecoder_type: rnnlayers: 2rnn_type: LSTMbidir_edges: True# Loggingtensorboard: truetensorboard_log_dir: logslog_file: logs/log-file.txtverbose: Trueattn_debug: Truealign_debug: Trueglobal_attention: generalglobal_attention_function: softmax
onmt_build_vocab -config en-sp.yaml -n_sample -1
onmt_train -config en-sp.yaml
Step 1000/ 5000; acc: 27.94; ppl: 71.88; xent: 4.27; lr: 0.00100; 13103/12039 tok/s; 157 secValidation perplexity: 136.446Validation accuracy: 24.234...Step 4000/ 5000; acc: 61.25; ppl: 5.28; xent: 1.66; lr: 0.00100; 13584/12214 tok/s; 641 secValidation accuracy: 22.1157...
回答:
我的验证准确率在训练过程中不断下降,而我的训练准确率却在上升。
听起来像是过拟合。
10,000个句子实在是太少了。所以你看到的情况是预期内的。你可以在验证集结果停止改善时停止训练。
同样的基本动态在更大规模上也会发生,只是需要更长的时间。
如果你目标是训练一个相当不错的模型,我看到有几个选项:
- 增加数据集大小到100万左右
- 从预训练模型开始并进行微调
- 两者结合
对于第一点,即使过滤掉最嘈杂的数据,你也可以从ModelFront获取至少100万行的英语:西班牙语数据。
对于第二点,我知道YerevaNN团队在WMT20中取得了优胜成绩,他们从一个Fairseq模型开始,使用了大约30万个翻译。而且他们能够在相当有限的硬件上做到这一点。