Repository: flairNLP/flair

Issue:
AttributeError: 'GRU' object has no attribute '_flat_weights_names'
There is error when loading a text classifier, 


Code:

```
from flair.models import TextClassifier

classifier = TextClassifier.load('en-sentiment')
```

Error:

```
AttributeError                            Traceback (most recent call last)
<ipython-input-4-f517a501f1cf> in <module>
----> 1 classifier = TextClassifier.load('en-sentiment')

~/Desktop/flair/flair/nn.py in load(cls, model)
     86             state = torch.load(f, map_location=flair.device)
     87 
---> 88         model = cls._init_model_with_state_dict(state)
     89 
     90         model.eval()

~/Desktop/flair/flair/models/text_classification_model.py in _init_model_with_state_dict(state)
    129             multi_label=state["multi_label"],
    130             beta=beta,
--> 131             loss_weights=weights,
    132         )
    133 

~/Desktop/flair/flair/models/text_classification_model.py in __init__(self, document_embeddings, label_dictionary, multi_label, multi_label_threshold, beta, loss_weights)
     90 
     91         # auto-spawn on GPU if available
---> 92         self.to(flair.device)
     93 
     94     def _init_weights(self):

~/.local/lib/python3.6/site-packages/torch/nn/modules/module.py in to(self, *args, **kwargs)
    423             return t.to(device, dtype if t.is_floating_point() else None, non_blocking)
    424 
--> 425         return self._apply(convert)
    426 
    427     def register_backward_hook(self, hook):

~/.local/lib/python3.6/site-packages/torch/nn/modules/module.py in _apply(self, fn)
    199     def _apply(self, fn):
    200         for module in self.children():
--> 201             module._apply(fn)
    202 
    203         def compute_should_use_set_data(tensor, tensor_applied):

~/.local/lib/python3.6/site-packages/torch/nn/modules/module.py in _apply(self, fn)
    199     def _apply(self, fn):
    200         for module in self.children():
--> 201             module._apply(fn)
    202 
    203         def compute_should_use_set_data(tensor, tensor_applied):

~/.local/lib/python3.6/site-packages/torch/nn/modules/rnn.py in _apply(self, fn)
    135         # Note: be v. careful before removing this, as 3rd party device types
    136         # likely rely on this behavior to properly .to() modules like LSTM.
--> 137         self._flat_weights = [getattr(self, weight) for weight in self._flat_weights_names]
    138 
    139         # Flattens params (on CUDA)

~/.local/lib/python3.6/site-packages/torch/nn/modules/module.py in __getattr__(self, name)
    574                 return modules[name]
    575         raise AttributeError("'{}' object has no attribute '{}'".format(
--> 576             type(self).__name__, name))
    577 
    578     def __setattr__(self, name, value):

AttributeError: 'GRU' object has no attribute '_flat_weights_names'

```




**Environment**
 - Ubuntu 18.04
 - Version: 0.4.4



Discussion:
It is probably fixed in master: https://github.com/flairNLP/flair/pull/1360
@carlodavid012 thanks for reporting this - the error persists even in master. I will push a fix in a moment. We will also do a release probably today so it will then also be fixed if you install the new version through pip!

Resolving patch:
diff --git a/flair/embeddings.py b/flair/embeddings.py
--- a/flair/embeddings.py
+++ b/flair/embeddings.py
@@ -2930,32 +2930,6 @@ def _add_embeddings_internal(self, sentences: Union[List[Sentence], Sentence]):
         lengths: List[int] = [len(sentence.tokens) for sentence in sentences]
         longest_token_sequence_in_batch: int = max(lengths)
 
-        # initialize zero-padded word embeddings tensor
-        # sentence_tensor = torch.zeros(
-        #     [
-        #         len(sentences),
-        #         longest_token_sequence_in_batch,
-        #         self.embeddings.embedding_length,
-        #     ],
-        #     dtype=torch.float,
-        #     device=flair.device,
-        # )
-        #
-        # for s_id, sentence in enumerate(sentences):
-        #     # fill values with word embeddings
-        #     all_embs = list()
-        #
-        #     for index_token, token in enumerate(sentence):
-        #         embs = token.get_each_embedding()
-        #         if not all_embs:
-        #             all_embs = [list() for _ in range(len(embs))]
-        #         for index_emb, emb in enumerate(embs):
-        #             all_embs[index_emb].append(emb)
-        #
-        #     concat_word_emb = [torch.stack(embs) for embs in all_embs]
-        #     concat_sentence_emb = torch.cat(concat_word_emb, dim=1)
-        #     sentence_tensor[s_id][: len(sentence)] = concat_sentence_emb
-
         pre_allocated_zero_tensor = torch.zeros(
             self.embeddings.embedding_length * longest_token_sequence_in_batch,
             dtype=torch.float,
@@ -3023,6 +2997,40 @@ def _add_embeddings_internal(self, sentences: Union[List[Sentence], Sentence]):
             sentence = sentences[sentence_no]
             sentence.set_embedding(self.name, embedding)
 
+    def _apply(self, fn):
+        major, minor, build, *_ = (int(info)
+                                for info in torch.__version__.split('.'))
+
+        # fixed RNN change format for torch 1.4.0
+        if major >= 1 and minor >= 4:
+            for child_module in self.children():
+                if isinstance(child_module, torch.nn.RNNBase):
+                    _flat_weights_names = []
+                    num_direction = None
+
+                    if child_module.__dict__["bidirectional"]:
+                        num_direction = 2
+                    else:
+                        num_direction = 1
+                    for layer in range(child_module.__dict__["num_layers"]):
+                        for direction in range(num_direction):
+                            suffix = "_reverse" if direction == 1 else ""
+                            param_names = ["weight_ih_l{}{}", "weight_hh_l{}{}"]
+                            if child_module.__dict__["bias"]:
+                                param_names += ["bias_ih_l{}{}", "bias_hh_l{}{}"]
+                            param_names = [
+                                x.format(layer, suffix) for x in param_names
+                            ]
+                            _flat_weights_names.extend(param_names)
+
+                    setattr(child_module, "_flat_weights_names",
+                            _flat_weights_names)
+
+                child_module._apply(fn)
+
+        else:
+            super()._apply(fn)
+
 
 @deprecated(
     version="0.4",


Test patch: