{ "cells": [ { "cell_type": "markdown", "id": "82d152bf", "metadata": { "papermill": { "duration": 0.007271, "end_time": "2024-11-27T10:40:39.115477", "exception": false, "start_time": "2024-11-27T10:40:39.108206", "status": "completed" }, "tags": [] }, "source": [ "# LR scheduling" ] }, { "cell_type": "code", "execution_count": 1, "id": "e84b0f26", "metadata": { "execution": { "iopub.execute_input": "2024-11-27T10:40:39.130563Z", "iopub.status.busy": "2024-11-27T10:40:39.130399Z", "iopub.status.idle": "2024-11-27T10:40:42.047581Z", "shell.execute_reply": "2024-11-27T10:40:42.047231Z" }, "papermill": { "duration": 2.927674, "end_time": "2024-11-27T10:40:42.050145", "exception": false, "start_time": "2024-11-27T10:40:39.122471", "status": "completed" }, "tags": [ "remove-cell" ] }, "outputs": [], "source": [ "from chapter import *" ] }, { "cell_type": "markdown", "id": "3bddf1e0", "metadata": { "papermill": { "duration": 0.001685, "end_time": "2024-11-27T10:40:42.054569", "exception": false, "start_time": "2024-11-27T10:40:42.052884", "status": "completed" }, "tags": [] }, "source": [ "Training the model with [one-cycle LR](https://pytorch.org/docs/stable/generated/torch.optim.lr_scheduler.OneCycleLR.html) schedule {cite}`super-convergence-resnet`. The one-cycle policy anneals the learning rate from an base learninge rate to a set maximum learning rate, and then, from that maximum learning rate, to a minimum learning rate much lower than the base learninge rate. Momentum is also annealed inversely to the learning rate which is necessary for stability." ] }, { "cell_type": "code", "execution_count": 2, "id": "86b1365d", "metadata": { "execution": { "iopub.execute_input": "2024-11-27T10:40:42.059148Z", "iopub.status.busy": "2024-11-27T10:40:42.058862Z", "iopub.status.idle": "2024-11-27T10:40:42.125789Z", "shell.execute_reply": "2024-11-27T10:40:42.125473Z" }, "papermill": { "duration": 0.07076, "end_time": "2024-11-27T10:40:42.127128", "exception": false, "start_time": "2024-11-27T10:40:42.056368", "status": "completed" }, "tags": [ "remove-input" ] }, "outputs": [ { "data": { "text/html": [ "
from torch.optim.lr_scheduler import OneCycleLR\n",
       "\n",
       "class SchedulerStatsCallback:\n",
       "    def __init__(self, optim):\n",
       "        self.lr = []\n",
       "        self.momentum = []\n",
       "        self.optim = optim\n",
       "\n",
       "    def __call__(self):\n",
       "        self.lr.append(self.optim.param_groups[0]["lr"])\n",
       "        self.momentum.append(self.optim.param_groups[0]["betas"][0])\n",
       "\n",
       "epochs = 3\n",
       "model = mnist_model().to(DEVICE)\n",
       "loss_fn = F.cross_entropy\n",
       "optim = torch.optim.AdamW(model.parameters(), lr=0.001)\n",
       "scheduler = OneCycleLR(optim, max_lr=0.01, steps_per_epoch=len(dl_train), epochs=epochs)\n",
       "scheduler_stats = SchedulerStatsCallback(optim)\n",
       "trainer = Trainer(model, optim, loss_fn, scheduler, callbacks=[scheduler_stats])\n",
       "
\n" ], "text/latex": [ "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", "\\PY{k+kn}{from} \\PY{n+nn}{torch}\\PY{n+nn}{.}\\PY{n+nn}{optim}\\PY{n+nn}{.}\\PY{n+nn}{lr\\PYZus{}scheduler} \\PY{k+kn}{import} \\PY{n}{OneCycleLR}\n", "\n", "\\PY{k}{class} \\PY{n+nc}{SchedulerStatsCallback}\\PY{p}{:}\n", " \\PY{k}{def} \\PY{n+nf+fm}{\\PYZus{}\\PYZus{}init\\PYZus{}\\PYZus{}}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{,} \\PY{n}{optim}\\PY{p}{)}\\PY{p}{:}\n", " \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{lr} \\PY{o}{=} \\PY{p}{[}\\PY{p}{]}\n", " \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{momentum} \\PY{o}{=} \\PY{p}{[}\\PY{p}{]}\n", " \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{optim} \\PY{o}{=} \\PY{n}{optim}\n", "\n", " \\PY{k}{def} \\PY{n+nf+fm}{\\PYZus{}\\PYZus{}call\\PYZus{}\\PYZus{}}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{)}\\PY{p}{:}\n", " \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{lr}\\PY{o}{.}\\PY{n}{append}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{optim}\\PY{o}{.}\\PY{n}{param\\PYZus{}groups}\\PY{p}{[}\\PY{l+m+mi}{0}\\PY{p}{]}\\PY{p}{[}\\PY{l+s+s2}{\\PYZdq{}}\\PY{l+s+s2}{lr}\\PY{l+s+s2}{\\PYZdq{}}\\PY{p}{]}\\PY{p}{)}\n", " \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{momentum}\\PY{o}{.}\\PY{n}{append}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{optim}\\PY{o}{.}\\PY{n}{param\\PYZus{}groups}\\PY{p}{[}\\PY{l+m+mi}{0}\\PY{p}{]}\\PY{p}{[}\\PY{l+s+s2}{\\PYZdq{}}\\PY{l+s+s2}{betas}\\PY{l+s+s2}{\\PYZdq{}}\\PY{p}{]}\\PY{p}{[}\\PY{l+m+mi}{0}\\PY{p}{]}\\PY{p}{)}\n", "\n", "\\PY{n}{epochs} \\PY{o}{=} \\PY{l+m+mi}{3}\n", "\\PY{n}{model} \\PY{o}{=} \\PY{n}{mnist\\PYZus{}model}\\PY{p}{(}\\PY{p}{)}\\PY{o}{.}\\PY{n}{to}\\PY{p}{(}\\PY{n}{DEVICE}\\PY{p}{)}\n", "\\PY{n}{loss\\PYZus{}fn} \\PY{o}{=} \\PY{n}{F}\\PY{o}{.}\\PY{n}{cross\\PYZus{}entropy}\n", "\\PY{n}{optim} \\PY{o}{=} \\PY{n}{torch}\\PY{o}{.}\\PY{n}{optim}\\PY{o}{.}\\PY{n}{AdamW}\\PY{p}{(}\\PY{n}{model}\\PY{o}{.}\\PY{n}{parameters}\\PY{p}{(}\\PY{p}{)}\\PY{p}{,} \\PY{n}{lr}\\PY{o}{=}\\PY{l+m+mf}{0.001}\\PY{p}{)}\n", "\\PY{n}{scheduler} \\PY{o}{=} \\PY{n}{OneCycleLR}\\PY{p}{(}\\PY{n}{optim}\\PY{p}{,} \\PY{n}{max\\PYZus{}lr}\\PY{o}{=}\\PY{l+m+mf}{0.01}\\PY{p}{,} \\PY{n}{steps\\PYZus{}per\\PYZus{}epoch}\\PY{o}{=}\\PY{n+nb}{len}\\PY{p}{(}\\PY{n}{dl\\PYZus{}train}\\PY{p}{)}\\PY{p}{,} \\PY{n}{epochs}\\PY{o}{=}\\PY{n}{epochs}\\PY{p}{)}\n", "\\PY{n}{scheduler\\PYZus{}stats} \\PY{o}{=} \\PY{n}{SchedulerStatsCallback}\\PY{p}{(}\\PY{n}{optim}\\PY{p}{)}\n", "\\PY{n}{trainer} \\PY{o}{=} \\PY{n}{Trainer}\\PY{p}{(}\\PY{n}{model}\\PY{p}{,} \\PY{n}{optim}\\PY{p}{,} \\PY{n}{loss\\PYZus{}fn}\\PY{p}{,} \\PY{n}{scheduler}\\PY{p}{,} \\PY{n}{callbacks}\\PY{o}{=}\\PY{p}{[}\\PY{n}{scheduler\\PYZus{}stats}\\PY{p}{]}\\PY{p}{)}\n", "\\end{Verbatim}\n" ], "text/plain": [ "from torch.optim.lr_scheduler import OneCycleLR\n", "\n", "class SchedulerStatsCallback:\n", " def __init__(self, optim):\n", " self.lr = []\n", " self.momentum = []\n", " self.optim = optim\n", "\n", " def __call__(self):\n", " self.lr.append(self.optim.param_groups[0][\"lr\"])\n", " self.momentum.append(self.optim.param_groups[0][\"betas\"][0])\n", "\n", "epochs = 3\n", "model = mnist_model().to(DEVICE)\n", "loss_fn = F.cross_entropy\n", "optim = torch.optim.AdamW(model.parameters(), lr=0.001)\n", "scheduler = OneCycleLR(optim, max_lr=0.01, steps_per_epoch=len(dl_train), epochs=epochs)\n", "scheduler_stats = SchedulerStatsCallback(optim)\n", "trainer = Trainer(model, optim, loss_fn, scheduler, callbacks=[scheduler_stats])" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%%save\n", "from torch.optim.lr_scheduler import OneCycleLR\n", "\n", "class SchedulerStatsCallback:\n", " def __init__(self, optim):\n", " self.lr = []\n", " self.momentum = []\n", " self.optim = optim\n", "\n", " def __call__(self):\n", " self.lr.append(self.optim.param_groups[0][\"lr\"])\n", " self.momentum.append(self.optim.param_groups[0][\"betas\"][0])\n", "\n", "epochs = 3\n", "model = mnist_model().to(DEVICE)\n", "loss_fn = F.cross_entropy\n", "optim = torch.optim.AdamW(model.parameters(), lr=0.001)\n", "scheduler = OneCycleLR(optim, max_lr=0.01, steps_per_epoch=len(dl_train), epochs=epochs)\n", "scheduler_stats = SchedulerStatsCallback(optim)\n", "trainer = Trainer(model, optim, loss_fn, scheduler, callbacks=[scheduler_stats])" ] }, { "cell_type": "markdown", "id": "69b358fa", "metadata": { "papermill": { "duration": 0.001721, "end_time": "2024-11-27T10:40:42.130945", "exception": false, "start_time": "2024-11-27T10:40:42.129224", "status": "completed" }, "tags": [] }, "source": [ "Run training:" ] }, { "cell_type": "code", "execution_count": 3, "id": "68929a94", "metadata": { "execution": { "iopub.execute_input": "2024-11-27T10:40:42.135185Z", "iopub.status.busy": "2024-11-27T10:40:42.134941Z", "iopub.status.idle": "2024-11-27T10:41:35.199049Z", "shell.execute_reply": "2024-11-27T10:41:35.198411Z" }, "papermill": { "duration": 53.070614, "end_time": "2024-11-27T10:41:35.203300", "exception": false, "start_time": "2024-11-27T10:40:42.132686", "status": "completed" }, "tags": [] }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "754f379b1a3147deb9370c0480e321f7", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/3 [00:00\n", "\n", "\n", " \n", " \n", " \n", " \n", " 2024-11-27T18:41:35.940779\n", " image/svg+xml\n", " \n", " \n", " Matplotlib v3.9.2, https://matplotlib.org/\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n" ], "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fig, (ax1, ax3) = plt.subplots(2, 1, figsize=(8, 4), gridspec_kw={'height_ratios': [4, 1]})\n", "\n", "AX1_COLOR = \"C0\"\n", "AX2_COLOR = \"C1\"\n", "ax1.plot(trainer.train_log[\"loss\"], color=AX1_COLOR, linewidth=1, alpha=0.6)\n", "ax1.plot(trainer.train_log[\"loss_avg\"], color=AX1_COLOR, linewidth=2)\n", "ax1.grid(axis=\"both\", linestyle=\"dotted\", alpha=0.8)\n", "ax1.set_xlabel(\"step\")\n", "\n", "ax2 = ax1.twinx()\n", "ax2.plot(trainer.train_log[\"accs\"], color=AX2_COLOR, linewidth=1, alpha=0.6)\n", "ax2.plot(trainer.train_log[\"accs_avg\"], color=AX2_COLOR, linewidth=2)\n", "\n", "ax1.set_ylabel(\"Train loss\")\n", "ax2.set_ylabel(\"Train accuracy (%)\")\n", "ax1.yaxis.label.set_color(AX1_COLOR)\n", "ax2.yaxis.label.set_color(AX2_COLOR)\n", "\n", "ax4 = ax3.twinx()\n", "ax3.plot(scheduler_stats.lr, color=\"black\", label=\"lr\", linewidth=2)\n", "ax4.plot(scheduler_stats.momentum, color=\"blue\", label=r\"$\\beta_1$\", linewidth=2)\n", "ax4.grid(linestyle=\"dotted\")\n", "ax3.set_xlabel(\"step\")\n", "ax3.set_ylabel(\"lr\")\n", "ax4.set_ylabel(r\"$\\beta_1$\")\n", "ax3.yaxis.label.set_color(\"black\")\n", "ax4.yaxis.label.set_color(\"blue\")\n", "\n", "fig.tight_layout()\n" ] }, { "cell_type": "markdown", "id": "9d4f830c", "metadata": { "papermill": { "duration": 0.007386, "end_time": "2024-11-27T10:41:36.032297", "exception": false, "start_time": "2024-11-27T10:41:36.024911", "status": "completed" }, "tags": [] }, "source": [ "**Figure.** Note peak in train loss as LR increases to `max_lr` set at initialization, and the decreasing noise as the LR decreases at the end of training.\n", "This works similar [our previous](dl/02-optim) **LR finder** which is a parameter-free method for finding a good base `lr`.\n", "\n", "The bump in learning rate occurs over a wide duration during training, \n", "so that the optimizer avoids many sharp minima. \n", "This allows the network to train with less epochs — increasing the number of \n", "epochs increases the exploration time (not just convergence time)." ] }, { "cell_type": "code", "execution_count": 5, "id": "26fe6181", "metadata": { "execution": { "iopub.execute_input": "2024-11-27T10:41:36.054301Z", "iopub.status.busy": "2024-11-27T10:41:36.053882Z", "iopub.status.idle": "2024-11-27T10:41:36.321786Z", "shell.execute_reply": "2024-11-27T10:41:36.320852Z" }, "papermill": { "duration": 0.280974, "end_time": "2024-11-27T10:41:36.324533", "exception": false, "start_time": "2024-11-27T10:41:36.043559", "status": "completed" }, "tags": [ "remove-cell" ] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "mkdir: ./artifacts/: File exists\r\n" ] } ], "source": [ "!mkdir ./artifacts/\n", "PATH = \"./artifacts/mnist_model.pkl\"\n", "torch.save(model.state_dict(), PATH)" ] }, { "cell_type": "code", "execution_count": null, "id": "4e6dff6e", "metadata": { "papermill": { "duration": 0.013253, "end_time": "2024-11-27T10:41:36.347489", "exception": false, "start_time": "2024-11-27T10:41:36.334236", "status": "completed" }, "tags": [] }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": ".venv", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.4" }, "papermill": { "default_parameters": {}, "duration": 60.948826, "end_time": "2024-11-27T10:41:39.079809", "environment_variables": {}, "exception": null, "input_path": "03bc-lr-sched.ipynb", "output_path": "03bc-lr-sched.ipynb", "parameters": {}, "start_time": "2024-11-27T10:40:38.130983", "version": "2.6.0" }, "widgets": { "application/vnd.jupyter.widget-state+json": { "state": { "377588f4564344ec8bcfd0bdb1552de7": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "3c7c16c747164b9d81c30e4ac939ccfd": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "StyleView", "background": null, "description_width": "", "font_size": null, "text_color": null } }, "54c1039cc2af48f4ba565488998c2a0f": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "61c3adbb304a477eb1c781e58e76559f": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "StyleView", "bar_color": null, "description_width": "" } }, "754f379b1a3147deb9370c0480e321f7": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_fb41097af2a74574b3413c56fd2799f1", "IPY_MODEL_f8063dd5d6ea462c8dc9028e7c081137", "IPY_MODEL_f5d97d0506eb4218bf8b16f468b26f2b" ], "layout": "IPY_MODEL_377588f4564344ec8bcfd0bdb1552de7", "tabbable": null, "tooltip": null } }, "a18242ef6c904b83821233dcd34411c7": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "eb6a4117806247399ba18358314f9bf1": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "StyleView", "background": null, "description_width": "", "font_size": null, "text_color": null } }, "f5d97d0506eb4218bf8b16f468b26f2b": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "HTMLView", "description": "", "description_allow_html": false, "layout": "IPY_MODEL_f831cdeb68304b9b84392c7792d89848", "placeholder": "\u200b", "style": "IPY_MODEL_eb6a4117806247399ba18358314f9bf1", "tabbable": null, "tooltip": null, "value": "\u20073/3\u2007[00:53<00:00,\u200717.68s/it]" } }, "f8063dd5d6ea462c8dc9028e7c081137": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "ProgressView", "bar_style": "success", "description": "", "description_allow_html": false, "layout": "IPY_MODEL_54c1039cc2af48f4ba565488998c2a0f", "max": 3.0, "min": 0.0, "orientation": "horizontal", "style": "IPY_MODEL_61c3adbb304a477eb1c781e58e76559f", "tabbable": null, "tooltip": null, "value": 3.0 } }, "f831cdeb68304b9b84392c7792d89848": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "fb41097af2a74574b3413c56fd2799f1": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "HTMLView", "description": "", "description_allow_html": false, "layout": "IPY_MODEL_a18242ef6c904b83821233dcd34411c7", "placeholder": "\u200b", "style": "IPY_MODEL_3c7c16c747164b9d81c30e4ac939ccfd", "tabbable": null, "tooltip": null, "value": "100%" } } }, "version_major": 2, "version_minor": 0 } } }, "nbformat": 4, "nbformat_minor": 5 }