# Buggy code
def __init__(
    self,
    word_vec_size,
    word_vocab_size,
    word_padding_idx,
    position_encoding=False,
    feat_merge="concat",
    feat_vec_exponent=0.7,
    feat_vec_size=-1,
    feat_padding_idx=[],
    feat_vocab_sizes=[],
    dropout=0,
    sparse=False,
):
    if feat_padding_idx is None:
        feat_padding_idx = []
    self.word_padding_idx = word_padding_idx

    self.word_vec_size = word_vec_size

    # Dimensions and padding for constructing the word embedding matrix
    vocab_sizes = [word_vocab_size]
    emb_dims = [word_vec_size]
    pad_indices = [word_padding_idx]

    # Dimensions and padding for feature embedding matrices
    # (these have no effect if feat_vocab_sizes is empty)
    if feat_merge == "sum":
        feat_dims = [word_vec_size] * len(feat_vocab_sizes)
    elif feat_vec_size > 0:
        feat_dims = [feat_vec_size] * len(feat_vocab_sizes)
    else:
        feat_dims = [int(vocab**feat_vec_exponent) for vocab in feat_vocab_sizes]
    vocab_sizes.extend(feat_vocab_sizes)
    emb_dims.extend(feat_dims)
    pad_indices.extend(feat_padding_idx)

    # The embedding matrix look-up tables. The first look-up table
    # is for words. Subsequent ones are for features, if any exist.
    emb_params = zip(vocab_sizes, emb_dims, pad_indices)
    embeddings = [
        nn.Embedding(vocab, dim, padding_idx=pad, sparse=sparse)
        for vocab, dim, pad in emb_params
    ]
    emb_luts = Elementwise(feat_merge, embeddings)

    # The final output size of word + feature vectors. This can vary
    # from the word vector size if and only if features are defined.
    # This is the attribute you should access if you need to know
    # how big your embeddings are going to be.
    self.embedding_size = sum(emb_dims) if feat_merge == "concat" else word_vec_size

    # The sequence of operations that converts the input sequence
    # into a sequence of embeddings. At minimum this consists of
    # looking up the embeddings for each word and feature in the
    # input. Model parameters may require the sequence to contain
    # additional operations as well.
    super(Embeddings, self).__init__()
    self.make_embedding = nn.Sequential()
    self.make_embedding.add_module("emb_luts", emb_luts)

    if feat_merge == "mlp" and len(feat_vocab_sizes) > 0:
        in_dim = sum(emb_dims)
        out_dim = word_vec_size
        mlp = nn.Sequential(nn.Linear(in_dim, out_dim), nn.ReLU())
        self.make_embedding.add_module("mlp", mlp)

    self.position_encoding = position_encoding

    if self.position_encoding:
        pe = PositionalEncoding(dropout, self.embedding_size)
        self.make_embedding.add_module("pe", pe)


# Traceback (ValueError)
Traceback (most recent call last):
File "train.py", line 40, in <module>
main(opt)
File "train.py", line 27, in main
single_main(opt)
File "/home/rudra/OpenNMT-py/onmt/train_single.py", line 113, in main
optim = build_optim(model, opt, checkpoint)
File "/home/rudra/OpenNMT-py/onmt/utils/optimizers.py", line 62, in build_optim
optim.optimizer.load_state_dict(saved_optimizer_state_dict)
File "/home/rudra/miniconda3/envs/py36/lib/python3.6/site-packages/torch/optim/optimizer.py", line         107, in load_state_dict
raise ValueError("loaded state dict contains a parameter group "
ValueError: loaded state dict contains a parameter group that doesn't match the size of optimizer's group

# Fixed code
def __init__(
    self,
    word_vec_size,
    word_vocab_size,
    word_padding_idx,
    position_encoding=False,
    feat_merge="concat",
    feat_vec_exponent=0.7,
    feat_vec_size=-1,
    feat_padding_idx=[],
    feat_vocab_sizes=[],
    dropout=0,
    sparse=False,
    fix_word_vecs=False,
):
    if feat_padding_idx is None:
        feat_padding_idx = []
    self.word_padding_idx = word_padding_idx

    self.word_vec_size = word_vec_size

    # Dimensions and padding for constructing the word embedding matrix
    vocab_sizes = [word_vocab_size]
    emb_dims = [word_vec_size]
    pad_indices = [word_padding_idx]

    # Dimensions and padding for feature embedding matrices
    # (these have no effect if feat_vocab_sizes is empty)
    if feat_merge == "sum":
        feat_dims = [word_vec_size] * len(feat_vocab_sizes)
    elif feat_vec_size > 0:
        feat_dims = [feat_vec_size] * len(feat_vocab_sizes)
    else:
        feat_dims = [int(vocab**feat_vec_exponent) for vocab in feat_vocab_sizes]
    vocab_sizes.extend(feat_vocab_sizes)
    emb_dims.extend(feat_dims)
    pad_indices.extend(feat_padding_idx)

    # The embedding matrix look-up tables. The first look-up table
    # is for words. Subsequent ones are for features, if any exist.
    emb_params = zip(vocab_sizes, emb_dims, pad_indices)
    embeddings = [
        nn.Embedding(vocab, dim, padding_idx=pad, sparse=sparse)
        for vocab, dim, pad in emb_params
    ]
    emb_luts = Elementwise(feat_merge, embeddings)

    # The final output size of word + feature vectors. This can vary
    # from the word vector size if and only if features are defined.
    # This is the attribute you should access if you need to know
    # how big your embeddings are going to be.
    self.embedding_size = sum(emb_dims) if feat_merge == "concat" else word_vec_size

    # The sequence of operations that converts the input sequence
    # into a sequence of embeddings. At minimum this consists of
    # looking up the embeddings for each word and feature in the
    # input. Model parameters may require the sequence to contain
    # additional operations as well.
    super(Embeddings, self).__init__()
    self.make_embedding = nn.Sequential()
    self.make_embedding.add_module("emb_luts", emb_luts)

    if feat_merge == "mlp" and len(feat_vocab_sizes) > 0:
        in_dim = sum(emb_dims)
        out_dim = word_vec_size
        mlp = nn.Sequential(nn.Linear(in_dim, out_dim), nn.ReLU())
        self.make_embedding.add_module("mlp", mlp)

    self.position_encoding = position_encoding

    if self.position_encoding:
        pe = PositionalEncoding(dropout, self.embedding_size)
        self.make_embedding.add_module("pe", pe)

    if fix_word_vecs:
        self.word_lut.weight.requires_grad = False