注意:此代码不再积极维护。
该存储库包含在Tensorflow中为以下论文开发的代码:
如果使用此代码,请考虑引用以下论文:
@article{keneshloo2018deep,
title={Deep Reinforcement Learning For Sequence to Sequence Models},
author={Keneshloo, Yaser and Shi, Tian and Ramakrishnan, Naren and Reddy, Chandan K.},
journal={arXiv preprint arXiv:1805.09461},
year={2018}
}
近年来,从机器翻译,标题生成,文本摘要,语音到文本到图像字幕生成的各种任务中都使用了序列到序列(SEQ2SEQ)模型。所有这些模型的基础框架通常是一个深神网络,其中包含编码器和解码器。编码器处理输入数据,解码器接收编码器的输出并生成最终输出。尽管在大多数情况下,仅使用编码器/解码器模型就可以产生比上述任务的传统方法更好的结果,但研究人员提出了对这些序列对序列模型的额外改进,例如在输入,指针生成模型和自我意见模型上使用基于注意力的模型和自我意见模型。但是,所有这些SEQ2SEQ模型都有两个常见问题:1)暴露偏见和2)火车/测试测量之间的不一致。最近,通过使用增强学习方法(RL)在SEQ2SEQ模型中解决这两个问题的一种完全新的观点。在这些新研究中,我们试图从RL的角度看SEQ2SEQ问题,并尝试提出一种表述,该公式可以将RL方法在决策和序列中的力量结合到记忆长期记忆中的序列模型中。在本文中,我们将总结一些结合了从RL世界到深神经网络领域的概念的最新框架,并解释这两个领域如何在解决复杂的SEQ2SEQ任务中彼此受益。最后,我们将提供有关当前现有模型的某些问题以及如何通过更好的RL模型改进它们的一些见解。我们还提供了用于实施大多数模型的源代码,这些模型将在本文中讨论有关抽象文本摘要的复杂任务。
- 使用Python 2.7
Python要求可以安装如下:
pip install -r python_requirements.txt
- TensorFlow 1.10.1
- 库达9
- Cudnn 7.1
https://github.com/abisee/cnn-dailmail
https://summari.es/
我们提供了辅助代码来下载CNN-DailMail数据集并预处理此数据集和新闻编辑室数据集。请参阅此链接以访问它们。
我们通过在摘要结果中使用这些数据集的加工版本,在胭脂度量上看到了很大的改进,因此,我们强烈建议使用这些预处理的文件进行所有培训。
该代码是各种支持以下功能的多种不同模式的一般框架:
Bengio等。提出了预定抽样的想法,以避免暴露偏见问题。最近,Goyal等。通过使用Soft-Argmax相当硬的Argmax,提出了对该方法的可区分相关性,该相对于硬化误差解决了此模型中存在的后传播误差。另外,Ranzato等。提出了另一个称为End2EndbackProp的简单模型,用于避免曝光偏置问题。要根据每篇论文培训模型,我们提供不同的标志,如下所示:
范围 默认 描述 计划_s采样 错误的 是否进行计划抽样 Sampling_probability 0 选择地面真相或模型输出的Epsilon值 fixe_sampling_probability 错误的 是使用固定采样概率还是自适应 hard_argmax 真的 是使用软argmax还是硬grgmax greedy_scheduled_smpling 错误的 无论是使用贪婪还是样品进行输出,True表示贪婪 e2ebackprop 错误的 是否使用E2ebackprop算法来解决曝光偏差 阿尔法 1 软argmax参数
CUDA_VISIBLE_DEVICES=0 python src/run_summarization.py --mode=train --data_path= $HOME /data/cnn_dm/finished_files/chunked/train_ * --vocab_path= $HOME /data/cnn_dm/finished_files/vocab --log_root= $HOME /working_dir/cnn_dm/RLSeq2Seq/ --exp_name=scheduled-sampling-hardargmax-greedy --batch_size=80 --max_iter=40000 --scheduled_sampling=True --sampling_probability=2.5E-05 --hard_argmax=True --greedy_scheduled_sampling=TrueCUDA_VISIBLE_DEVICES=0 python src/run_summarization.py --mode=train --data_path= $HOME /data/cnn_dm/finished_files/chunked/train_ * --vocab_path= $HOME /data/cnn_dm/finished_files/vocab --log_root= $HOME /working_dir/cnn_dm/RLSeq2Seq/ --exp_name=scheduled-sampling-softargmax-sampling --batch_size=80 --max_iter=40000 --scheduled_sampling=True --sampling_probability=2.5E-05 --hard_argmax=False --greedy_scheduled_sampling=False --alpha=10CUDA_VISIBLE_DEVICES=0 python src/run_summarization.py --mode=train --data_path= $HOME /data/cnn_dm/finished_files/chunked/train_ * --vocab_path= $HOME /data/cnn_dm/finished_files/vocab --log_root= $HOME /working_dir/cnn_dm/RLSeq2Seq/ --exp_name=scheduled-sampling-end2endbackprop --batch_size=80 --max_iter=40000 --scheduled_sampling=True --sampling_probability=2.5E-05 --hard_argmax=True --E2EBackProp=True --k=4
范围 默认 描述 rl_training 错误的 开始政策成就培训 convert_to_reinforce_model 错误的 将指针模型转换为增强模型。打开此操作并在火车模式下运行。您当前的培训模型将被复制到新版本(带有_cov_init附加的同名),该版本将准备运行,并打开覆盖范围,以便在覆盖范围训练阶段。 内部模块 错误的 是否使用不关注核管模型 USE_TEMPORAL_ENTISTENTION 真的 是否使用暂时关注 matrix_ateention 错误的 使用矩阵注意,等式。 2在https://arxiv.org/pdf/1705.04304.pdf中 ETA 0 RL/MLE缩放系数,1表示使用RL损失,0表示使用MLE损失 fixed_eta 错误的 根据全球步骤使用固定值或自适应 伽玛 0.99 RL奖励折扣系数 奖励_功能 rouge_l/f_score BLEU或ROUGE度量之一(Rouge_1/f_score,rouge_2/f_score,rouge_l/f_score)
Paulus等。提出了一种自我批评的政策梯度模型,用于抽象文本摘要。下图表示该方法的工作原理以及我们如何实现此方法:

为了复制他们的实验,我们可以使用以下一组过程:
CUDA_VISIBLE_DEVICES=0 python src/run_summarization.py --mode=train --data_path= $HOME /data/cnn_dm/finished_files/chunked/train_ * --vocab_path= $HOME /data/cnn_dm/finished_files/vocab --log_root= $HOME /working_dir/cnn_dm/RLSeq2Seq/ --exp_name=intradecoder-temporalattention-withpretraining --batch_size=80 --max_iter=20000 --use_temporal_attention=True --intradecoder=True --rl_training=False在这里,我们使用不同的GPU进行评估,但是如果减少批次数量,我们可以使用相同的GPU。在实施中,我们使用批次大小为8进行评估,但是对于每个评估步骤,我们迭代验证数据集100次。这类似于在800批次大小上找到评估误差。这将有助于减少评估过程所需的内存,并为在一个GPU上同时进行培训和评估提供选项。
CUDA_VISIBLE_DEVICES=1 python src/run_summarization.py --mode=eval --data_path= $HOME /data/cnn_dm/finished_files/chunked/val_ * --vocab_path= $HOME /data/cnn_dm/finished_files/vocab --log_root= $HOME /working_dir/cnn_dm/RLSeq2Seq/ --exp_name=intradecoder-temporalattention-withpretraining --batch_size=8 --use_temporal_attention=True --intradecoder=True --rl_training=False正如Paulus等人所建议的那样,我们使用了从跨膜损失到RL损失的线性过渡,因此我们最终完全依靠RL损失来训练模型。参数ETA控制此过渡。我们将ETA设置为ETA = 1/(最大RL迭代)。
首先,将所需的培训参数添加到模型:
CUDA_VISIBLE_DEVICES=0 python src/run_summarization.py --mode=train --data_path= $HOME /data/cnn_dm/finished_files/chunked/train_ * --vocab_path= $HOME /data/cnn_dm/finished_files/vocab --log_root= $HOME /working_dir/cnn_dm/RLSeq2Seq/ --exp_name=intradecoder-temporalattention-withpretraining --batch_size=80 --max_iter=40000 --intradecoder=True --use_temporal_attention=True --eta=2.5E-05 --rl_training=True --convert_to_reinforce_model=True然后,开始使用MLE+RL训练损失运行模型:
CUDA_VISIBLE_DEVICES=0 python src/run_summarization.py --mode=train --data_path= $HOME /data/cnn_dm/finished_files/chunked/train_ * --vocab_path= $HOME /data/cnn_dm/finished_files/vocab --log_root= $HOME /working_dir/cnn_dm/RLSeq2Seq/ --exp_name=intradecoder-temporalattention-withpretraining --batch_size=80 --max_iter=40000 --intradecoder=True --use_temporal_attention=True --eta=2.5E-05 --rl_training=TrueCUDA_VISIBLE_DEVICES=1 python src/run_summarization.py --mode=eval --data_path= $HOME /data/cnn_dm/finished_files/chunked/val_ * --vocab_path= $HOME /data/cnn_dm/finished_files/vocab --log_root= $HOME /working_dir/cnn_dm/RLSeq2Seq/ --exp_name=intradecoder-temporalattention-withpretraining --batch_size=8 --use_temporal_attention=True --intradecoder=True --rl_training=True我们将胭脂作为评估指标。
CUDA_VISIBLE_DEVICES=0 python src/run_summarization.py --mode=decode --data_path= $HOME /data/cnn_dm/finished_files/chunked/test_ * --vocab_path= $HOME /data/cnn_dm/finished_files/vocab --log_root= $HOME /working_dir/cnn_dm/RLSeq2Seq/ --exp_name=intradecoder-temporalattention-withpretraining --rl_training=True --intradecoder=True --use_temporal_attention=True --single_pass=1 --beam_size=4 --decode_after=0
范围 默认 描述 ac_training 错误的 使用DDQN使用Actor-Critic学习。 dqn_scheduled_sampling 错误的 是否使用计划的采样来使用DDQN模型的估计值与实际Q估算值 dqn_layers 512,256,128 DDQN密集的隐藏层大小。它将创建三个密集的层,有512、256和128尺寸 dqn_replay_buffer_size 100000 重播缓冲区的尺寸 dqn_batch_size 100 训练DDQN型号的批量尺寸 dqn_target_update 10000 每10000个步骤更新目标Q网络 dqn_sleep_time 2 火车DDQN型号每2秒 dqn_gpu_num 1 GPU编号训练DDQN dueling_net 真的 是否使用决斗网络训练模型https://arxiv.org/pdf/1511.06581.pdf dqn_polyak_averaging 真的 是否要使用PolyAk平均来更新目标Q网络参数:psi^{prime} =(tau * psi^{prime})+(1-tau) * psi 计算_true_q 错误的 是使用真正的Q值训练DDQN还是使用DDQN的估计值训练它 dqn_pretrain 错误的 用固定演员模型预处理DDQN网络 dqn_pretrain_steps 10000 预先训练DDQN的步骤数
参与者批评模型的一般框架如下:

在我们的实施中,演员是指针生成器模型,评论家是一种回归模型,可将Q值估计最小化,使用双重Q网络(DDQN)。该代码的实现使DDQN培训与主线程不同,并且我们从Actor模型中不同步收集了该网络的经验。因此,对于每批,我们收集(批次_size * max_dec_steps)进行DDQN培训。我们实施了优先的重播缓冲区。在DDQN培训期间,我们始终选择我们的迷你批次,以便根据基本真相的摘要,它们具有最好的部分奖励的经验。我们添加了基于真正的Q估计的培训DDQN的选项,并提供了一个计划训练该网络的计划采样过程。请注意,由于收集了真正的Q值,使用真实Q估计的训练DDQN将大大降低训练速度。因此,我们建议仅在一些迭代中激活它。如Bahdanau等人的建议。最好使用固定的预训练的演员先预先培训评论家模型,然后同时开始训练这两个模型。例如,我们可以使用以下一组代码来运行与Bahdanau等人相似的实验:
CUDA_VISIBLE_DEVICES=0 python src/run_summarization.py --mode=train --data_path= $HOME /data/cnn_dm/finished_files/chunked/train_ * --vocab_path= $HOME /data/cnn_dm/finished_files/vocab --log_root= $HOME /working_dir/cnn_dm/RLSeq2Seq/ --exp_name=actor-critic-ddqn --batch_size=80 --max_iter=20000我们可以使用Dueling网络通过激活dueling_net标志来训练DDQN。此外,我们可以选择使用dqn_polyak_averaging标志的polyak平均来更新目标网络。
CUDA_VISIBLE_DEVICES=0,1 python src/run_summarization.py --mode=train --data_path= $HOME /data/cnn_dm/finished_files/chunked/train_ * --vocab_path= $HOME /data/cnn_dm/finished_files/vocab --log_root= $HOME /working_dir/cnn_dm/RLSeq2Seq/ --exp_name=actor-critic-ddqn --batch_size=80 --max_iter=21000 --ac_training=True --dueling_net=True --dqn_polyak_averaging=True --convert_to_reinforce_model=True --dqn_gpu_num=1使用dqn_pretrain_steps标志来设置要预先培训评论家的迭代数量。
CUDA_VISIBLE_DEVICES=0,1 python src/run_summarization.py --mode=train --data_path= $HOME /data/cnn_dm/finished_files/chunked/train_ * --vocab_path= $HOME /data/cnn_dm/finished_files/vocab --log_root= $HOME /working_dir/cnn_dm/RLSeq2Seq/ --exp_name=actor-critic-ddqn --batch_size=80 --ac_training=True --dqn_pretrain=True --dueling_net=True --dqn_polyak_averaging=True --dqn_gpu_num=1我们可以使用dqn_gpu_num选项使用其他GPU编号来在另一个GPU中运行Actor,并在另一个GPU中运行Actor。另外,如前所述,我们应该避免长期使用真实的Q-估计,因此,我们使用真实的估计仅用于1000个迭代训练DDQN。
CUDA_VISIBLE_DEVICES=0,1 python src/run_summarization.py --mode=train --data_path= $HOME /data/cnn_dm/finished_files/chunked/train_ * --vocab_path= $HOME /data/cnn_dm/finished_files/vocab --log_root= $HOME /working_dir/cnn_dm/RLSeq2Seq/ --exp_name=actor-critic-ddqn --batch_size=80 --max_iter=22000 --ac_training=True --dueling_net=True --dqn_polyak_averaging=True --calculate_true_q=True --dqn_gpu_num=1请注意,我们不再使用calculate_true_q标志了。
CUDA_VISIBLE_DEVICES=0,1 python src/run_summarization.py --mode=train --data_path= $HOME /data/cnn_dm/finished_files/chunked/train_ * --vocab_path= $HOME /data/cnn_dm/finished_files/vocab --log_root= $HOME /working_dir/cnn_dm/RLSeq2Seq/ --exp_name=actor-critic-ddqn --batch_size=80 --max_iter=40000 --ac_training=True --dueling_net=True --dqn_polyak_averaging=True --dqn_gpu_num=1CUDA_VISIBLE_DEVICES=0 python src/run_summarization.py --mode=decode --data_path= $HOME /data/cnn_dm/finished_files/chunked/test_ * --vocab_path= $HOME /data/cnn_dm/finished_files/vocab --log_root= $HOME /working_dir/cnn_dm/RLSeq2Seq/ --exp_name=actor-critic-ddqn --ac_training=True --dueling_net=True --dqn_polyak_averaging=True --dqn_gpu_num=1 --single_pass=1 --beam_size=4请注意,我们也可以在Actor-Critic模型中使用诸如intradecoder , temporal_attention , E2EBackProp , scheduled_sampling等选项。使用这些选项将有助于具有更好的性能演员模型。
感谢@astorfi在准备此文档方面的帮助。