We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Plotter throws error if test loss is not monitored
The Plotter method to plot training curves currently throws an error (
`ValueError: 'TEST_LOSS' is not in list`) if test loss is not monitored during training. 

To reproduce:

```python
trainer: ModelTrainer = ModelTrainer(tagger, corpus)

trainer.train(
    "resources/taggers/example-ner",
    max_epochs=1,
)

plotter = Plotter()
plotter.plot_training_curves("resources/taggers/example-ner/loss.tsv")
```




--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `flair/visual/training_curves.py`
Content:
```
1 import logging
2 from collections import defaultdict
3 from pathlib import Path
4 from typing import Union, List
5 
6 import numpy as np
7 import csv
8 
9 import math
10 
11 import matplotlib.pyplot as plt
12 
13 
14 # header for 'weights.txt'
15 WEIGHT_NAME = 1
16 WEIGHT_NUMBER = 2
17 WEIGHT_VALUE = 3
18 
19 log = logging.getLogger("flair")
20 
21 
22 class Plotter(object):
23     """
24     Plots training parameters (loss, f-score, and accuracy) and training weights over time.
25     Input files are the output files 'loss.tsv' and 'weights.txt' from training either a sequence tagger or text
26     classification model.
27     """
28 
29     @staticmethod
30     def _extract_evaluation_data(file_name: Path, score: str = "F1") -> dict:
31         training_curves = {
32             "train": {"loss": [], "score": []},
33             "test": {"loss": [], "score": []},
34             "dev": {"loss": [], "score": []},
35         }
36 
37         with open(file_name, "r") as tsvin:
38             tsvin = csv.reader(tsvin, delimiter="\t")
39 
40             # determine the column index of loss, f-score and accuracy for train, dev and test split
41             row = next(tsvin, None)
42 
43             score = score.upper()
44 
45             if f"TEST_{score}" not in row:
46                 log.warning("-" * 100)
47                 log.warning(f"WARNING: No {score} found for test split in this data.")
48                 log.warning(
49                     f"Are you sure you want to plot {score} and not another value?"
50                 )
51                 log.warning("-" * 100)
52 
53             TRAIN_SCORE = (
54                 row.index(f"TRAIN_{score}") if f"TRAIN_{score}" in row else None
55             )
56             DEV_SCORE = row.index(f"DEV_{score}") if f"DEV_{score}" in row else None
57             TEST_SCORE = row.index(f"TEST_{score}")
58 
59             # then get all relevant values from the tsv
60             for row in tsvin:
61 
62                 if TRAIN_SCORE is not None:
63                     if row[TRAIN_SCORE] != "_":
64                         training_curves["train"]["score"].append(
65                             float(row[TRAIN_SCORE])
66                         )
67 
68                 if DEV_SCORE is not None:
69                     if row[DEV_SCORE] != "_":
70                         training_curves["dev"]["score"].append(float(row[DEV_SCORE]))
71 
72                 if row[TEST_SCORE] != "_":
73                     training_curves["test"]["score"].append(float(row[TEST_SCORE]))
74 
75         return training_curves
76 
77     @staticmethod
78     def _extract_weight_data(file_name: Path) -> dict:
79         weights = defaultdict(lambda: defaultdict(lambda: list()))
80 
81         with open(file_name, "r") as tsvin:
82             tsvin = csv.reader(tsvin, delimiter="\t")
83 
84             for row in tsvin:
85                 name = row[WEIGHT_NAME]
86                 param = row[WEIGHT_NUMBER]
87                 value = float(row[WEIGHT_VALUE])
88 
89                 weights[name][param].append(value)
90 
91         return weights
92 
93     @staticmethod
94     def _extract_learning_rate(file_name: Path):
95         lrs = []
96         losses = []
97 
98         with open(file_name, "r") as tsvin:
99             tsvin = csv.reader(tsvin, delimiter="\t")
100             row = next(tsvin, None)
101             LEARNING_RATE = row.index("LEARNING_RATE")
102             TRAIN_LOSS = row.index("TRAIN_LOSS")
103 
104             # then get all relevant values from the tsv
105             for row in tsvin:
106                 if row[TRAIN_LOSS] != "_":
107                     losses.append(float(row[TRAIN_LOSS]))
108                 if row[LEARNING_RATE] != "_":
109                     lrs.append(float(row[LEARNING_RATE]))
110 
111         return lrs, losses
112 
113     def plot_weights(self, file_name: Union[str, Path]):
114         if type(file_name) is str:
115             file_name = Path(file_name)
116 
117         weights = self._extract_weight_data(file_name)
118 
119         total = len(weights)
120         columns = 2
121         rows = max(2, int(math.ceil(total / columns)))
122         # print(rows)
123 
124         # figsize = (16, 16)
125         if rows != columns:
126             figsize = (8, rows + 0)
127 
128         fig = plt.figure()
129         f, axarr = plt.subplots(rows, columns, figsize=figsize)
130 
131         c = 0
132         r = 0
133         for name, values in weights.items():
134             # plot i
135             axarr[r, c].set_title(name, fontsize=6)
136             for _, v in values.items():
137                 axarr[r, c].plot(np.arange(0, len(v)), v, linewidth=0.35)
138             axarr[r, c].set_yticks([])
139             axarr[r, c].set_xticks([])
140             c += 1
141             if c == columns:
142                 c = 0
143                 r += 1
144 
145         while r != rows and c != columns:
146             axarr[r, c].set_yticks([])
147             axarr[r, c].set_xticks([])
148             c += 1
149             if c == columns:
150                 c = 0
151                 r += 1
152 
153         # save plots
154         f.subplots_adjust(hspace=0.5)
155         plt.tight_layout(pad=1.0)
156         path = file_name.parent / "weights.png"
157         plt.savefig(path, dpi=300)
158         print(
159             f"Weights plots are saved in {path}"
160         )  # to let user know the path of the save plots
161         plt.close(fig)
162 
163     def plot_training_curves(
164         self, file_name: Union[str, Path], plot_values: List[str] = ["loss", "F1"]
165     ):
166         if type(file_name) is str:
167             file_name = Path(file_name)
168 
169         fig = plt.figure(figsize=(15, 10))
170 
171         for plot_no, plot_value in enumerate(plot_values):
172 
173             training_curves = self._extract_evaluation_data(file_name, plot_value)
174 
175             plt.subplot(len(plot_values), 1, plot_no + 1)
176             if training_curves["train"]["score"]:
177                 x = np.arange(0, len(training_curves["train"]["score"]))
178                 plt.plot(
179                     x, training_curves["train"]["score"], label=f"training {plot_value}"
180                 )
181             if training_curves["dev"]["score"]:
182                 x = np.arange(0, len(training_curves["dev"]["score"]))
183                 plt.plot(
184                     x, training_curves["dev"]["score"], label=f"validation {plot_value}"
185                 )
186             if training_curves["test"]["score"]:
187                 x = np.arange(0, len(training_curves["test"]["score"]))
188                 plt.plot(
189                     x, training_curves["test"]["score"], label=f"test {plot_value}"
190                 )
191             plt.legend(bbox_to_anchor=(1.04, 0), loc="lower left", borderaxespad=0)
192             plt.ylabel(plot_value)
193             plt.xlabel("epochs")
194 
195         # save plots
196         plt.tight_layout(pad=1.0)
197         path = file_name.parent / "training.png"
198         plt.savefig(path, dpi=300)
199         print(
200             f"Loss and F1 plots are saved in {path}"
201         )  # to let user know the path of the save plots
202         plt.show(block=False)  # to have the plots displayed when user run this module
203         plt.close(fig)
204 
205     def plot_learning_rate(
206         self, file_name: Union[str, Path], skip_first: int = 10, skip_last: int = 5
207     ):
208         if type(file_name) is str:
209             file_name = Path(file_name)
210 
211         lrs, losses = self._extract_learning_rate(file_name)
212         lrs = lrs[skip_first:-skip_last] if skip_last > 0 else lrs[skip_first:]
213         losses = losses[skip_first:-skip_last] if skip_last > 0 else losses[skip_first:]
214 
215         fig, ax = plt.subplots(1, 1)
216         ax.plot(lrs, losses)
217         ax.set_ylabel("Loss")
218         ax.set_xlabel("Learning Rate")
219         ax.set_xscale("log")
220         ax.xaxis.set_major_formatter(plt.FormatStrFormatter("%.0e"))
221 
222         # plt.show()
223 
224         # save plot
225         plt.tight_layout(pad=1.0)
226         path = file_name.parent / "learning_rate.png"
227         plt.savefig(path, dpi=300)
228         print(
229             f"Learning_rate plots are saved in {path}"
230         )  # to let user know the path of the save plots
231         plt.show(block=True)  # to have the plots displayed when user run this module
232         plt.close(fig)
233
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/flair/visual/training_curves.py b/flair/visual/training_curves.py
--- a/flair/visual/training_curves.py
+++ b/flair/visual/training_curves.py
@@ -54,7 +54,7 @@
                 row.index(f"TRAIN_{score}") if f"TRAIN_{score}" in row else None
             )
             DEV_SCORE = row.index(f"DEV_{score}") if f"DEV_{score}" in row else None
-            TEST_SCORE = row.index(f"TEST_{score}")
+            TEST_SCORE = row.index(f"TEST_{score}") if f"TEST_{score}" in row else None
 
             # then get all relevant values from the tsv
             for row in tsvin:
@@ -69,8 +69,9 @@
                     if row[DEV_SCORE] != "_":
                         training_curves["dev"]["score"].append(float(row[DEV_SCORE]))
 
-                if row[TEST_SCORE] != "_":
-                    training_curves["test"]["score"].append(float(row[TEST_SCORE]))
+                if TEST_SCORE is not None:
+                    if row[TEST_SCORE] != "_":
+                        training_curves["test"]["score"].append(float(row[TEST_SCORE]))
 
         return training_curves

{"golden_diff": "diff --git a/flair/visual/training_curves.py b/flair/visual/training_curves.py\n--- a/flair/visual/training_curves.py\n+++ b/flair/visual/training_curves.py\n@@ -54,7 +54,7 @@\n                 row.index(f\"TRAIN_{score}\") if f\"TRAIN_{score}\" in row else None\n             )\n             DEV_SCORE = row.index(f\"DEV_{score}\") if f\"DEV_{score}\" in row else None\n-            TEST_SCORE = row.index(f\"TEST_{score}\")\n+            TEST_SCORE = row.index(f\"TEST_{score}\") if f\"TEST_{score}\" in row else None\n \n             # then get all relevant values from the tsv\n             for row in tsvin:\n@@ -69,8 +69,9 @@\n                     if row[DEV_SCORE] != \"_\":\n                         training_curves[\"dev\"][\"score\"].append(float(row[DEV_SCORE]))\n \n-                if row[TEST_SCORE] != \"_\":\n-                    training_curves[\"test\"][\"score\"].append(float(row[TEST_SCORE]))\n+                if TEST_SCORE is not None:\n+                    if row[TEST_SCORE] != \"_\":\n+                        training_curves[\"test\"][\"score\"].append(float(row[TEST_SCORE]))\n \n         return training_curves\n", "issue": "Plotter throws error if test loss is not monitored\nThe Plotter method to plot training curves currently throws an error (\r\n`ValueError: 'TEST_LOSS' is not in list`) if test loss is not monitored during training. \r\n\r\nTo reproduce:\r\n\r\n```python\r\ntrainer: ModelTrainer = ModelTrainer(tagger, corpus)\r\n\r\ntrainer.train(\r\n    \"resources/taggers/example-ner\",\r\n    max_epochs=1,\r\n)\r\n\r\nplotter = Plotter()\r\nplotter.plot_training_curves(\"resources/taggers/example-ner/loss.tsv\")\r\n```\r\n\r\n\r\n\n", "before_files": [{"content": "import logging\nfrom collections import defaultdict\nfrom pathlib import Path\nfrom typing import Union, List\n\nimport numpy as np\nimport csv\n\nimport math\n\nimport matplotlib.pyplot as plt\n\n\n# header for 'weights.txt'\nWEIGHT_NAME = 1\nWEIGHT_NUMBER = 2\nWEIGHT_VALUE = 3\n\nlog = logging.getLogger(\"flair\")\n\n\nclass Plotter(object):\n    \"\"\"\n    Plots training parameters (loss, f-score, and accuracy) and training weights over time.\n    Input files are the output files 'loss.tsv' and 'weights.txt' from training either a sequence tagger or text\n    classification model.\n    \"\"\"\n\n    @staticmethod\n    def _extract_evaluation_data(file_name: Path, score: str = \"F1\") -> dict:\n        training_curves = {\n            \"train\": {\"loss\": [], \"score\": []},\n            \"test\": {\"loss\": [], \"score\": []},\n            \"dev\": {\"loss\": [], \"score\": []},\n        }\n\n        with open(file_name, \"r\") as tsvin:\n            tsvin = csv.reader(tsvin, delimiter=\"\\t\")\n\n            # determine the column index of loss, f-score and accuracy for train, dev and test split\n            row = next(tsvin, None)\n\n            score = score.upper()\n\n            if f\"TEST_{score}\" not in row:\n                log.warning(\"-\" * 100)\n                log.warning(f\"WARNING: No {score} found for test split in this data.\")\n                log.warning(\n                    f\"Are you sure you want to plot {score} and not another value?\"\n                )\n                log.warning(\"-\" * 100)\n\n            TRAIN_SCORE = (\n                row.index(f\"TRAIN_{score}\") if f\"TRAIN_{score}\" in row else None\n            )\n            DEV_SCORE = row.index(f\"DEV_{score}\") if f\"DEV_{score}\" in row else None\n            TEST_SCORE = row.index(f\"TEST_{score}\")\n\n            # then get all relevant values from the tsv\n            for row in tsvin:\n\n                if TRAIN_SCORE is not None:\n                    if row[TRAIN_SCORE] != \"_\":\n                        training_curves[\"train\"][\"score\"].append(\n                            float(row[TRAIN_SCORE])\n                        )\n\n                if DEV_SCORE is not None:\n                    if row[DEV_SCORE] != \"_\":\n                        training_curves[\"dev\"][\"score\"].append(float(row[DEV_SCORE]))\n\n                if row[TEST_SCORE] != \"_\":\n                    training_curves[\"test\"][\"score\"].append(float(row[TEST_SCORE]))\n\n        return training_curves\n\n    @staticmethod\n    def _extract_weight_data(file_name: Path) -> dict:\n        weights = defaultdict(lambda: defaultdict(lambda: list()))\n\n        with open(file_name, \"r\") as tsvin:\n            tsvin = csv.reader(tsvin, delimiter=\"\\t\")\n\n            for row in tsvin:\n                name = row[WEIGHT_NAME]\n                param = row[WEIGHT_NUMBER]\n                value = float(row[WEIGHT_VALUE])\n\n                weights[name][param].append(value)\n\n        return weights\n\n    @staticmethod\n    def _extract_learning_rate(file_name: Path):\n        lrs = []\n        losses = []\n\n        with open(file_name, \"r\") as tsvin:\n            tsvin = csv.reader(tsvin, delimiter=\"\\t\")\n            row = next(tsvin, None)\n            LEARNING_RATE = row.index(\"LEARNING_RATE\")\n            TRAIN_LOSS = row.index(\"TRAIN_LOSS\")\n\n            # then get all relevant values from the tsv\n            for row in tsvin:\n                if row[TRAIN_LOSS] != \"_\":\n                    losses.append(float(row[TRAIN_LOSS]))\n                if row[LEARNING_RATE] != \"_\":\n                    lrs.append(float(row[LEARNING_RATE]))\n\n        return lrs, losses\n\n    def plot_weights(self, file_name: Union[str, Path]):\n        if type(file_name) is str:\n            file_name = Path(file_name)\n\n        weights = self._extract_weight_data(file_name)\n\n        total = len(weights)\n        columns = 2\n        rows = max(2, int(math.ceil(total / columns)))\n        # print(rows)\n\n        # figsize = (16, 16)\n        if rows != columns:\n            figsize = (8, rows + 0)\n\n        fig = plt.figure()\n        f, axarr = plt.subplots(rows, columns, figsize=figsize)\n\n        c = 0\n        r = 0\n        for name, values in weights.items():\n            # plot i\n            axarr[r, c].set_title(name, fontsize=6)\n            for _, v in values.items():\n                axarr[r, c].plot(np.arange(0, len(v)), v, linewidth=0.35)\n            axarr[r, c].set_yticks([])\n            axarr[r, c].set_xticks([])\n            c += 1\n            if c == columns:\n                c = 0\n                r += 1\n\n        while r != rows and c != columns:\n            axarr[r, c].set_yticks([])\n            axarr[r, c].set_xticks([])\n            c += 1\n            if c == columns:\n                c = 0\n                r += 1\n\n        # save plots\n        f.subplots_adjust(hspace=0.5)\n        plt.tight_layout(pad=1.0)\n        path = file_name.parent / \"weights.png\"\n        plt.savefig(path, dpi=300)\n        print(\n            f\"Weights plots are saved in {path}\"\n        )  # to let user know the path of the save plots\n        plt.close(fig)\n\n    def plot_training_curves(\n        self, file_name: Union[str, Path], plot_values: List[str] = [\"loss\", \"F1\"]\n    ):\n        if type(file_name) is str:\n            file_name = Path(file_name)\n\n        fig = plt.figure(figsize=(15, 10))\n\n        for plot_no, plot_value in enumerate(plot_values):\n\n            training_curves = self._extract_evaluation_data(file_name, plot_value)\n\n            plt.subplot(len(plot_values), 1, plot_no + 1)\n            if training_curves[\"train\"][\"score\"]:\n                x = np.arange(0, len(training_curves[\"train\"][\"score\"]))\n                plt.plot(\n                    x, training_curves[\"train\"][\"score\"], label=f\"training {plot_value}\"\n                )\n            if training_curves[\"dev\"][\"score\"]:\n                x = np.arange(0, len(training_curves[\"dev\"][\"score\"]))\n                plt.plot(\n                    x, training_curves[\"dev\"][\"score\"], label=f\"validation {plot_value}\"\n                )\n            if training_curves[\"test\"][\"score\"]:\n                x = np.arange(0, len(training_curves[\"test\"][\"score\"]))\n                plt.plot(\n                    x, training_curves[\"test\"][\"score\"], label=f\"test {plot_value}\"\n                )\n            plt.legend(bbox_to_anchor=(1.04, 0), loc=\"lower left\", borderaxespad=0)\n            plt.ylabel(plot_value)\n            plt.xlabel(\"epochs\")\n\n        # save plots\n        plt.tight_layout(pad=1.0)\n        path = file_name.parent / \"training.png\"\n        plt.savefig(path, dpi=300)\n        print(\n            f\"Loss and F1 plots are saved in {path}\"\n        )  # to let user know the path of the save plots\n        plt.show(block=False)  # to have the plots displayed when user run this module\n        plt.close(fig)\n\n    def plot_learning_rate(\n        self, file_name: Union[str, Path], skip_first: int = 10, skip_last: int = 5\n    ):\n        if type(file_name) is str:\n            file_name = Path(file_name)\n\n        lrs, losses = self._extract_learning_rate(file_name)\n        lrs = lrs[skip_first:-skip_last] if skip_last > 0 else lrs[skip_first:]\n        losses = losses[skip_first:-skip_last] if skip_last > 0 else losses[skip_first:]\n\n        fig, ax = plt.subplots(1, 1)\n        ax.plot(lrs, losses)\n        ax.set_ylabel(\"Loss\")\n        ax.set_xlabel(\"Learning Rate\")\n        ax.set_xscale(\"log\")\n        ax.xaxis.set_major_formatter(plt.FormatStrFormatter(\"%.0e\"))\n\n        # plt.show()\n\n        # save plot\n        plt.tight_layout(pad=1.0)\n        path = file_name.parent / \"learning_rate.png\"\n        plt.savefig(path, dpi=300)\n        print(\n            f\"Learning_rate plots are saved in {path}\"\n        )  # to let user know the path of the save plots\n        plt.show(block=True)  # to have the plots displayed when user run this module\n        plt.close(fig)\n", "path": "flair/visual/training_curves.py"}], "after_files": [{"content": "import logging\nfrom collections import defaultdict\nfrom pathlib import Path\nfrom typing import Union, List\n\nimport numpy as np\nimport csv\n\nimport math\n\nimport matplotlib.pyplot as plt\n\n\n# header for 'weights.txt'\nWEIGHT_NAME = 1\nWEIGHT_NUMBER = 2\nWEIGHT_VALUE = 3\n\nlog = logging.getLogger(\"flair\")\n\n\nclass Plotter(object):\n    \"\"\"\n    Plots training parameters (loss, f-score, and accuracy) and training weights over time.\n    Input files are the output files 'loss.tsv' and 'weights.txt' from training either a sequence tagger or text\n    classification model.\n    \"\"\"\n\n    @staticmethod\n    def _extract_evaluation_data(file_name: Path, score: str = \"F1\") -> dict:\n        training_curves = {\n            \"train\": {\"loss\": [], \"score\": []},\n            \"test\": {\"loss\": [], \"score\": []},\n            \"dev\": {\"loss\": [], \"score\": []},\n        }\n\n        with open(file_name, \"r\") as tsvin:\n            tsvin = csv.reader(tsvin, delimiter=\"\\t\")\n\n            # determine the column index of loss, f-score and accuracy for train, dev and test split\n            row = next(tsvin, None)\n\n            score = score.upper()\n\n            if f\"TEST_{score}\" not in row:\n                log.warning(\"-\" * 100)\n                log.warning(f\"WARNING: No {score} found for test split in this data.\")\n                log.warning(\n                    f\"Are you sure you want to plot {score} and not another value?\"\n                )\n                log.warning(\"-\" * 100)\n\n            TRAIN_SCORE = (\n                row.index(f\"TRAIN_{score}\") if f\"TRAIN_{score}\" in row else None\n            )\n            DEV_SCORE = row.index(f\"DEV_{score}\") if f\"DEV_{score}\" in row else None\n            TEST_SCORE = row.index(f\"TEST_{score}\") if f\"TEST_{score}\" in row else None\n\n            # then get all relevant values from the tsv\n            for row in tsvin:\n\n                if TRAIN_SCORE is not None:\n                    if row[TRAIN_SCORE] != \"_\":\n                        training_curves[\"train\"][\"score\"].append(\n                            float(row[TRAIN_SCORE])\n                        )\n\n                if DEV_SCORE is not None:\n                    if row[DEV_SCORE] != \"_\":\n                        training_curves[\"dev\"][\"score\"].append(float(row[DEV_SCORE]))\n\n                if TEST_SCORE is not None:\n                    if row[TEST_SCORE] != \"_\":\n                        training_curves[\"test\"][\"score\"].append(float(row[TEST_SCORE]))\n\n        return training_curves\n\n    @staticmethod\n    def _extract_weight_data(file_name: Path) -> dict:\n        weights = defaultdict(lambda: defaultdict(lambda: list()))\n\n        with open(file_name, \"r\") as tsvin:\n            tsvin = csv.reader(tsvin, delimiter=\"\\t\")\n\n            for row in tsvin:\n                name = row[WEIGHT_NAME]\n                param = row[WEIGHT_NUMBER]\n                value = float(row[WEIGHT_VALUE])\n\n                weights[name][param].append(value)\n\n        return weights\n\n    @staticmethod\n    def _extract_learning_rate(file_name: Path):\n        lrs = []\n        losses = []\n\n        with open(file_name, \"r\") as tsvin:\n            tsvin = csv.reader(tsvin, delimiter=\"\\t\")\n            row = next(tsvin, None)\n            LEARNING_RATE = row.index(\"LEARNING_RATE\")\n            TRAIN_LOSS = row.index(\"TRAIN_LOSS\")\n\n            # then get all relevant values from the tsv\n            for row in tsvin:\n                if row[TRAIN_LOSS] != \"_\":\n                    losses.append(float(row[TRAIN_LOSS]))\n                if row[LEARNING_RATE] != \"_\":\n                    lrs.append(float(row[LEARNING_RATE]))\n\n        return lrs, losses\n\n    def plot_weights(self, file_name: Union[str, Path]):\n        if type(file_name) is str:\n            file_name = Path(file_name)\n\n        weights = self._extract_weight_data(file_name)\n\n        total = len(weights)\n        columns = 2\n        rows = max(2, int(math.ceil(total / columns)))\n        # print(rows)\n\n        # figsize = (16, 16)\n        if rows != columns:\n            figsize = (8, rows + 0)\n\n        fig = plt.figure()\n        f, axarr = plt.subplots(rows, columns, figsize=figsize)\n\n        c = 0\n        r = 0\n        for name, values in weights.items():\n            # plot i\n            axarr[r, c].set_title(name, fontsize=6)\n            for _, v in values.items():\n                axarr[r, c].plot(np.arange(0, len(v)), v, linewidth=0.35)\n            axarr[r, c].set_yticks([])\n            axarr[r, c].set_xticks([])\n            c += 1\n            if c == columns:\n                c = 0\n                r += 1\n\n        while r != rows and c != columns:\n            axarr[r, c].set_yticks([])\n            axarr[r, c].set_xticks([])\n            c += 1\n            if c == columns:\n                c = 0\n                r += 1\n\n        # save plots\n        f.subplots_adjust(hspace=0.5)\n        plt.tight_layout(pad=1.0)\n        path = file_name.parent / \"weights.png\"\n        plt.savefig(path, dpi=300)\n        print(\n            f\"Weights plots are saved in {path}\"\n        )  # to let user know the path of the save plots\n        plt.close(fig)\n\n    def plot_training_curves(\n        self, file_name: Union[str, Path], plot_values: List[str] = [\"loss\", \"F1\"]\n    ):\n        if type(file_name) is str:\n            file_name = Path(file_name)\n\n        fig = plt.figure(figsize=(15, 10))\n\n        for plot_no, plot_value in enumerate(plot_values):\n\n            training_curves = self._extract_evaluation_data(file_name, plot_value)\n\n            plt.subplot(len(plot_values), 1, plot_no + 1)\n            if training_curves[\"train\"][\"score\"]:\n                x = np.arange(0, len(training_curves[\"train\"][\"score\"]))\n                plt.plot(\n                    x, training_curves[\"train\"][\"score\"], label=f\"training {plot_value}\"\n                )\n            if training_curves[\"dev\"][\"score\"]:\n                x = np.arange(0, len(training_curves[\"dev\"][\"score\"]))\n                plt.plot(\n                    x, training_curves[\"dev\"][\"score\"], label=f\"validation {plot_value}\"\n                )\n            if training_curves[\"test\"][\"score\"]:\n                x = np.arange(0, len(training_curves[\"test\"][\"score\"]))\n                plt.plot(\n                    x, training_curves[\"test\"][\"score\"], label=f\"test {plot_value}\"\n                )\n            plt.legend(bbox_to_anchor=(1.04, 0), loc=\"lower left\", borderaxespad=0)\n            plt.ylabel(plot_value)\n            plt.xlabel(\"epochs\")\n\n        # save plots\n        plt.tight_layout(pad=1.0)\n        path = file_name.parent / \"training.png\"\n        plt.savefig(path, dpi=300)\n        print(\n            f\"Loss and F1 plots are saved in {path}\"\n        )  # to let user know the path of the save plots\n        plt.show(block=False)  # to have the plots displayed when user run this module\n        plt.close(fig)\n\n    def plot_learning_rate(\n        self, file_name: Union[str, Path], skip_first: int = 10, skip_last: int = 5\n    ):\n        if type(file_name) is str:\n            file_name = Path(file_name)\n\n        lrs, losses = self._extract_learning_rate(file_name)\n        lrs = lrs[skip_first:-skip_last] if skip_last > 0 else lrs[skip_first:]\n        losses = losses[skip_first:-skip_last] if skip_last > 0 else losses[skip_first:]\n\n        fig, ax = plt.subplots(1, 1)\n        ax.plot(lrs, losses)\n        ax.set_ylabel(\"Loss\")\n        ax.set_xlabel(\"Learning Rate\")\n        ax.set_xscale(\"log\")\n        ax.xaxis.set_major_formatter(plt.FormatStrFormatter(\"%.0e\"))\n\n        # plt.show()\n\n        # save plot\n        plt.tight_layout(pad=1.0)\n        path = file_name.parent / \"learning_rate.png\"\n        plt.savefig(path, dpi=300)\n        print(\n            f\"Learning_rate plots are saved in {path}\"\n        )  # to let user know the path of the save plots\n        plt.show(block=True)  # to have the plots displayed when user run this module\n        plt.close(fig)\n", "path": "flair/visual/training_curves.py"}]}