Nota: Este código ya no se mantiene activamente.
Este repositorio contiene el código desarrollado en TensorFlow para el siguiente documento:
Si usó este código, considere amablemente citar el siguiente documento:
@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}
}
En los últimos años, los modelos de secuencia a secuencia (SEQ2SEQ) se utilizan en una variedad de tareas, desde traducción automática, generación de titulares, resumen de texto, habla a texto, hasta la generación de subtítulos. El marco subyacente de todos estos modelos suele ser una red neuronal profunda que contiene un codificador y decodificador. El codificador procesa los datos de entrada y un decodificador recibe la salida del codificador y genera la salida final. Aunque simplemente usando un modelo de codificador/decodificador, la mayoría de las veces produciría un mejor resultado que los métodos tradicionales en las tareas mencionadas anteriormente, los investigadores propusieron mejoras adicionales sobre estas secuencias a los modelos de secuencia, como usar un modelo basado en la atención sobre la entrada, los modelos de generación de puntero y los modelos de autoatensión. Sin embargo, todos estos modelos SEQ2SEQ sufren dos problemas comunes: 1) sesgo de exposición y 2) inconsistencia entre la medición de tren/prueba. Recientemente, surgió un punto de vista completamente fresco para resolver estos dos problemas en los modelos SEQ2SEQ mediante el uso de métodos en el aprendizaje de refuerzo (RL). En estas nuevas investigaciones, tratamos de observar los problemas de SEQ2SEQ desde el punto de vista RL y tratamos de encontrar una formulación que podría combinar el poder de los métodos RL en la toma de decisiones y la secuencia de modelos de secuencia en el recuerdo de recuerdos largos. En este artículo, resumiremos algunos de los marcos más recientes que combinan conceptos del mundo RL al área de la red neuronal profunda y explicaremos cómo estas dos áreas podrían beneficiarse entre sí para resolver tareas complejas SEQ2SEQ. Al final, proporcionaremos información sobre algunos de los problemas de los modelos existentes actuales y cómo podemos mejorarlos con mejores modelos RL. También proporcionamos el código fuente para implementar la mayoría de los modelos que se discutirán en este documento sobre la compleja tarea de resumen de texto abstractos.
- Use Python 2.7
Los requisitos de Python se pueden instalar de la siguiente manera:
pip install -r python_requirements.txt
- TensorFlow 1.10.1
- CUDA 9
- Cudnn 7.1
https://github.com/abisee/cnn-dailymail
https://summari.es/
Hemos proporcionado códigos de ayuda para descargar el conjunto de datos CNN-DailyMail y preprocesar este conjunto de datos de datos y redes de redacción. Consulte este enlace para acceder a ellos.
Vimos una gran mejora en la medida de Rouge mediante el uso de nuestra versión procesada de estos conjuntos de datos en los resultados de resumen, por lo tanto, sugerimos firmemente el uso de estos archivos preprocesados para toda la capacitación.
Este código es un marco general para una variedad de modos diferentes que admite las siguientes características:
Bengio et al. propuso la idea de un muestreo programado para evitar el problema de sesgo de exposición. Recientemente, Goyal et al. propuso una relajación diferenciable de este método, mediante el uso de argmax suave bastante duro, argmax, que resuelve el error de propagación posterior que existe en este modelo. Además, Ranzato et al. propuso otro modelo simple llamado End2EdBackProp para evitar el problema de sesgo de exposición. Para capacitar un modelo basado en cada uno de estos documentos, proporcionamos diferentes banderas de la siguiente manera:
Parámetro Por defecto Descripción Scheduled_sampling FALSO si hacer un muestreo programado o no muestreo_probabilidad 0 Valor de Epsilon para elegir la verdad en tierra o la salida del modelo fijo_sampling_probability FALSO Si se debe usar una probabilidad de muestreo fijo o adaptativa hard_argmax Verdadero Si usar argmax suave o argmax duro greedy_scheduled_sampling FALSO Si usar codicioso o muestra para la salida, verdadero significa codicioso E2EBACKPROP FALSO Si usar el algoritmo E2EBackProp para resolver el sesgo de exposición alfa 1 argumento de 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 Por defecto Descripción rl_trining FALSO Iniciar capacitación en el gradiente de políticas convert_to_reinforce_model FALSO Convierta un modelo de puntero a un modelo de refuerzo. Encienda esto y ejecute en modo de tren. Su modelo de entrenamiento actual se copiará a una nueva versión (el mismo nombre con _cov_init adjunto) que estará listo para funcionar con la bandera de cobertura activada, para la etapa de entrenamiento de cobertura. intradecoder FALSO Use la atención de intradeCoder o no use_temporal_attention Verdadero Si usar atención temporal o no Matrix_Atention FALSO Use atención de la matriz, Eq. 2 en https://arxiv.org/pdf/1705.04304.pdf ETA 0 Factor de escala RL/MLE, 1 significa usar pérdida de RL, 0 significa usar pérdida de MLE fijo_eta FALSO Utilice un valor fijo para ETA o adaptativo basado en el paso global gama 0.99 Factor de descuento de recompensa RL recompensa_function Rouge_L/F_Score Ya sea Bleu o una de las medidas Rouge (Rouge_1/F_Score, Rouge_2/F_Score, Rouge_L/F_Score)
Paulus et al. propuso un modelo de gradiente de política autocrítico para resumen de texto abstractivo. La siguiente figura representa cómo funciona este método y cómo implementamos este método:

Para replicar su experimento, podemos usar el siguiente conjunto de procesos:
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=FalseAquí, usamos una GPU diferente para la evaluación, pero podemos usar la misma GPU si disminuimos el número de lotes. En nuestra implementación, utilizamos un tamaño por lotes de 8 para la evaluación, pero para cada paso de evaluación, iteramos sobre el conjunto de datos de validación 100 veces. Esto es similar a encontrar el error de evaluación en un tamaño por lotes de 800. Esto ayudará a disminuir la memoria requerida por el proceso de evaluación y proporcionar opciones para ejecutar tanto la capacitación como la evaluación en una 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=FalseSegún lo sugerido por Paulus et al, utilizamos una transición lineal de la pérdida de entropía cruzada a la pérdida de RL para que al final confíe completamente en la pérdida de RL para entrenar el modelo. El parámetro ETA controla esta transición. Establecemos ETA para que sea eta = 1/(iteración máxima RL).
Primero, agregue el parámetro de entrenamiento requerido al 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=TrueLuego, comience a ejecutar el modelo con la pérdida de entrenamiento 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=TrueUtilizamos Rouge como métricas de evaluación.
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 Por defecto Descripción AC_TRAININA FALSO Use el aprendizaje crítico actor por DDQN. dqn_scheduled_sampling FALSO Si se debe usar el muestreo programado para usar estimaciones del modelo DDQN frente a los valores reales de Q-Easimates dqn_layers 512,256,128 DDQN DENSE Tamaño de capa oculta. Creará tres capas densas con 512, 256 y 128 tamaño dqn_replay_buffer_size 100000 Tamaño del búfer de repetición dqn_batch_size 100 Tamaño de lote para entrenar el modelo DDQN dqn_target_update 10000 Actualizar el objetivo Q Red cada 10000 pasos dqn_sleep_time 2 CONTRICE MODELO DDQN cada 2 segundos dqn_gpu_num 1 Número de GPU para entrenar el DDQN dueling_net Verdadero Si se debe usar la red de duelo para entrenar el modelo https://arxiv.org/pdf/1511.06581.pdf dqn_polyak_averaging Verdadero Si se debe usar Polyak Promedio para actualizar los parámetros de red de Target Q: Psi^{Prime} = (tau * psi^{prime})+ (1 tau) * psi calculación_true_q FALSO Si se debe usar valores Q verdaderos para entrenar DDQN o usar las estimaciones de DDQN para entrenarlo dqn_prain FALSO Pretrarse la red DDQN con modelo de actor fijo dqn_prain_steps 10000 Número de pasos para pre-entrenar el DDQN
El marco general para el modelo de actor-crítico es el siguiente:

En nuestra implementación, el actor es el modelo de generador de puntero y el crítico es un modelo de regresión que minimiza la estimación del valor Q utilizando Double Deep Q Network (DDQN). El código se implementa de tal manera que la capacitación DDQN está en un hilo diferente del hilo principal y recopilamos experiencias para esta red asincrónicamente del modelo de actor. Por lo tanto, para cada lote, recopilamos los estados (Batch_Size * max_dec_steps) para la capacitación DDQN. Implementamos el búfer de repetición priorizado. Y durante la capacitación DDQN siempre seleccionamos nuestros mini lotes de modo que contengan experiencias que tienen la mejor recompensa parcial de acuerdo con el resumen de la verdad sobre el suelo. Agregamos una opción de capacitación de DDQN basada en la verdadera estimación Q y ofrecimos un proceso de muestreo programado para capacitar a esta red. Tenga en cuenta que la capacitación DDQN utilizando una verdadera estimación Q reducirá significativamente la velocidad de entrenamiento, debido a la recolección de valores Q verdaderos. Por lo tanto, sugerimos que solo active esto para algunas iteraciones. Según lo sugerido por Bahdanau et al. También es bueno usar un actor pre-entrenado fijo para pre-entrenado primero el modelo crítico y luego comenzar a entrenar ambos modelos, simultáneamente. Por ejemplo, podemos usar el siguiente conjunto de códigos para ejecutar un experimento similar al de 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 Dueling Network para entrenar el DDQN activando el indicador dueling_net . Además, podemos elegir actualizar la red de destino utilizando el promedio de Polyak por el indicador 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 el indicador dqn_pretrain_steps para establecer cuántas iteraciones desea pre-entrenar al 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 ejecutar actor en una GPU y crítico en otra GPU simplemente usando un número de GPU diferente para la opción dqn_gpu_num . Además, como se mencionó anteriormente, debemos evitar el uso de la verdadera estimación Q por mucho tiempo, por lo tanto, usamos una estimación verdadera para entrenar DDQN para solo 1000 iteraciones.
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 Tenga en cuenta que ya no usamos 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 Tenga en cuenta que podemos usar opciones como intradecoder , temporal_attention , E2EBackProp , scheduled_sampling , etc. en modelos críticos de actores también. El uso de estas opciones ayudará a tener un modelo de actor de mejor rendimiento.
Gracias @astorfi por su ayuda para preparar esta documentación.