在 TensorFlow 1.x 上用 LSTM 训练 PTB 语言模型:循环神经网络实战教程
文档开发工具教程【免费下载链接】docsTensorFlow documentation项目地址https://gitcode.com/gh_mirrors/doc/docs点击查看免费下载本篇技术指南以 TensorFlow 1.x 官方文档为骨架完整讲解如何基于 Penn Tree BankPTB语料训练一个循环神经网络RNN语言模型覆盖数据准备、LSTM 单元搭建、截断反向传播、嵌入层、损失函数与困惑度评估、多层 LSTM 堆叠以及最终的训练运行与调优适用于希望掌握序列建模与 TensorFlow 1.x RNN 编程实战的开发者。语言建模任务定义与价值语言建模Language Modeling的核心目标是拟合一个概率模型使其能够为句子分配概率。具体做法是给定一段历史词序列模型预测下一个词出现的概率分布。这一能力是语音识别、机器翻译、图像描述image captioning等众多任务的公共基础。本教程采用的基准数据集是Penn Tree BankPTB。它虽然体量较小、训练速度快却是评估语言模型质量的经典基准非常适合作为入门与复现实验的载体。教程的目标是复现 Zaremba 等人 2014 年论文Recurrent Neural Network Regularization中在 PTB 数据集上取得的高质量结果。教程文件一览本教程对应的完整可运行代码位于 TensorFlow models 仓库的models/tutorials/rnn/ptb目录包含两个核心文件文件用途ptb_word_lm.py在 PTB 数据集上训练语言模型的全部代码reader.py读取与预处理数据集的辅助代码其中ptb_word_lm.py负责构建计算图词嵌入、LSTM 单元、损失与优化器、驱动训练循环并按周期输出困惑度reader.py负责将原始文本文件切分成词序列、转换为整数 ID并以 batch 形式提供给训练过程。下载与准备 PTB 数据教程使用的数据位于 PTB 数据集simple-examples.tgz的data/目录中。该数据集已经完成预处理整体词表规模为10000 个不同的词其中包含句末标记end-of-sentence marker以及一个用于表示罕见词的专用符号unk。在reader.py中每个词都会被转换为一个唯一的整数标识符integer id。这种词 → 整数 ID的映射是后续嵌入层embedding layer工作的前提神经网络无法直接消费字符串必须先完成符号数字化。模型设计LSTM 逐词处理与批数据布局模型的核心是一个LSTM 单元tf.contrib.rnn.BasicLSTMCell它逐词处理输入序列并为句中的每个位置计算下一个词的候选概率分布。网络的记忆状态memory state初始化为全零向量并在每读取一个词之后被更新。出于计算效率考虑数据按大小为batch_size的小批量mini-batch处理。这里有一个极易混淆的关键点batch 中的词并不对应一个句子。准确地说batch 中每一列词应该对应同一个时间步t。TensorFlow 会自动为你完成每个 batch 的梯度求和。以一个直观的例子说明数据布局batch_size 2, time_steps 5t0 t1 t2 t3 t4 [The, brown, fox, is, quick] [The, red, fox, jumped, high] words_in_dataset[0] [The, The] words_in_dataset[1] [brown, red] words_in_dataset[2] [fox, fox] words_in_dataset[3] [is, jumped] words_in_dataset[4] [quick, high]也就是说words_in_dataset[t]是一个长度为batch_size的向量其所有元素都来自时间步t。这种按时间步切分、跨样本对齐的布局是 RNN 批处理的标准范式。基础实现伪代码words_in_dataset tf.placeholder(tf.float32, [time_steps, batch_size, num_features]) lstm tf.contrib.rnn.BasicLSTMCell(lstm_size) # Initial state of the LSTM memory. state lstm.zero_state(batch_size, dtypetf.float32) probabilities [] loss 0.0 for current_batch_of_words in words_in_dataset: # The value of state is updated after processing each batch of words. output, state lstm(current_batch_of_words, state) # The LSTM output can be used to make next word predictions logits tf.matmul(output, softmax_w) softmax_b probabilities.append(tf.nn.softmax(logits)) loss loss_function(probabilities, target_words)代码要点words_in_dataset的形状为[time_steps, batch_size, num_features]第一个维度正是时间步与上述数据布局呼应每次调用lstm(current_batch_of_words, state)返回(output, state)其中更新后的state会作为下一次调用的输入形成时间维度上的状态传递LSTM 的output经线性变换softmax_w、softmax_b得到 logits再经tf.nn.softmax转为概率训练中真正使用的方式是逐时间步循环而不是一次性把整个序列塞入tf.placeholder后者在截断反向传播中另有讲究见下一节。截断反向传播Truncated Backpropagation从设计上看RNN 的输出依赖于任意久远的输入这使得标准反向传播的计算变得困难。为了让学习过程可行业界普遍采用一种常见做法构建一个**展开unrolled的有限版本网络**其中包含固定数量num_steps的 LSTM 输入与输出并在这段有限近似上训练。实现方式是每次喂入长度为num_steps的输入块并在处理完该块后执行一次反向传播。下面是为截断反向传播创建计算图的简化代码# Placeholder for the inputs in a given iteration. words tf.placeholder(tf.int32, [batch_size, num_steps]) lstm tf.contrib.rnn.BasicLSTMCell(lstm_size) # Initial state of the LSTM memory. initial_state state lstm.zero_state(batch_size, dtypetf.float32) for i in range(num_steps): # The value of state is updated after processing each batch of words. output, state lstm(words[:, i], state) # The rest of the code. # ... final_state state注意此处的words形状为[batch_size, num_steps]与上一节演示的[time_steps, batch_size, num_features]不同——它按words[:, i]取第i个时间步的所有 batch 样本。final_state是处理完num_steps个词之后的状态。在整个数据集上的迭代实现如下# A numpy array holding the state of LSTM after each batch of words. numpy_state initial_state.eval() total_loss 0.0 for current_batch_of_words in words_in_dataset: numpy_state, current_loss session.run([final_state, loss], # Initialize the LSTM state from the previous iteration. feed_dict{initial_state: numpy_state, words: current_batch_of_words}) total_loss current_loss关键设计由于截断反向传播只回溯num_steps步跨块的历史信息无法通过计算图自动传播。因此这里用initial_state.eval()把上一块的final_state保存为 numpy 数组并在下一块通过feed_dict重新注入。这样状态信息在块与块之间依然能够持续流动而梯度传播被限制在单块内部兼顾了长程记忆与训练可行性。输入词向量嵌入Embedding在送入 LSTM 之前词 ID 会被嵌入到一个稠密表示dense representation中原理可参考 词向量表示word2vec教程。嵌入允许模型高效地表达特定词的知识并且实现非常简洁# embedding_matrix is a tensor of shape [vocabulary_size, embedding size] word_embeddings tf.nn.embedding_lookup(embedding_matrix, word_ids)embedding_matrix会被随机初始化模型仅通过观察数据本身就能学会区分不同词的语义。这与仓库中 嵌入指南 的表述一致嵌入是将词等离散对象映射到实数向量训练结束后embedding_matrix中即存放词表中每个词的稠密向量。损失函数与困惑度Perplexity训练目标是最小化目标词的平均负对数概率$$ \text{loss} -\frac{1}{N}\sum_{i1}^{N} \ln p_{\text{target}_i} $$该函数实现并不困难但 TensorFlow 已提供现成的sequence_loss_by_example函数直接调用即可。论文中通常报告的指标是每个词的平均困惑度perplexity常简称 perplexity它与 loss 的关系为$$e^{-\frac{1}{N}\sum_{i1}^{N} \ln p_{\text{target}_i}} e^{\text{loss}}$$困惑度可以直观理解为模型在每个词位置上的平均候选词数不确定性困惑度越低模型对下一个词的预测越确定质量越高。训练全程需要持续监控该值。堆叠多层 LSTM为了赋予模型更强的表达能力可以在数据上叠加多个 LSTM 层第一层的输出成为第二层的输入依此类推。TensorFlow 提供的MultiRNNCell让这一过程无缝衔接def lstm_cell(): return tf.contrib.rnn.BasicLSTMCell(lstm_size) stacked_lstm tf.contrib.rnn.MultiRNNCell( [lstm_cell() for _ in range(number_of_layers)]) initial_state state stacked_lstm.zero_state(batch_size, tf.float32) for i in range(num_steps): # The value of state is updated after processing each batch of words. output, state stacked_lstm(words[:, i], state) # The rest of the code. # ... final_state state注意MultiRNNCell.zero_state返回的是多层状态的元组由stacked_lstm内部统一管理各层的隐藏状态与记忆状态调用方无需手动拆分。运行完整训练代码运行前先下载并解压 PTB 数据集到主目录下tar xvfz simple-examples.tgz -C $HOMEWindows 环境下可能需要借助其他解压工具。然后克隆 TensorFlow models 仓库进入 PTB 示例目录并启动训练cd models/tutorials/rnn/ptb python ptb_word_lm.py --data_path$HOME/simple-examples/data/ --modelsmall模型配置small / medium / large教程代码内置 3 种受支持的模型配置small、medium与large。它们的差异在于 LSTM 的尺寸以及训练所用的超参数集合。配置说明small尺寸最小、训练最快测试集上困惑度应能降到120 以下medium尺寸与超参数介于两者之间large尺寸最大测试集上困惑度应能降到80 以下但可能需要数小时训练总体上模型越大、效果越好small模型在测试集上的困惑度低于 120large模型低于 80后者需要数小时训练时间。这一预期与 Zaremba 等人论文的报告一致可作为复现实验的验收基准。进一步优化方向本教程尚未提及两个能显著改善模型的技巧递减学习率调度decreasing learning rate schedule在训练后期逐步降低学习率有助于模型收敛到更优解LSTM 层间 Dropout在多层 LSTM 之间引入 dropout 正则化可有效缓解过拟合。建议仔细研读ptb_word_lm.py的代码并动手修改以进一步改进模型效果。值得一提的是从本仓库的 TensorFlow 1.x 性能指南RNN Performance 一节 可以看出tf.contrib.rnn.BasicLSTMCell被视为参考实现在 NVIDIA GPU 上优先考虑tf.contrib.cudnn_rnn通常比BasicLSTMCell快一个数量级以上、内存占用少 3~4 倍在 CPU、移动设备上则可用tf.contrib.rnn.LSTMBlockFusedCell获得最佳速度与内存效率。理解这些取舍有助于在完成本教程后针对更大规模的序列任务做进一步工程优化。赞分享文档开发工具教程【免费下载链接】docsTensorFlow documentation项目地址https://gitcode.com/gh_mirrors/doc/docs点击查看免费下载相关推荐CANN驱动Ascend950网络工具Commands List Query Commands Querying hccn\_tool Help Information https://link.g驱动开发人工智能CANNAudacity 免费开源音频编辑器录音、降噪与导出完整实用手册Audacity 免费开源音频编辑器录音、降噪与导出完整实用手册 Audacity 是一款免费的开源音频软件与跨平台音频编辑器支持录音、音频降噪、多轨混音与音频处理桌面应用音视频gradient-checkpointing实战教程在TensorFlow中训练超大规模神经网络gradient checkpointing实战教程在TensorFlow中训练超大规模神经网络 想要训练超大规模神经网络却总是遇到内存不足的问题gradi上一篇突破最优传输效率瓶颈POT库中5类求解器的深度对比与实战指南下一篇sqlpp11项目深度解析高效使用预处理语句提升数据库操作性能创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

pnpm 的 pkg-manifest/utils 工具包:深入解析 package.json 依赖字段读写与版本范围处理

pnpm 的 pkg-manifest/utils 工具包:深入解析 package.json 依赖字段读写与版本范围处理

包管理器开发工具CLI 【免费下载链接】pnpm Fast, disk space efficient package manager 项目地址: https://gitcode.com/gh_mirrors/pn/pnpm 点击查看 免费下载 导读 在 pnpm 的 TypeScript 源码仓库中,pnpm11/pkg-manifest/utils(包名 p…

2026/10/10 1:26:38 阅读更多 →
sslh内存管理机制:哈希表和间隙数组的优化实现

sslh内存管理机制:哈希表和间隙数组的优化实现

sslh内存管理机制:哈希表和间隙数组的优化实现 sslh作为一款高效的协议多路复用器,能够在同一端口上共享SSH和HTTPS等协议。其出色的性能表现很大程度上得益于精心设计的内存管理机制,特别是哈希表和间隙数组的优化实现。本文将深入解析sslh…

2026/10/10 1:26:38 阅读更多 →
鸿蒙高级——内存专用之linux-reserve-memory 方案简介

鸿蒙高级——内存专用之linux-reserve-memory 方案简介

引言 最近因为工作需求涉及到一些AI端侧推理加速的需求,于是新学习了一个新的知识点。 一、linux-reserve-memory 方案 linux-reserve-memory 是 Linux 内核中用于预留内存机制。预留内存(Reserved Memory) 是一种机制,用于预留特…

2026/10/10 1:26:38 阅读更多 →

最新新闻

Spring AI 实战:从配置到对话,ChatClient 链式调用与上下文管理

Spring AI 实战:从配置到对话,ChatClient 链式调用与上下文管理

1. 从配置文件到对话窗口:Spring AI 到底简化了什么第一次接触 Spring AI 的时候,我脑子里其实带着一个很具体的疑问:过去在 Java 项目里接一个大模型对话能力,光是 HTTP 客户端封装、请求体拼装、响应解析、异常重试这些杂活&…

2026/10/10 5:17:30 阅读更多 →
如何安全管理 OpenFlux 共享密钥:传输、存储与轮换实战指南

如何安全管理 OpenFlux 共享密钥:传输、存储与轮换实战指南

如何安全管理 OpenFlux 共享密钥:传输、存储与轮换实战指南 OpenFlux 是一款网络栈研究工具,通过可插拔的传输层构建 TCP 隧道。当启用传输加密时,客户端与出口节点共用的**共享密钥(shared secret)**就是整条隧道的安…

2026/10/10 5:17:30 阅读更多 →
Ant Design Blazor Affix 滚动容器实战:用 TargetSelector 将固钉绑定到指定滚动元素

Ant Design Blazor Affix 滚动容器实战:用 TargetSelector 将固钉绑定到指定滚动元素

前端UI组件设计系统 【免费下载链接】ant-design-blazor 基于 Ant Design 与 Blazor 的前端组件库。让开发者解放生产力,实现更大价值。 项目地址: https://gitcode.com/ant-design-blazor/ant-design-blazor 点击查看 免费下载 本篇指南围绕 Ant Desig…

2026/10/10 5:17:30 阅读更多 →
x64dbg 调试器插件开发指南:深入解析 DbgScriptBpToggle 脚本断点切换 API 及其完整调用链

x64dbg 调试器插件开发指南:深入解析 DbgScriptBpToggle 脚本断点切换 API 及其完整调用链

逆向工程调试器开发工具应用安全 【免费下载链接】x64dbg An open-source user mode debugger for Windows. Optimized for reverse engineering and malware analysis. 项目地址: https://gitcode.com/gh_mirrors/x6/x64dbg 点击查看 免费下载 导读 DbgScriptBpT…

2026/10/10 5:17:30 阅读更多 →
LogicStack-LeetCode 题解:813. 最大平均值和的分组——「序列 DP + 前缀和」求连续段平均值之和最大值

LogicStack-LeetCode 题解:813. 最大平均值和的分组——「序列 DP + 前缀和」求连续段平均值之和最大值

教程文档 【免费下载链接】LogicStack-LeetCode 公众号「宫水三叶的刷题日记」刷穿 LeetCode 系列文章源码 项目地址: https://gitcode.com/gh_mirrors/lo/LogicStack-LeetCode 点击查看 免费下载 导读 本篇以「宫水三叶的刷题日记」系列仓库(LogicSta…

2026/10/10 5:17:30 阅读更多 →
GPS天线设计 GNSS天线设计建议

GPS天线设计 GNSS天线设计建议

GPS天线设计 GNSS天线设计建议 天线作为导航定位设备中最重要的接收器件,它起到的作用就像是人的“耳朵”;是将卫星发送下来的电磁波能量变换成电子器件可解析的电流。因此天线的性能好坏将直接关系到GPS整机的产品性能。目前GNSS系统开放民用定位系统主要是美国GPS…

2026/10/10 5:16:30 阅读更多 →

日新闻

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

1. 从“卫星轨道分类”这个标题说起:为什么值得花时间搞懂第一次接触“卫星轨道分类”这个概念,很多人会觉得它离自己很远——不就是天上的星星怎么转吗?但如果你正在做航天任务规划、遥感数据接收、星座设计,甚至只是准备一场航天…

2026/10/10 0:00:39 阅读更多 →
Spring AOP 核心原理与实战:从概念到日志切面落地

Spring AOP 核心原理与实战:从概念到日志切面落地

1. 从一个真实痛点说起:为什么你的代码里到处都是重复逻辑刚入行那会儿,我写过一个用户管理模块,注册、登录、改密码、注销四个接口。每个接口里都塞了几乎一样的日志打印、参数校验、事务开启和提交。当时觉得没什么,能跑就行。直…

2026/10/10 0:00:40 阅读更多 →
Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

简介:这是一套面向计算机相关专业学生与项目实战学习者的Python数据采集与分析可视化完整项目,以Boss直聘岗位数据为对象,适合用作毕业设计、课程设计或期末大作业。资源包共38个文件,约246KB,以13个py源码文件为核心&…

2026/10/10 0:00:40 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 1:36:08 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 10:11:06 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 21:13:17 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 6:17:20 阅读更多 →