Nota: Este código não é mais mantido ativamente.
Este repositório contém o código desenvolvido no TensorFlow para o seguinte artigo:
Se você usou este código, por favor, considere citar o seguinte artigo:
@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}
}
Nos últimos anos, os modelos de sequência para sequência (SEQ2SEQ) são usados em uma variedade de tarefas, desde tradução da máquina, geração de manchetes, resumo de texto, fala para texto e geração de legenda de imagem. A estrutura subjacente de todos esses modelos é geralmente uma rede neural profunda que contém um codificador e decodificador. O codificador processa os dados de entrada e um decodificador recebe a saída do codificador e gera a saída final. Embora simplesmente o uso de um modelo de codificador/decodificador, na maioria das vezes, produza melhor o resultado do que os métodos tradicionais nas tarefas acima mencionadas, os pesquisadores propuseram melhorias adicionais sobre esses modelos de sequência para seqüências, como usar um modelo baseado em atenção sobre os modelos de entrada, geração de ponteiro e modelos de auto-atenção. No entanto, todos esses modelos SEQ2SEQ sofrem de dois problemas comuns: 1) viés de exposição e 2) inconsistência entre a medição do trem/teste. Recentemente, surgiu um ponto de vista completamente novo na solução desses dois problemas nos modelos SEQ2SEQ usando métodos no aprendizado de reforço (RL). Nessas novas pesquisas, tentamos analisar os problemas do SEQ2SEQ do ponto de vista da RL e tentamos criar uma formulação que possa combinar o poder dos métodos RL na tomada de decisões e sequenciar modelos de seqüência na lembrança de longas memórias. Neste artigo, resumiremos algumas das estruturas mais recentes que combinam conceitos do mundo da RL à área de rede neural profunda e explicará como essas duas áreas podem se beneficiar uma da outra na solução de tarefas complexas do SEQ2SEQ. No final, forneceremos informações sobre alguns dos problemas dos modelos existentes atuais e como podemos melhorá -los com melhores modelos de RL. Também fornecemos o código -fonte para implementar a maioria dos modelos que serão discutidos neste artigo sobre a complexa tarefa de resumo abstrato de texto.
- Use Python 2.7
Os requisitos do Python podem ser instalados da seguinte forma:
pip install -r python_requirements.txt
- Tensorflow 1.10.1
- CUDA 9
- CUDNN 7.1
https://github.com/abisee/cnn-dailymail
https://summari.es/
Fornecemos códigos auxiliares para baixar o conjunto de dados da CNN-DailyMail e pré-processar esse conjunto de dados e conjunto de dados da sala de redação. Consulte este link para acessá -los.
Vimos uma grande melhoria na medida de Rouge usando nossa versão processada desses conjuntos de dados nos resultados de resumo; portanto, sugerimos fortemente o uso desses arquivos pré-processados para todo o treinamento.
Este código é uma estrutura geral para uma variedade de modos diferentes que suporta os seguintes recursos:
Bengio et al. propôs a idéia de amostragem programada para evitar problemas de viés de exposição. Recentemente, Goyal et al. propuseram uma relaxção diferenciável desse método, usando o argmax soft-argmax, que resolve o erro de propagação de volta que existe neste modelo. Além disso, Ranzato et al. propuseram outro modelo simples chamado end2endbackProp para evitar problemas de viés de exposição. Para treinar um modelo baseado em cada um desses papéis, fornecemos bandeiras diferentes da seguinte forma:
Parâmetro Padrão Descrição programado_sampling Falso se deve fazer amostragem programada ou não sampling_probability 0 Valor epsilon para escolher a saída do solo ou modelo de modelo FILL_SAMPLING_PROBABILIDADE Falso Se deve usar probabilidade de amostragem fixa ou adaptativa hard_argmax Verdadeiro Se deve usar argmax suave ou argmax duro ganancioso_scheduled_sampling Falso Se deve usar ganancioso ou amostra para a saída, verdadeiro significa ganancioso E2ebackprop Falso Se deve usar o algoritmo E2EbackProp para resolver o viés de exposição alfa 1 argumento argmax suave
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
Parâmetro Padrão Descrição rl_training Falso Inicie o treinamento em gradiente de políticas convert_to_reinforce_model Falso Converta um modelo de ponteiro em um modelo de reforço. Ligue isso e execute no modo de trem. Seu modelo de treinamento atual será copiado para uma nova versão (mesmo nome com _cov_init anexado) que estará pronto para executar com a bandeira de cobertura ligada, para o estágio de treinamento de cobertura. Intadecoder Falso Use atenção intra -tendal ou não USE_TEMPORAL_ATTENTENT Verdadeiro Se deve usar atenção temporal ou não Matrix_attion Falso Use a atenção da matriz, Eq. 2 em https://arxiv.org/pdf/1705.04304.pdf ETA 0 Fator de escala RL/MLE, 1 significa usar perda de RL, 0 significa usar perda de MLE FILL_ETA Falso Use valor fixo para ETA ou adaptativo com base na etapa global gama 0,99 RL Recompensa Fator de desconto Recompensa_function rouge_l/f_score Bleu ou uma das medidas Rouge (Rouge_1/f_score, Rouge_2/f_score, Rouge_l/f_score)
Paulus et al. propuseram um modelo de gradiente de política autocrítica para resumo abstrato de texto. A figura a seguir representa como esse método funciona e como implementamos este método:

Para replicar o experimento, podemos usar o seguinte conjunto de processos:
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=FalseAqui, usamos uma GPU diferente para avaliação, mas podemos usar a mesma GPU se diminuirmos o número de lotes. Em nossa implementação, usamos um tamanho em lote de 8 para avaliação, mas para cada etapa de avaliação, iteramos sobre o conjunto de dados de validação 100 vezes. Isso é semelhante a encontrar o erro de avaliação em um tamanho de lote de 800. Isso ajudará a diminuir a memória exigida pelo processo de avaliação e fornecer opções para executar o treinamento e avaliar uma 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=FalseConforme sugerido por Paulus et al, usamos uma transição linear da perda de entropia cruzada para a perda de RL, para que, no final, dependamos completamente da perda de RL para treinar o modelo. O parâmetro ETA controla essa transição. Definimos o ETA como ETA = 1/(iteração máxima do RL).
Primeiro, adicione o parâmetro de treinamento necessário ao modelo:
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=TrueEm seguida, comece a executar o modelo com perda de treinamento 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=TrueUsamos o Rouge como métricas de avaliação.
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
Parâmetro Padrão Descrição ac_training Falso Use o aprendizado ator-crítico por DDQN. dqn_scheduled_sampling Falso Se deve usar a amostragem programada para usar estimativas do modelo DDQN vs os valores reais de estestações Q DQN_LAYERS 512.256.128 DDQN denso tamanho da camada oculta. Ele criará três camadas densas com 512, 256 e 128 tamanho DQN_REPLAY_BUFFER_SIZE 100000 Tamanho do buffer de repetição dqn_batch_size 100 Tamanho do lote para treinar o modelo DDQN dqn_target_update 10000 Atualize o alvo q Rede a cada 10000 etapas dqn_sleep_time 2 Trem modelo DDQN a cada 2 segundos DQN_GPU_NUM 1 Número da GPU para treinar o DDQN dueling_net Verdadeiro Se deve usar a rede de duelo para treinar o modelo https://arxiv.org/pdf/1511.06581.pdf dqn_polyak_averraging Verdadeiro Se você deve usar a média do Polyak para atualizar os parâmetros de rede q de destino: psi^{prime} = (tau * psi^{prime})+ (1-tau) * psi calcular_true_q Falso Se deve usar os verdadeiros valores q para treinar DDQN ou usar as estimativas do DDQN para treiná-lo dqn_pretrain Falso Pré -TRAIN a rede DDQN com modelo de ator fixo DQN_PRETRAIN_STEPS 10000 Número de etapas para pré-treinar o DDQN
A estrutura geral para o modelo ator-crítico é o seguinte:

Em nossa implementação, o ator é o modelo Pointer-Generator e o crítico é um modelo de regressão que minimiza a estimativa de valor Q usando a rede Q Duplo Deep Doup Deep (DDQN). O código é implementado de modo que o treinamento do DDQN esteja em um encadeamento diferente do thread principal e coletamos experiências para essa rede de forma assíncrona do modelo de ator. Portanto, para cada lote, coletamos (Batch_size * max_dec_steps) declara para o treinamento DDQN. Implementamos o buffer de repetição priorizado. E durante o treinamento do DDQN, sempre selecionamos nossos mini lotes para que eles contenham experiências que tenham a melhor recompensa parcial de acordo com o resumo da verdadeira-verdade. Adicionamos uma opção de treinamento do DDQN com base na verdadeira estimação Q e oferecemos um processo de amostragem programada para treinar essa rede. Observe que o treinamento do DDQN usando a verdadeira estimação Q reduzirá significativamente a velocidade do treinamento, devido à coleta de valores Q verdadeiros. Portanto, sugerimos ativar isso apenas para algumas iterações. Conforme sugerido por Bahdanau et al. Também é bom usar um ator pré-treinado fixo para pré-treinar o modelo crítico primeiro e depois começar a treinar os dois modelos, simultaneamente. Por exemplo, podemos usar o seguinte conjunto de códigos para executar um experimento semelhante como Bahdanau et al.:
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 Podemos usar a rede de duelo para treinar o DDQN ativando o sinalizador dueling_net . Além disso, podemos optar por atualizar a rede de destino usando a média do Polyak pelo sinalizador dqn_polyak_averaging .
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 Use o sinalizador dqn_pretrain_steps para definir quantas iteração você deseja pré-treinar o crítico.
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 Podemos executar o ator em uma GPU e crítica em outra GPU simplesmente usando um número diferente de GPU para crítico usando a opção dqn_gpu_num . Além disso, como mencionado anteriormente, devemos evitar o uso de verdadeiros Q-estimação por muito tempo, portanto, usamos uma estimativa verdadeira para treinar DDQN para apenas 1000 iterações.
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 Observe que não usamos mais calculate_true_q sinalizador.
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 Observe que podemos usar opções como intradecoder , temporal_attention , E2EBackProp , scheduled_sampling , etc. em modelos de ator-crítico também. O uso dessas opções ajudará a ter um modelo de ator de melhor desempenho.
Obrigado @ASTORFI por sua ajuda na preparação desta documentação.