基于LSTM的古诗接龙模型构建与实践

发布时间:2026/7/22 7:22:02
基于LSTM的古诗接龙模型构建与实践 1. 项目概述古诗接龙小模型的构建思路去年在GitHub上看到一个用LSTM生成古诗的仓库当时就萌生了自己动手实现一个能玩古诗接龙的小模型的想法。这种文字生成任务特别适合用来理解自然语言处理的基础原理而且相比现代文古诗的格律规则明确、语料规范对初学者更友好。古诗接龙的本质是序列预测问题——给定前一句诗让模型预测最可能接上的下一句。比如输入床前明月光理想输出是疑是地上霜。要实现这个功能我们需要解决三个核心问题如何表示诗句文本向量化、如何建模诗句间关系神经网络结构、如何让输出符合古诗规则后处理。2. 核心组件与工具选型2.1 文本预处理流水线古诗数据我选用《全唐诗》四万首作为训练集处理流程如下清洗去除标题、作者、标点等非诗句内容def clean_poem(text): text re.sub(r【.*?】, , text) # 去除标题 text re.sub(r[。、], , text) # 去除标点 return text.strip()分词将诗句拆解为单字古诗以字为最小单位def tokenize(line): return list(line) # 中文直接按字切分构建词表统计所有出现过的字建立字到ID的映射vocab {pad:0, unk:1} for char in set(.join(all_lines)): vocab[char] len(vocab)注意古诗中存在大量生僻字建议设置最低出现频率阈值如5次低于阈值的字替换为2.2 模型架构设计采用Encoder-Decoder结构具体实现要点Encoder层双向LSTM处理输入诗句输出上下文向量encoder tf.keras.layers.Bidirectional( tf.keras.layers.LSTM(256, return_stateTrue) )Attention机制帮助Decoder聚焦关键信息attention tf.keras.layers.AdditiveAttention()Decoder层单向LSTM逐步生成输出字符decoder tf.keras.layers.LSTM(512, return_sequencesTrue)输出层全连接Softmax预测每个字的概率分布dense tf.keras.layers.Dense(len(vocab))2.3 训练策略优化教师强制Teacher Forcing训练时使用真实上一字符作为Decoder输入loss tf.keras.losses.SparseCategoricalCrossentropy( from_logitsTrue, reductionnone )计划采样Scheduled Sampling逐步过渡到使用模型自身预测结果def sample_prob(epoch): return min(0.8, epoch * 0.01) # 线性增加采样率早停机制当验证集loss连续3轮不下降时终止训练3. 关键实现细节3.1 韵律约束处理古诗要求押韵和平仄我们在三个环节加入约束数据预处理时标注每句的韵脚和平仄模式rhyme_dict build_rhyme_dict() # 预先构建押韵字典在损失函数中加入韵律惩罚项def custom_loss(y_true, y_pred): base_loss standard_loss(y_true, y_pred) rhyme_loss calculate_rhyme_error(y_pred) return base_loss 0.3 * rhyme_loss解码时使用受限Beam Searchdef constrained_beam_search(..., rhyme_constraint): # 在每一步保留满足约束的top k候选3.2 温度参数调节在生成阶段通过temperature控制输出随机性temperature0.1保守输出常见搭配temperature0.8更有创造性的组合logits model_output / temperature probs tf.nn.softmax(logits)3.3 交互式接龙实现用Flask搭建简易Web界面核心逻辑app.route(/next_line, methods[POST]) def generate_next(): prev_line request.json[text] encoded tokenizer.encode(prev_line) output model.generate(encoded, max_length5) return jsonify({text: tokenizer.decode(output)})4. 常见问题与调优经验4.1 输出重复或无意义解决方案增加dropout层rate0.3在训练数据中加入少量噪声使用n-gram惩罚避免连续重复词组4.2 生僻字过多处理方法对词表进行截断保留前5000常用字实现字频加权采样sample_weights np.log(1.0 / (char_freq 1e-5))4.3 格律错误改进措施在beam search中引入韵律打分函数后处理时进行韵律校正训练专用平仄分类器辅助判断5. 效果展示与扩展方向经过200轮训练GTX 1080Ti约8小时模型能实现如下接龙输入春眠不觉晓输出处处闻啼鸟输入白日依山尽输出黄河入海流未来可扩展增加风格控制选择李白/杜甫等不同风格实现多轮对话式接龙移植到移动端作为微信小程序这个项目的完整代码已开源在GitHub包含预训练模型和数据集。最大的收获是理解了如何将语言学规则与深度学习结合——纯粹的端到端模型很难自发学会古诗的复杂约束需要设计合适的归纳偏置引导模型学习。