Repository: flairNLP/flair

Issue:
AttributeError when use regressor.predict()
Hi,

I am getting this error when calling the predict function in regressor. 

> AttributeError                            Traceback (most recent call last)
<ipython-input-43-0bb09f97a1db> in <module>
----> 1 regressor.predict(corpus.test[0:3])
> 
> ~/anaconda3/envs/torch/lib/python3.8/site-packages/flair/models/text_regression_model.py in predict(self, sentences, mini_batch_size, embedding_storage_mode)
     67 
     68                 for (sentence, score) in zip(batch, scores.tolist()):
---> 69                     sentence.labels = [Label(value=str(score[0]))]
     70 
     71                 # clearing token embeddings to save memory
> 
> AttributeError: can't set attribute

referring to
https://github.com/flairNLP/flair/blob/4aa77cbc62720a8f0e5a595ab264f82aaaad10dc/flair/models/text_regression_model.py#L69

Should it be sentence.set_labels() here?

Thanks


Discussion:
Hi,
I received the exact same error.
@heukirne Any insights here?
Thanks
@aditya-malte , I help this project a long time ago, can't remeber this error.
Do you have the Traceback?
The traceback is exactly the same as the one mentioned by the author of this issue
`AttributeError Traceback (most recent call last)
in
----> 1 regressor.predict(corpus.test[0:3])

~/anaconda3/envs/torch/lib/python3.8/site-packages/flair/models/text_regression_model.py in predict(self, sentences, mini_batch_size, embedding_storage_mode)
67
68 for (sentence, score) in zip(batch, scores.tolist()):
---> 69 sentence.labels = [Label(value=str(score[0]))]
70
71 # clearing token embeddings to save memory

AttributeError: can't set attribute`
Also tried the solution suggested earlier in this thread by @cpuyyp . I think the issue might be that the sentence object is immutable. Trying an alternate approach where a new object gets created.
We're running in to the same issue; feel free to keep us posted @aditya-malte
Sure :)
Have you tried to run your code similarly to the regression tests?
https://github.com/flairNLP/flair/blob/master/tests/test_text_regressor.py
Yes you're right, its an error in the way the labels are set. I'll put in a PR to fix this!

Resolving patch:
diff --git a/flair/models/text_regression_model.py b/flair/models/text_regression_model.py
--- a/flair/models/text_regression_model.py
+++ b/flair/models/text_regression_model.py
@@ -6,7 +6,7 @@
 import flair.embeddings
 import torch
 import torch.nn as nn
-from typing import List, Union
+from typing import List, Union, Optional
 
 from flair.datasets import DataLoader, SentenceDataset
 from flair.training_utils import MetricRegression, Result, store_embeddings
@@ -17,12 +17,13 @@
 
 
 class TextRegressor(flair.models.TextClassifier):
-    def __init__(self, document_embeddings: flair.embeddings.DocumentEmbeddings):
+    def __init__(self, document_embeddings: flair.embeddings.DocumentEmbeddings, label_name: str = 'label'):
 
         super(TextRegressor, self).__init__(
             document_embeddings=document_embeddings,
             label_dictionary=flair.data.Dictionary(),
             multi_label=False,
+            label_type=label_name,
         )
 
         log.info("Using REGRESSION - experimental")
@@ -42,12 +43,16 @@ def _labels_to_indices(self, sentences: List[Sentence]):
         return vec
 
     def predict(
-        self,
-        sentences: Union[Sentence, List[Sentence]],
-        mini_batch_size: int = 32,
-        embedding_storage_mode="none",
+            self,
+            sentences: Union[Sentence, List[Sentence]],
+            label_name: Optional[str] = None,
+            mini_batch_size: int = 32,
+            embedding_storage_mode="none",
     ) -> List[Sentence]:
 
+        if label_name == None:
+            label_name = self.label_type if self.label_type is not None else 'label'
+
         with torch.no_grad():
             if type(sentences) is Sentence:
                 sentences = [sentences]
@@ -58,7 +63,7 @@ def predict(
             store_embeddings(filtered_sentences, "none")
 
             batches = [
-                filtered_sentences[x : x + mini_batch_size]
+                filtered_sentences[x: x + mini_batch_size]
                 for x in range(0, len(filtered_sentences), mini_batch_size)
             ]
 
@@ -66,7 +71,7 @@ def predict(
                 scores = self.forward(batch)
 
                 for (sentence, score) in zip(batch, scores.tolist()):
-                    sentence.labels = [Label(value=str(score[0]))]
+                    sentence.set_label(label_name, value=str(score[0]))
 
                 # clearing token embeddings to save memory
                 store_embeddings(batch, storage_mode=embedding_storage_mode)
@@ -74,7 +79,7 @@ def predict(
             return sentences
 
     def _calculate_loss(
-        self, scores: torch.tensor, sentences: List[Sentence]
+            self, scores: torch.tensor, sentences: List[Sentence]
     ) -> torch.tensor:
         """
         Calculates the loss.
@@ -85,7 +90,7 @@ def _calculate_loss(
         return self.loss_function(scores.squeeze(1), self._labels_to_indices(sentences))
 
     def forward_labels_and_loss(
-        self, sentences: Union[Sentence, List[Sentence]]
+            self, sentences: Union[Sentence, List[Sentence]]
     ) -> (List[List[float]], torch.tensor):
 
         scores = self.forward(sentences)
@@ -93,12 +98,12 @@ def forward_labels_and_loss(
         return scores, loss
 
     def evaluate(
-        self,
-        sentences: Union[List[DataPoint], Dataset],
-        out_path: Union[str, Path] = None,
-        embedding_storage_mode: str = "none",
-        mini_batch_size: int = 32,
-        num_workers: int = 8,
+            self,
+            sentences: Union[List[DataPoint], Dataset],
+            out_path: Union[str, Path] = None,
+            embedding_storage_mode: str = "none",
+            mini_batch_size: int = 32,
+            num_workers: int = 8,
     ) -> (Result, float):
 
         # read Dataset into data loader (if list of sentences passed, make Dataset first)
@@ -139,7 +144,7 @@ def evaluate(
                 metric.pred.extend(results)
 
                 for sentence, prediction, true_value in zip(
-                    batch, results, true_values
+                        batch, results, true_values
                 ):
                     eval_line = "{}\t{}\t{}\n".format(
                         sentence.to_original_text(), true_value, prediction
@@ -175,13 +180,16 @@ def _get_state_dict(self):
         model_state = {
             "state_dict": self.state_dict(),
             "document_embeddings": self.document_embeddings,
+            "label_name": self.label_type,
         }
         return model_state
 
     @staticmethod
     def _init_model_with_state_dict(state):
 
-        model = TextRegressor(document_embeddings=state["document_embeddings"])
+        label_name = state["label_name"] if "label_name" in state.keys() else None
+
+        model = TextRegressor(document_embeddings=state["document_embeddings"], label_name=label_name)
 
         model.load_state_dict(state["state_dict"])
         return model


Test patch: