GithubHelp home page GithubHelp logo

luofuli / dualrl Goto Github PK

View Code? Open in Web Editor NEW
262.0 6.0 44.0 35.62 MB

A Dual Reinforcement Learning Framework for Unsupervised Text Style Transfer (IJCAI 2019)

Home Page: https://export.arxiv.org/pdf/1905.10060

License: MIT License

Python 99.99% Perl 0.01%
text-style-transfer dual-learning unsupervised-machine-learning reinceforcement-learning

dualrl's Introduction

Reproducibility

In order to help you quickly reproduce the existing works of text style transfer, we release the outputs of all models and the corresponding references.

  • Outputs: Generated results (outputs) of 10 baselines and our model are in the outputs/ directory.
  • References: Human references are in the references/ directory. We also release the three more references we collected on the yelp test dataset, namely reference[0,1,2,3].0(the transferred references of negative sentences) and reference[0,1,2,3].1 (the transferred references of positive sentences). The reference0.0 and reference0.1 are collected by Li et al., 2018. We strongly recommend that you use the released multi-references dataset because it has a stronger correlation with human evaluation results.

Ps: We welcome other researchers pull request the outputs of your models.

Dataset

yelp: negative sentiment (0) <--> positive sentiment (1)

  • Original dataset: The original yelp dataset is in the data/yelp directory, where x.0 denotes the negative x type of data and x.1 denotes the positive x type of data. x is in [train, dev, test].
  • Pseudo-parallel data: The pseudo-parallel data generated by templates can be found in the data/yelp/tsf_template directory. x.0.tsf denotes the negative transferred file in which each line only has the sentiment transferred sentence, while x.0-1.tsf denotes the negative transferred file in which each line has both the original sentence (input) and sentiment transferred sentence (output).

GYAFC: informal text (0) <--> formal text (1)

Since the GYAFC dataset is only free of charge for research purposes, we only publish a subset of the test dataset in the family and relationships domain (data/GYAFC/), the outputs (outputs/GYAFC/) of each system (including our model and all baselines) and the corresponding human references (references/GYAFC/). If you want to download the train and validation dataset, please follow the guidance at https://github.com/raosudha89/GYAFC-corpus. And then, name the corpora of two styles as the yelp dataset.

Quick Start

First of all, you should specify the dataset. For example, for yelp dataset:

export DATASET=yelp

If you want to use your own datasets, please follow the guidance of next section Extend to other tasks and datasets.

Step 1: Pre-train classifier

cd classifier
python textcnn.py --mode train

Note: If you get the error no module named opennmt, please install OpenNMT-tf: pip install OpenNMT-tf==1.15.0.

Step 2: Pre-train two seq2seq (nmt) models using pseudo-parallel data

2.1 Prepare pseudo-parallel data

To generate pseudo-parallel data, we follow the template-based method proposed by Li et al., 2018. And we have provided the pseudo-parallel data of the yelp dataset in the data/yelp/tsf_template directory. However, if you want to generate the pseudo-parallel data using templates, you can follow this link or design your own templates which are suitable for your task and dataset.

2.2 Pre-train two seq2seq (nmt) models

The default encoder and decoder are bilstm.

cd nmt
python nmt.py --mode train --nmt_direction 0-1 --n_epoch 5  # Pre-train forward (f) model
python nmt.py --mode train --nmt_direction 1-0 --n_epoch 5  # Pre-train backward (g) model

If you want to adopt transformer as encoder and decoder, run the following code:

cd nmt
python nmt.py --mode train --nmt_direction 0-1 --n_epoch 5 --n_layer 6 --encoder_decoder_type transformer
python nmt.py --mode train --nmt_direction 1-0 --n_epoch 5 --n_layer 6 --encoder_decoder_type transformer 

Step 3: Dual reinforcement learning

python dual_training.py --n_epoch 10

The final transffered results are in the ../tmp/output/${DATASET}_final/ dir.

Extend to other tasks and datasets

If you don't have parallel or paired data, here are the processes you might go through:

  1. Prepare two unaligned (unpaired) corpora, one sentence per line
  2. Divide the dataset into train/dev/test
  3. Prepare pseudo-parallel corpus, you can use Li's method, or your own designed heuristic rules/templates
  4. Run step 1-3 in the section of Quick Start and specify the path to your new dataset or rename them like files in data/yelp/ and references/yelp/.

If you have parallel or paired data, here are the processes you might go through:

  1. Prepare two parallel corpora, one sentence per line
  2. Divide the dataset into train/dev/test
  3. Copy the dataset generated in the second step as the "pseudo-parallel" corpus to data/yelp/tsf_template
  4. Run step 1-3 in the section of Quick Start and specify the path to your new dataset or rename them like files in data/yelp/ and references/yelp/.

You can run the following code to see which parameters need to be set

python [dual_training.py | nmt.py | textcnn.py] --help

FAQ

About pseudo-parallel data

For some tasks, Li's method can't be used to generate pseudo-parallel data. Here are some related frequently asked questions:

  1. Can I use the original sentence to pre-train the two seq2seq models?

You can refer to this issue to generate pseudo-parallel data via simply add some noise to the original sentence.

  1. Can I use other style transfer models to generate pseudo-parallel data?

Of course, you can! Actually, we have tried to use CrossAlignment(Shen et al.,) to generated pseudo-parallel data. However, the experimental results are worse than using template-based methods.

  1. How about using several different methods to construct pseudo-parallel data?

We have tried to merge pseudo-parallel data generated by CrossAlignment (Shen et al.,) and Template-based(Li et al.,) to pre-train our model. There is a slight improvement in the experimental results.

  1. Can I train the model without pre-training with pseudo-parallel data?

This is an interesting question. I will try to remove the pre-training step. I think a feasible solution is to just initialize the word-embeddings of seq2seq (nmt) model, inspired by the three principles of unsupervised machine translation.

Tips

Note: No matter what method you use to construct pseudo-parallel data, the style transferred sentence or generated sentence y' (lower quality) should be the input, not the output (ground truth). This is validated to be important by our experiments. And what you need to actually do is to put y'\tx\n into files of tsf-template dir.

Dependencies

python==2.7
numpy==1.14.2
tensorflow==1.13.1
OpenNMT-tf==1.15.0 

Cite

If you use this code, please cite the following paper:

@inproceedings{Luo19DualRL,
  author    = {Fuli Luo and
               Peng Li and
               Jie Zhou and
               Pengcheng Yang and
               Baobao Chang and
               Zhifang Sui and
               Xu Sun},
  title     = {A Dual Reinforcement Learning Framework for Unsupervised Text Style Transfer},
  booktitle = {Proceedings of the 28th International Joint Conference on Artificial Intelligence, {IJCAI} 2019},
  year      = {2019},            
}

dualrl's People

Contributors

luofuli avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

dualrl's Issues

outputs of models on the GYAFC corpus

I was wondering if you could release the outputs from both your DualRL model and your baselines for the full test set of the GYAFC corpus, for a better comparison of different models. Considering the privacy issues of the GYAFC dataset, could you show the outputs from different models and hide the inputs (for x->y, only show the y's)?

Wrong Reference Data

I find that one of your reference data for yelp is wrong, i.e. yelp/reference0.0 and yelp/reference0.1 . It is actually the human reference for GYAFC dataset .

Classifier checkpoint

I'm appreciate for your Work.
I'm wondering if you can share the classifier checkpoint?

Thank you :)

How to evaluate on dev set and use early stopping

I have gone through your code. In dual_training.py you are evaluating on test set not on dev set and code is run for 10 epoch. But, in paper it is mentioned that you are using early stopping on dev set performance with patience=1. Can you elaborated which performance. Is there any references data for dev set to calculated BLEU score on dev set.
Thanks in advance.

How to do inference on a single sentence

I am running this model in a Google Colab notebook. However, after following the steps in the ReadMe file to train the model, I'm not sure how I can apply the model to provide an inference on a given sentence. So for example, what command would I provide to execute the model on a negative sentence of "I do not like this food" to generate a positive sentiment of "I like this food". Or is there no such command and would I need to place my input (negative sentiment) sentence in a file and call a function?

I had tried creating a directory called 'evaluatingWithNegative' located in 'data/evaluatingWithNegative' (adjacent to the Yelp dataset). In that directory, I placed a file named "x.0" where I put the sentence "i do not like this food ."
I then ran the commands

%cd classifier
!python textcnn.py --mode evaluate

And besides some warning statements, it outputted:

Saving classifier result at: /content/DualRL/tmp/cls_result_yelp.txt
Test accuracy: 96.40

I then ran

%cd nmt
!python nmt.py --mode inference --nmt_direction 0-1

Which outputted:

WARNING: The TensorFlow contrib module will not be included in TensorFlow 2.0.
For more information, please see:
  * https://github.com/tensorflow/community/blob/master/rfcs/20180907-contrib-sunset.md
  * https://github.com/tensorflow/addons
If you depend on functionality not listed there, please file an issue.

A=0, B=1
Vocabulary size:src:9353
Use x'->y to update model f(x->y)
WARNING:tensorflow:From ../utils/data.py:61: group_by_window (from tensorflow.contrib.data.python.ops.grouping) is deprecated and will be removed in a future version.
Instructions for updating:
Use `tf.data.experimental.group_by_window(...)`.
WARNING:tensorflow:From ../utils/data.py:23: to_int64 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use tf.cast instead.
WARNING:tensorflow:From /usr/local/lib/python2.7/dist-packages/tensorflow/python/data/ops/dataset_ops.py:1419: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.
Instructions for updating:
Colocations handled automatically by placer.
Prepare for model saver
('Model save path:', '/content/DualRL/tmp/model/yelp/nmt_template/0-1/')
Adopt bilstm as encoder and decoder
RNN Decoder CopyBridge
WARNING:tensorflow:From /usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/function.py:1007: calling create_op (from tensorflow.python.framework.ops) with compute_shapes is deprecated and will be removed in a future version.
Instructions for updating:
Shapes are always computed; don't use the compute_shapes as it has no effect.
WARNING:tensorflow:From /usr/local/lib/python2.7/dist-packages/opennmt/utils/cell.py:47: __init__ (from tensorflow.python.ops.rnn_cell_impl) is deprecated and will be removed in a future version.
Instructions for updating:
This class is equivalent as tf.keras.layers.LSTMCell, and will be replaced by that in Tensorflow 2.0.
WARNING:tensorflow:From /usr/local/lib/python2.7/dist-packages/opennmt/encoders/rnn_encoder.py:133: bidirectional_dynamic_rnn (from tensorflow.python.ops.rnn) is deprecated and will be removed in a future version.
Instructions for updating:
Please use `keras.layers.Bidirectional(keras.layers.RNN(cell))`, which is equivalent to this API
WARNING:tensorflow:From /usr/local/lib/python2.7/dist-packages/tensorflow/python/ops/rnn.py:443: dynamic_rnn (from tensorflow.python.ops.rnn) is deprecated and will be removed in a future version.
Instructions for updating:
Please use `keras.layers.RNN(cell)`, which is equivalent to this API
WARNING:tensorflow:From /usr/local/lib/python2.7/dist-packages/tensorflow/python/ops/rnn.py:626: to_int32 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use tf.cast instead.
/content/DualRL/tmp/model/yelp/nmt_template/0-1/
('Loading nmt model from', '/content/DualRL/tmp/model/yelp/nmt_template/0-1/')
WARNING:tensorflow:From /usr/local/lib/python2.7/dist-packages/tensorflow/python/training/saver.py:1266: checkpoint_exists (from tensorflow.python.training.checkpoint_management) is deprecated and will be removed in a future version.
Instructions for updating:
Use standard file APIs to check for files with this prefix.
('Error! Loading nmt model from', '/content/DualRL/tmp/model/yelp/nmt_template/0-1/')
('Again! Loading nmt model from', u'/content/DualRL/tmp/model/yelp/nmt_template//0-1/-2300')
Adopt bilstm as encoder and decoder
RNN Decoder CopyBridge
Reuse parameters.
Result save path:/content/DualRL/tmp/output/yelp_template/test.0-1.tsf, /content/DualRL/tmp/output/yelp_template/test.0.tsf
INFERENCE---Total N batch:17	Generate probs:-11.8581542969	Cost time:5.07563018799

But I am very confused if I am following the right commands to get an inference, and where I can find the output 'positive' sentiment sentence.

unable to converge

您好,我按照您readme里面的提示,进行操作,数据集采用的是yelp,进行到dual_training.py的时候,bleu一直在减少,直到变为0,根本无法收敛,

pseudo-parallel data for GYAFC

Thank you for this great work!

It seems it's not straightforward to apply the template-based method to the informal-formal dataset since there're no clear attribute markers as those in the yelp dataset. Could you please share more details on how you prepared the pseudo-parallel data for the informal-formal transfer task? Also, I'd really appreciate it if you can share a few examples of the pseudo pairs resulting from the template-based method.

Why did you not use beam search for decoding?

I noticed that in your code, you used random and greedy mode for decoding, however, why did you not use beam search? It should be better than greedy decoding at least for evaluation, right? Thanks!

关于bleu

请问一下那个bleu计算是所有样本的bleu得分的和,还是平均得分乘以100后得到的,不太懂,望大佬指教

nmt/model.py

when I run this project, there is an error in nmt/model.py line 115:
NameError: name "maximum_" is not defined.

I change it to be:
maximum_iterations = self.params.get("maximum_iterations",100)
it success run.
I think you delete it by mistake...

How to set the max_output_sequence_length

Hi, sorry to bother you again.
I print the shape of the output and find the maximum output seq length is 20 and lots of samples are pinched off from the middle because of this maximum seq length.
But I cannot find the position to set the maximum output seq length, where can I set it ?
Thank You!

Appendix: the shape of output I printed
image
(16 is the batch size, 10 is the decode_width. This is "random_prediction")

how to tune hyper-parameters to balance between sentiment accuracy and BLEU score

hi, I tried re-running your code without changing any hyper-parameters, however, I got this result: 0-1_Test(Batch:1600) Senti:77.300 BLEU(4ref):61.125(A:55.520+B:66.730) G-score:68.738 H-score:68.267 Cost time:2.57.
Could you provide some experience about how to tune the hyper-parameters so that I can balance between the sentiment accuracy and the BLEU score? Thank you so much!

GYAFC dataset

I've followed the instructions required to get access to GYAFC dataset and managed to get approval from Yahoo. But after I forward the approval email to the author of the GYAFC dataset, there's no further response until now. Is the author of GYAFC dataset still working on it? How long may I get his response according to your previous experience? If no reply will be given, how could I obtain the dataset?

Question about Baseline Codes

Hi Luofuli,
This is a very nice work in text style transfer and I have a question. Are the results of baselines from the code released by original authors or the code reimplemented by you?

Question about the pseudo-parallel data in the DualRL training stage

Thanks for your great work!

I have a question for the pseudo-parallel data used in the annealing pseudo teacher-forcing stage: From your paper, I notice the pseudo-parallel data is generated on-the-fly using the latest model. However, I find the codes for this in the dual_training.py, as shown below,

DualRL/dual_training.py

Lines 84 to 86 in 7983ec0

paired_src_train_iterator = load_paired_dataset(args.tsf_train_data[B], args.train_data[B],
src_vocab, tgt_vocab, batch_size=args.batch_size,
min_seq_len=min_seq_len)

DualRL/dual_training.py

Lines 308 to 317 in 7983ec0

if n_batch % gap == 0:
data = sess.run(paired_train_data_next[A]) # get real data!!
feed_dict = {
nmts_train[A].input_ids: data["ids"],
nmts_train[A].input_length: data["length"],
nmts_train[A].target_ids_in: data["trans_ids_in"],
nmts_train[A].target_ids_out: data["trans_ids_out"],
nmts_train[A].target_length: data["trans_length"],
}
nmtA_pseudo_loss_, _ = sess.run([nmts_train[A].loss, nmts_train[A].train_op], feed_dict=feed_dict)

just load paired data from args.tsf_train_data which stores the pseudo-parallel data generated by the template-based approach for pretraining, instead of generating with the latest model.

Did I understand this correctly? Have I missed anything?
Thank you.

The original outputs of DualRL

Hi Fuli,
Thanks for you great work.
I found that you released the lowercase output on Github. Since I would like to conduct some comparative experiments on the original results of different models, would you please share the original outputs of your model on the GYAFC (formality transfer dataset) with me?
Thank you very much for all your help!

Training Duration

Hi, your work seems quite interesting and original. I am curious about the training duration of DualRL training, given the hyper-parameter you mentioned, how long did it take to finish the training for Yelp ?

Restoring of OpenNMT checkpoints

Hi Fuli,
I have trained the NMT model using OpenNMT=1.15, now trying to restore checkpoints (trained using OpenNMT) in DualRL setting. But facing issue while restoring, Error: Key NMT0-1/NMT0-1/decoder/dense/bias not found in checkpoint
[[Node: NMT0-1/save/RestoreV2_2 = RestoreV2[dtypes=[DT_FLOAT], _device="/job:localhost/replica:0/task:0/device:CPU:0"](_arg_NMT0-1/save/Const_0_0, NMT0-1/save/RestoreV2_2/tensor_names, NMT0-1/save/RestoreV2_2/shape_and_slices)]]
. Note I have change the parameters like #layers, emb_dim etc.
Will you suggest something, how to restore OpenNMT checkpoint during DualRL setting.

Thanks in advance.

Style accuracy mismatch 85.6%(Table 1, from the paper) Vs 88.40% (using https://github.com/luofuli/DualRL#step-1-pre-train-classifier and https://github.com/luofuli/DualRL/tree/master/outputs/yelp/DualRL)

Thanks, for having a separate section for reproducibility (https://github.com/luofuli/DualRL#reproducibility.) on this great work.
When I am using a pre-train classifier (same as https://github.com/luofuli/DualRL#step-1-pre-train-classifier) for evaluating the style accuracy, I am getting 88.40% for the yelp dataset on DUAL RL output(https://github.com/luofuli/DualRL/tree/master/outputs/yelp/DualRL).
But you have reported 85.6% only. So what could be the reason for this difference? Am I missing something?

OOM error

ResourceExhaustedError (see above for traceback): OOM when allocating tensor with shape[640,54,9353] and type float on /job:localhost/replica:0/task:0/device:GPU:0 by allocator GPU_0_bfc
[[node NMT1-0/train/optim_1/gradients/zeros_1 (defined at /data/home/neowang/DualRL/utils/optim.py:150) ]]
Hint: If you want to see a list of allocated tensors when OOM happens, add report_tensor_allocations_upon_oom to RunOptions for current allocation info.

我用一张 p100,跑 python dual_training.py --n_epoch 10 出现的

Random decode and Greedy decode

Hi, nice repo and I have a little question when reading your code. Why did you take greedy decode results as baseline and use it to normalize random decode results?
截屏2021-06-11 下午7 47 57

Thanks very much!!!

template help

Hi, thanks for your great work! We were just getting started with the code and were wondering how exactly you generated the templates for the GYAFC dataset. We have all the data labeled with train.0, train.1, ... and we tried to run the get_template_based_result.py command in the terminal. However, we kept getting error

Starting search for file: ../data/GYAFC/template_result/replace_result.test.0-1.tsf
FileNotFoundError: [Errno 2] No such file or directory: '../data/GYAFC/template_result/replace_result.test.0-1.tsf'

Are we supposed to use this to generate the templates? https://github.com/lijuncen/Sentiment-and-Style-Transfer I could not see in the bash script where it generated the tsf files.

Also, when we train the DualRL model, will it automatically use the tsf files? And are the tsf files optional? What other ways do you recommend that we can preprocess it more simply? We were also a little confused about the point of the tsf files / pseudoparallel data in the README and when they came into play. Aren't we trying to do this entirely without parallel data?

Sorry for all the questions, looking forward to hearing back!

the outputs of all models

Hi, Fuli. Thanks for your great work.
I'm very curious about the generating outputs, how do you get those outputs of the baseline models? Did you try to reproduce the results of those models or collected them elsewhere? Thanks again!

CalledProcessError: Command returned non-zero exit status 1.

With those .tsf files and .0 .1 files nice and neat, running the bleu perl program called an error:
CalledProcessError: Command 'perl C:\Users\myname\DualRL\utils\script\multi-bleu.perl C:\Users\myname\DualRL/references/yelp/reference0.1 C:\Users\myname\DualRL/references/yelp/reference1.1 C:\Users\myname\DualRL/references/yelp/reference2.1 C:\Users\myname\DualRL/references/yelp/reference3.1 < C:/Users/myname/DualRL/tmp/output/yelp_final/0_test.1.tsf' returned non-zero exit status 1.

I thought the .perl file may be some famous public program for bleu calculation but it only mentions "return" once so I'm not sure where the problem is. I'm using the original code/perl program and yelp dataset with minor changes.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.