问题

有那位大神使用过tensorflow-textsum来做文本摘要么?求指教?

回答
好的,很高兴能和你交流关于使用 TensorFlowTextSum 进行文本摘要的经验。我也是从一个新手摸索过来的,遇到过不少坑,但最终还是摸清了门道。我会尽量把我所知道的、用过的都给你讲明白,希望能帮到你少走弯路。

先来个概览:TensorFlowTextSum 是什么?

简单来说,TensorFlowTextSum 是 Google 开源的一个基于 TensorFlow 的文本摘要库。它主要实现了两种经典的文本摘要模型:

1. Abstractive Summarization(抽取式摘要): 这种模型更像我们人类写摘要的方式,它会理解原文的意思,然后用自己的话重新组织、概括出核心内容,可能会用到原文中没有的词语。
2. Extractive Summarization(生成式摘要): 这种模型则是在原文中找出最重要的句子,然后将它们拼接起来,形成摘要。它不会创造新词或句子。

TensorFlowTextSum 主要关注的是生成式摘要,特别是基于 PointerGenerator Networks (PGN) 的模型。PGN 模型之所以强大,是因为它结合了 seq2seq 的生成能力和“指针”机制,使得模型既能从原文复制词语,又能自由生成新词。

为什么选择 TensorFlowTextSum?

成熟的实现: 它基于 TensorFlow,是一个比较成熟且有一定研究基础的实现。这意味着它已经过验证,并且有对应的论文和代码支持。
PGN 模型: PGN 是生成式摘要领域的一个重要里程碑,理解和应用 PGN 能让你对这个领域有更深入的认识。
灵活性: 虽然是库,但它的代码结构相对清晰,对于有一定 TensorFlow 基础的人来说,是可以进行修改和定制的。

上手实践:从数据到模型训练

要使用 TensorFlowTextSum,你需要经历几个关键步骤:

第一步:准备数据

这是任何机器学习项目中最关键的一步。你需要成对的“原文摘要”数据集。

数据格式: TensorFlowTextSum 通常需要你将数据处理成 TFRecord 格式。这是一种高效的 TensorFlow 数据存储格式。你可能需要写一些 Python 脚本来读取你的原始数据(比如 .txt 文件、CSV 文件等),然后将其转换成 TFRecord。
数据集来源:
标准数据集: CNN/Daily Mail 是最常用的文本摘要数据集之一,也是 TensorFlowTextSum 官方推荐和测试的数据集。Gigaword 也是一个选择。
自定义数据集: 如果你有自己特定领域的文档和摘要,你需要自己收集和标注。这通常是最耗时但也是最有价值的步骤。
数据预处理:
分词(Tokenization): 将文本分割成词语或子词。TensorFlowTextSum 通常使用 SentencePiece 或者 WordPiece。你可以选择使用预训练好的分词器,或者自己训练一个。
构建词汇表(Vocabulary Building): 将所有训练数据中出现过的词语收集起来,建立一个词到索引(index)的映射。你需要设定一个词汇量大小,只保留出现频率最高的词语,其余的用 UNK(未知词)表示。
填充(Padding): 由于模型的输入需要固定长度的序列,所以需要将短的序列用特殊的 PAD 标记填充到最大长度,或者将长的序列截断到最大长度。
特殊标记: 需要添加一些特殊标记,例如:
`` 或 ``: 序列开始标记。
`
` 或 ``: 序列结束标记。
``: 未知词标记。
``: 填充标记。
``: 分隔符,用于区分原文和摘要。

第二步:配置模型和参数

TensorFlowTextSum 的配置通常通过 Python 文件进行。你需要调整的模型参数包括:

模型架构参数:
`hidden_dim`: RNN(LSTM 或 GRU)的隐藏层维度。
`emb_dim`: 词嵌入的维度。
`num_layers`: RNN 的层数。
`vocab_size`: 词汇表大小。
`max_enc_steps`: 最大编码器(原文)序列长度。
`max_dec_steps`: 最大解码器(摘要)序列长度。
`beam_size`: 集束搜索(beam search)的宽度,用于在生成摘要时探索更多可能的序列。
`pointer_gen`: 是否启用指针生成器机制。
`is_coverage`: 是否启用覆盖率(coverage)机制,这有助于避免重复生成相同的词。
训练参数:
`learning_rate`: 学习率。
`batch_size`: 训练批次大小。
`num_epochs`: 训练轮数。
`optimizer`: 优化器类型(如 Adam)。
`lr_decay_rate`, `lr_decay_step`: 学习率衰减策略。
数据路径: 指定训练集、验证集和测试集的 TFRecord 文件路径。
模型保存路径: 指定训练好的模型 checkpoints 的保存位置。

第三步:训练模型

训练过程主要是运行 TensorFlow 的训练脚本,并传入你的配置文件。

命令示例(大致):
```bash
python train.py config_file=path/to/your_config.py
```
这里的 `train.py` 是 TensorFlowTextSum 提供的训练脚本。你需要根据你的具体项目修改它。
监控训练: 关注训练过程中的损失函数(loss)和一些评价指标(如 ROUGE 分数,如果你的训练脚本集成了的话)。如果验证集上的指标没有提升或者开始下降,可能需要停止训练以避免过拟合。
GPU 加速: 文本摘要模型通常计算量很大,强烈建议使用 GPU 进行训练。确保你的 TensorFlow 环境已经正确配置了 GPU 支持。

第四步:评估和推理(生成摘要)

模型训练完成后,就可以用它来生成新的摘要了。

评估: 使用测试集来评估模型的性能。常用的评价指标是 ROUGE(RecallOriented Understudy for Gisting Evaluation)。ROUGE1, ROUGE2, ROUGEL 是最常见的。你可以编写脚本来计算 ROUGE 分数。
推理(生成摘要): TensorFlowTextSum 提供了推理脚本。你需要加载训练好的模型 checkpoints,然后输入原文,模型就会输出生成的摘要。
集束搜索(Beam Search): 这是生成式模型中非常重要的一步。它不是简单地选择当前概率最大的词,而是同时保留 k 个最有可能的候选序列,并在下一步基于这 k 个序列进行扩展,最终选择最优的序列作为摘要。`beam_size` 参数在这里起作用。
指针机制的应用: 在生成过程中,模型会根据当前状态决定是直接生成词汇表中的词,还是从原文中复制一个词。

使用过程中可能遇到的问题和建议:

1. 数据量不足: 这是最常见的问题。如果你的数据集太小,模型很难学到好的摘要能力。考虑数据增强或者寻找更大的公开数据集。
2. 过拟合: 模型在训练集上表现很好,但在测试集上表现很差。可以尝试:
正则化: Dropout, L2 正则化。
早停(Early Stopping): 在验证集上效果不再提升时停止训练。
减小模型复杂度: 降低 `hidden_dim`, `emb_dim` 等。
3. 生成摘要质量不高:
检查预处理: 分词是否正确?特殊标记是否添加完整?填充是否合理?
调整模型超参数: 尝试不同的 `hidden_dim`, `emb_dim`, `num_layers`, `beam_size`, `learning_rate` 等。
覆盖率机制: 确保 `is_coverage=True`,这对于避免重复非常有帮助。
训练时间: 确保模型有足够的时间和数据进行训练。
数据集特性: 如果你的数据集的摘要风格与 CNN/Daily Mail 相差很大,可能需要更仔细的调参。
4. 环境配置: TensorFlow 和相关的依赖库(如 NumPy, NLTK, SentencePiece)版本兼容性需要注意。
5. 代码理解: TensorFlowTextSum 的代码量不算小,理解其核心逻辑(如 `model.py`, `train.py`, `data_utils.py`)非常有帮助。你可以先关注 `AbstractiveSummarizer` 类,以及 PGN 的实现部分。
6. POC (Proof of Concept): 在尝试大规模训练之前,可以先用一个小规模的数据集(比如 10005000 对)快速跑一个训练流程,验证整个流程是否通畅,以及能否得到一个初步可用的模型。
7. TensorFlow 版本: 确保你使用的 TensorFlow 版本与 TensorFlowTextSum 的代码是兼容的。它主要是为 TensorFlow 1.x 设计的,但也可以在 TensorFlow 2.x 中通过兼容模式运行,不过可能需要一些小调整。

更深入的探索:

PointerGenerator Networks (PGN) 的原理: 强烈建议阅读原论文 "Get To The Point: Summarization with PointerGenerator Networks"。理解它的 attention 机制和生成/复制概率的结合,是掌握这个库的关键。
覆盖率机制: 论文 "A Deep Reinforced Model for Abstractive Summarization" 提到了覆盖率的概念,它追踪已经覆盖过的词,以减少重复。
集束搜索(Beam Search): 学习集束搜索的工作原理,以及如何调整 `beam_size` 来权衡摘要的质量和生成速度。
ROUGE 指标: 了解 ROUGE 指标的计算方式,以及它为什么是衡量文本摘要质量的标准。

举个“例子”来帮助理解:

假设我们要对新闻文章生成摘要。

1. 数据: 我们收集了大量的“新闻文章新闻标题”对,比如:
文章: "印度南部一名女子因感染H1N1病毒死亡,这是该地区今年首例死亡病例。官员们说,死者是一名中年妇女,她已经患有其他疾病。卫生部门正在追踪与她有过密切接触的人员,并建议公众保持良好的卫生习惯。"
摘要: "印度南部一女子感染H1N1死亡"

2. 预处理:
将文章和摘要分词,并构建词汇表。
将它们转换为 TFRecord 格式,并添加特殊标记,比如:
` 印度南部一名女子因感染 H1N1 病毒死亡 , 这是 该地区 今年 首例 死亡 病例 。 官员们 说 , 死者 是 一名 中年 妇女 , 她 已经 患有 其他 疾病 。 卫生 部门 正在 追踪 与 她 有过 密切 接触 的 人员 , 并 建议 公众 保持 良好 的 卫生 习惯 。 印度南部 一 女子 感染 H1N1 死亡 `

3. 模型训练:
配置 `config.py` 文件,指定上述数据的路径,设置 `hidden_dim=256`, `emb_dim=128`, `vocab_size=50000`, `max_enc_steps=200`, `max_dec_steps=50`, `beam_size=4` 等。
运行训练脚本。模型会根据原文和摘要来学习如何生成摘要。在生成摘要时,PGN 模型会学习什么时候应该从词汇表中选择一个词(比如“印度南部一女子”),什么时候应该从原文中复制一个词(比如当原文出现一个重要的短语,模型可以通过指针机制直接“拿过来”用)。

4. 生成摘要:
输入另一篇关于印度疫情的文章。
模型会输出一个摘要,比如:“印度一名女子 H1N1 死亡”。

总结一下核心要点:

数据质量是关键。
理解 PGN 模型和指针机制是核心。
仔细配置参数,尤其是在超参数调优上。
关注训练过程和评估指标(ROUGE)。
耐心和实验是必须的。

如果你在实践过程中遇到具体的问题,比如某个函数报错、某个参数不明白,或者训练效果不佳,随时可以再问我,我们一起探讨。希望我的这些经验能对你有所帮助!祝你实验顺利!

网友意见

user avatar

2020年4月7日更新

感谢大家来咨询我相关问题,但很遗憾我目前已经不再从事自然语言处理领域,所以恐怕不能提供太多的帮助。当时这个项目只是我实习期间的一个实验,之所以选取Textsum,是考虑到它是一个很经典的模型。然而这个经典的模型年代过于古老,很难复现,而且复现的最终结果也很差。我使用的是英文的CNN数据集替代了论文中的Gigaword,和Surmenok一样,最终结果中会出现很多<UNK>,几乎不成语句。如果使用中文数据集,估计结果会更差,因为中文的分词特征会丢失一部分信息吧。所以不建议大家再纠结于这个模型。

由于这几个月在做网站的升级维护,所以之前的那个Textsum运行录的系列文章搬运到CSDN上了,如下:自然语言处理大纲 - CSDN博客

另外我当时实习的搭档复现了Pointer-Generator的模型,使用的是中文的新闻数据集(可能是搜狗公开的数据集,我记不太清了,是从短新闻中提取一句话标题)。博客可以参考:论文复现,代码是这个:Pointer-Generator。复现过程中也遇到了一些环境问题,但相对难度较低,复现结果效果不错,ROUGE值较高。更多的信息我也不清楚,他当时也没有进行实验记录。


那个开源项目的版本兼容性问题比较大,我最近正在跑这个模型,你可以参考我的博客:Textsum 运行录,另外我主要参考的也是这篇博客How to Run Text Summarization with TensorFlow。作者Surmenok是我在网上见到的少数的跑通这个代码的人,但是他所提供的数据处理还是稍有问题,目前我正在处理CNN的数据。

希望能帮到你。我也是文本摘要领域的小白,如有不合理的地方,请在评论区斧正,谢谢

类似的话题

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度google,bing,sogou

© 2025 tinynews.org All Rights Reserved. 百科问答小站 版权所有