Opennmt-py: How to retrain a fully trained model on a new dataset (for domain adaptation)

Created on 18 Jun 2018  路  11Comments  路  Source: OpenNMT/OpenNMT-py

I have a fully trained Conversation model and I want to retrain the weights of that model on a small domain data for some epochs. So I can use the -train_from opt for this. However, I am confused about how to make sure the vocabulary used is same for the domain data.
For example,
Let's say the original training data has 25k vocabulary size. And the domain data has 21k vocabulary size. Now I want to preprocess the domain data with the vocabulary of training data. How do I do this in OpenNMT? What opts should I use while preprocessing. I have *.train.pt, *.valid.pt and *.vocab.pt files from the preprocessing the original training data with 25K vocab size. (I had used -share_vocab option in that)

Most helpful comment

Hi,

First, you need to preprocess your domain data with the following code given below:
" python preprocess.py -train_src data/src-train1.txt -train_tgt data/tgt-train1.txt -valid_src data/src-val1.txt -valid_tgt data/tgt-val1.txt -save_data data/demo2 "
Here, 'src-train1.txt' , 'tgt-train1.txt' , 'src-val1.txt' and 'tgt-val1.txt' are your training and validation datasets for 'domain data' (having 21K vocab).

Then, you need to use the '-train_from' command as given below:
" python train.py -data data/demo2 -train_from demo-model1_acc_16.36_ppl_119.22_e27.pt -save_model demo-model1 "
Here, 'demo-model1_acc_16.36_ppl_119.22_e27.pt' is the pre-saved model (having 25K vocab).
And the new model is being saved to 'model1....'.

Does this help?

All 11 comments

Hi,

First, you need to preprocess your domain data with the following code given below:
" python preprocess.py -train_src data/src-train1.txt -train_tgt data/tgt-train1.txt -valid_src data/src-val1.txt -valid_tgt data/tgt-val1.txt -save_data data/demo2 "
Here, 'src-train1.txt' , 'tgt-train1.txt' , 'src-val1.txt' and 'tgt-val1.txt' are your training and validation datasets for 'domain data' (having 21K vocab).

Then, you need to use the '-train_from' command as given below:
" python train.py -data data/demo2 -train_from demo-model1_acc_16.36_ppl_119.22_e27.pt -save_model demo-model1 "
Here, 'demo-model1_acc_16.36_ppl_119.22_e27.pt' is the pre-saved model (having 25K vocab).
And the new model is being saved to 'model1....'.

Does this help?

Thanks for the response. It did work but it resumed learning rate from previous epoch. Is there a way to reset the learning rate to the initial or some other setting?

You may want to refer to this : http://opennmt.net/OpenNMT/training/retraining/#resuming-a-stopped-training
What you are asking for is surely implementable using torch (lua language), but I doubt if the same functionality is implementable using pytorch (for python language)

@abaheti95
if you want to init learning rate when training from a trained model ,you can hack in the source.
tips:
just like lua language ,you can add args -continue , befor that ,you should change opt.py.
also, if you want to change laearning rate , just modify the code in onmt/utils/optimizers.py named build_optim, when load parmas from trained model , you can hack in , and change the rate from the opt.learning_rate.

@hpulfc answer almost worked for me. Here's what I did to make it work (not sure if all of these are important...)

In train_single.py main():

if opt.train_from:
        logger.info('Loading checkpoint from %s' % opt.train_from)
        checkpoint = torch.load(opt.train_from,
                                map_location=lambda storage, loc: storage)
        model_opt = opt
        for i in range(0, len(checkpoint['optim'].optimizer.param_groups)):
            checkpoint['optim'].optimizer.param_groups[i]['lr'] = opt.learning_rate
            checkpoint['optim'].optimizer.param_groups[i]['weight_decay'] = opt.learning_rate_decay

and

# Build optimizer.
    optim = build_optim(model, opt, None)

Then in onmt/utils/optimizers.py build_optim() function:

saved_optimizer_state_dict = None
 optim = Optimizer(
            opt.optim, opt.learning_rate, opt.max_grad_norm,
            lr_decay=opt.learning_rate_decay,
            start_decay_steps=opt.start_decay_steps,
            decay_steps=opt.decay_steps,
            beta1=opt.adam_beta1,
            beta2=opt.adam_beta2,
            adagrad_accum=opt.adagrad_accumulator_init,
            decay_method=opt.decay_method,
            warmup_steps=opt.warmup_steps,
            model_size=opt.rnn_size)

 # Stage 1:
    # Essentially optim.set_parameters (re-)creates and optimizer using
    # model.paramters() as parameters that will be stored in the
    # optim.optimizer.param_groups field of the torch optimizer class.
    # Importantly, this method does not yet load the optimizer state, as
    # essentially it builds a new optimizer with empty optimizer state and
    # parameters from the model.

    optim.set_parameters(model.named_parameters())

    return optim

Pardon the indentation on the last code block, edited on mobile

@jbecke Thanks for sharing the code. This is very useful to me.

One thing is that this code overrides the default behavior of continuing training from an existing model (parameters and all) using the -train_from option, which I still need. So I added a 'resume' option to toggle between the two behavior, now all's well.

@kaihuchen glad it was useful. I鈥檓 not sure what you mean in your second paragraph. The code should still load the old model parameters (i.e. structure, weights and biases) but create a new optimizer with the given params. Could you please clarify what your issue is?

I will make a PR if the maintainers (@srush (?)) agree that this should be the default behavior, i.e. use previous flags but override ones that the user explicitly specifies when they run -train_from?

@jbecke

What I meant above was that with your code change I thought I am losing the trained weights, since when I restarted the session using the train_from option to load a fully trained model (with good accuracy and low perplexity), I observe the accuracy goes way down to near zero and perplexity shot way up as if the training is starting from scratch.

Hope this clarifies.

@vermasrijan Thanks for your answer. But how to deal with new words in the new dataset?

is there going to be an official fix for learning rate (when using train_form option) ?

it is already possible, not sure to understand your point.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mrpega picture mrpega  路  3Comments

liangbright picture liangbright  路  4Comments

azureskyL picture azureskyL  路  3Comments

AyaNsar picture AyaNsar  路  4Comments

mataney picture mataney  路  4Comments