diff --git a/MindEarth/applications/nowcasting/Nowcastnet/Nowcastnet.ipynb b/MindEarth/applications/nowcasting/Nowcastnet/Nowcastnet.ipynb index c62b4852df9c829621cc19f5634bba8388a60bb7..2709c6515a24bc81832ac88230e60cd9c9a73fcb 100644 --- a/MindEarth/applications/nowcasting/Nowcastnet/Nowcastnet.ipynb +++ b/MindEarth/applications/nowcasting/Nowcastnet/Nowcastnet.ipynb @@ -6,7 +6,7 @@ "collapsed": false }, "source": [ - "# NowcastNet: 融入物理机制的生成式短临降水预报模型" + "# NowcastNet: Physics-based generative model for extreme precipitation nowcasting" ] }, { @@ -15,11 +15,12 @@ "collapsed": false }, "source": [ - "## 概述\n", + "## Overview\n", "\n", - "NowcastNet是由清华大学龙明盛老师团队开发的一个基于雷达数据的短临降水预报模型。 它提供了0-3h的短临降水预报结果,空间分辨率为1km左右。\n", - "该模型主要分为evolution和generation两大模块,其中evolution模块融入了物理机制,给出一个粗糙的预测结果。接着,generation模块在此\n", - "基础上生成精细化的结果,从而得到最终的降水预报。模型框架图入下图所示(图片来源于论文 [Skilful nowcasting of extreme precipitation with NowcastNet](https://www.nature.com/articles/s41586-023-06184-4))\n", + "NowcastNet is proposed by Long Mingsheng. It is a nonlinear nowcasting model for\n", + "extreme precipitation with lead times of up to 3h. It includes a stochastic generative network and a deterministic\n", + "evolution network. The evolution network yields physically plausible predictions for advective features at a scale of\n", + "20km. The generative network generates convective details present in the radar observations.More information can be found in [paper](https://www.nature.com/articles/s41586-023-06184-4). The architecture of the Nowcastnet is shown below.\n", "\n", "![nowcastnet](images/nowcastnet.png)" ] @@ -32,13 +33,13 @@ "source": [ "## NowcastNet\n", "\n", - "1. Evolution network:融入物理机制,以历史的$x_{-T:0}$为输入,通过U-Net预测动量$v_{1:T}$和残差$s_{1:T}$,再经过evolution operator得到预测$x_{1:T}^{''}$。形式如下:\n", + "1. Evolution network:a motion decoder for learning motion fields $v_{1:T}$ and an intensity decoder for learning intensity residuals $s_{1:T}$. Then, evolution operator uses $v_{1:T}$ and $s_{1:T}$ to predict $x_{1:T}^{''}$. The formalization is shown below.\n", "\n", "$$\n", "x_{1:T}^{''} = Evolution(x_{-T:0})\n", "$$\n", "\n", - "2. Nowcast encoder & decoder:采用[Semantic Image Synthesis with Spatially-Adaptive Normalization](https://openaccess.thecvf.com/content_CVPR_2019/papers/Park_Semantic_Image_Synthesis_With_Spatially-Adaptive_Normalization_CVPR_2019_paper.pdf)架构把Evolution network的输出$x_{1:T}^{''}$做为conditioning进行GAN训练。" + "2. Nowcast encoder & decoder:It uses [Semantic Image Synthesis with Spatially-Adaptive Normalization](https://openaccess.thecvf.com/content_CVPR_2019/papers/Park_Semantic_Image_Synthesis_With_Spatially-Adaptive_Normalization_CVPR_2019_paper.pdf) to model the relation between physics-conditioning$x_{1:T}^{''}$and outputs." ] }, { @@ -47,15 +48,15 @@ "collapsed": false }, "source": [ - "## 技术路径\n", + "## Technology path\n", "\n", - "MindSpore Earth求解该问题的具体流程如下:\n", + "MindSpore Earth solves the problem as follows:\n", "\n", - "1. 创建数据集\n", - "2. 模型构建\n", - "3. 损失函数\n", - "4. 模型训练\n", - "5. 模型评估与可视化" + "1. Data Construction.\n", + "2. Model Construction.\n", + "3. Loss function.\n", + "4. Model Training.\n", + "5. Model Evaluation and Visualization." ] }, { @@ -64,7 +65,7 @@ "collapsed": false }, "source": [ - "训练和测试所用的数据集可以在: [Nowcastnet/dataset]() 下载" + "Download the training and test dataset: [Nowcastnet/dataset]()." ] }, { @@ -90,11 +91,11 @@ ], "source": [ "import random\n", + "import os\n", "\n", - "import matplotlib.pyplot as plt\n", "import mindspore as ms\n", "import numpy as np\n", - "from mindspore import context, nn, amp, set_seed\n", + "from mindspore import context, nn, set_seed\n", "from mindspore.train.serialization import load_checkpoint, load_param_into_net" ] }, @@ -114,10 +115,10 @@ "from src import EvolutionTrainer, GenerationTrainer, GenerateLoss, DiscriminatorLoss, EvolutionLoss\n", "from src import EvolutionPredictor, GenerationPredictor\n", "from src import RadarData, NowcastDataset\n", + "from src import init_generation_model\n", "from src.evolution import EvolutionNet\n", - "from src.generator import GenerationNet\n", - "from src.discriminator import TemporalDiscriminator\n", - "from src.visual import change_alpha\n", + "from src.visual import plt_img\n", + "from mindearth.utils import make_dir\n", "from mindearth.utils.tools import load_yaml_config" ] }, @@ -151,7 +152,9 @@ "outputs": [], "source": [ "config = load_yaml_config(\"./configs/Nowcastnet.yaml\")\n", - "context.set_context(mode=context.GRAPH_MODE, device_target=\"Ascend\", device_id=1)" + "make_dir(os.path.join(config['summary'][\"summary_dir\"], \"img\"))\n", + "context.set_context(mode=context.GRAPH_MODE, device_target=\"Ascend\", device_id=1)\n", + "logger = get_logger(config)" ] }, { @@ -160,11 +163,11 @@ "collapsed": false }, "source": [ - "## 创建数据集\n", + "## Data Construction\n", "\n", - "在[dataset]()路径下,下载训练数据集,验证数据集到`./dataset`目录,修改`./configs/Nowcastnet.yaml`配置文件中的`root_dir`。\n", + "Download the statistic, training and validation dataset from [dataset]() to `./dataset`. Modify the parameter of `root_dir` in the `./configs/Nowcastnet.yaml`, which set the directory for dataset.\n", "\n", - "`./dataset`中的目录结构如下所示:\n", + "The `./dataset` is hosted with the following directory structure:\n", "\n", "```markdown\n", "├── train\n", @@ -530,14 +533,16 @@ } ], "source": [ - "logger = get_logger(config)\n", "config[\"model\"][\"module_name\"] = 'evolution'\n", "config[\"data\"][\"batch_size\"] = 4\n", "config[\"summary\"][\"eval_interval\"] = 1\n", "config[\"summary\"][\"visual\"] = False\n", "train_params = config.get(\"train\")\n", "summary_params = config.get(\"summary\")\n", - "evo_model = EvolutionNet(config)\n", + "evo_model = EvolutionNet(config.get('data').get(\"t_in\", 9),\n", + " config.get('data').get(\"t_out\", 20),\n", + " config.get('data').get(\"h_size\", 512),\n", + " config.get('data').get(\"w_size\", 512))\n", "evo_model.set_train()" ] }, @@ -547,7 +552,7 @@ "collapsed": false }, "source": [ - "### 模型训练" + "### Model Training" ] }, { @@ -2733,9 +2738,9 @@ "collapsed": false }, "source": [ - "### evolution评估和可视化\n", + "### Evaluation and Visualization\n", "\n", - "完成训练后,我们使用ckpt进行推理,下述展示了推理的可视化图片\n" + "After training, we use the checkpoint for inference. The visualization of predictions, ground truth and their error is shown below.\n" ] }, { @@ -2760,7 +2765,7 @@ "source": [ "config[\"data\"][\"batch_size\"] = 1\n", "config[\"summary\"][\"visual\"] = True\n", - "params = load_checkpoint('./summary/ckpt/evolution-3_200.ckpt')\n", + "params = load_checkpoint('./summary/ckpt/evolution_1-15_380.ckpt')\n", "evo_model.set_train(False)\n", "load_param_into_net(evo_model, params)\n", "evo_inference = EvolutionPredictor(config, evo_model, logger)" @@ -2777,83 +2782,6 @@ "collapsed": false }, "outputs": [], - "source": [ - "def plt_img(field, label, idx, plot_evo=False, evo=None, interval=10, fig_name=\"\", vmin=1, vmax=40, cmap=\"viridis\"):\n", - " if plot_evo:\n", - " _, axs = plt.subplots(3, 3)\n", - " else:\n", - " _, axs = plt.subplots(2, 3)\n", - " axs[0][0].set_axis_off()\n", - " axs[0][1].set_axis_off()\n", - " axs[0][2].set_axis_off()\n", - " axs[1][0].set_axis_off()\n", - " axs[1][1].set_axis_off()\n", - " axs[1][2].set_axis_off()\n", - " alpha = change_alpha(label[idx[0]])\n", - " _ = axs[0][0].imshow(label[idx[0]], alpha=alpha, vmin=vmin, vmax=vmax, cmap=cmap)\n", - " axs[0][0].set_title(f\"label {idx[0] * interval + interval} min\")\n", - " alpha = change_alpha(label[idx[1]])\n", - " _ = axs[0][1].imshow(label[idx[1]], alpha=alpha, vmin=vmin, vmax=vmax, cmap=cmap)\n", - " axs[0][1].set_title(f\"label {idx[1] * interval + interval} min\")\n", - " alpha = change_alpha(label[idx[2]])\n", - " _ = axs[0][2].imshow(label[idx[2]], alpha=alpha, vmin=vmin, vmax=vmax, cmap=cmap)\n", - " axs[0][2].set_title(f\"label {idx[2] * interval + interval} min\")\n", - " alpha = change_alpha(field[idx[0]])\n", - " _ = axs[1][0].imshow(field[idx[0]], alpha=alpha, vmin=vmin, vmax=vmax, cmap=cmap)\n", - " axs[1][0].set_title(f\"pred {idx[0] * interval + interval} min\")\n", - " alpha = change_alpha(field[idx[1]])\n", - " _ = axs[1][1].imshow(field[idx[1]], alpha=alpha, vmin=vmin, vmax=vmax, cmap=cmap)\n", - " axs[1][1].set_title(f\"pred {idx[1] * interval + interval} min\")\n", - " alpha = change_alpha(field[idx[2]])\n", - " _ = axs[1][2].imshow(field[idx[2]], alpha=alpha, vmin=vmin, vmax=vmax, cmap=cmap)\n", - " axs[1][2].set_title(f\"pred {idx[2] * interval + interval} min\")\n", - " if plot_evo:\n", - " axs[2][0].set_axis_off()\n", - " axs[2][1].set_axis_off()\n", - " axs[2][2].set_axis_off()\n", - " alpha = change_alpha(evo[idx[0]])\n", - " _ = axs[2][0].imshow(evo[idx[0]], alpha=alpha, vmin=vmin, vmax=vmax, cmap=cmap)\n", - " axs[2][0].set_title(f\"evo results {idx[0] * interval + interval} min\")\n", - " alpha = change_alpha(evo[idx[1]])\n", - " _ = axs[2][1].imshow(evo[idx[1]], alpha=alpha, vmin=vmin, vmax=vmax, cmap=cmap)\n", - " axs[2][1].set_title(f\"evo results {idx[1] * interval + interval} min\")\n", - " alpha = change_alpha(evo[idx[2]])\n", - " _ = axs[2][2].imshow(evo[idx[2]], alpha=alpha, vmin=vmin, vmax=vmax, cmap=cmap)\n", - " axs[2][2].set_title(f\"evo results {idx[2] * interval + interval} min\")\n", - " plt.savefig(fig_name, dpi=180)\n", - " plt.show()\n", - " plt.close()" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": { - "ExecuteTime": { - "end_time": "2024-02-01T02:48:00.012436500Z", - "start_time": "2024-02-01T02:47:26.190772800Z" - }, - "collapsed": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\\\r" - ] - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAgMAAAGDCAYAAAC2gxMSAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAADjiElEQVR4nOzdd5gV1fnA8e/M3H7v9l7ZpS5L772LoIIIdo091sQYk5+JxtiiscUYe2IvsaJiQREBFRCk97rAsmzv9fYyM78/LmxELFjYds/neXwed3bKmcvZue+c8h5J13UdQRAEQRAiltzeBRAEQRAEoX2JYEAQBEEQIpwIBgRBEAQhwolgQBAEQRAinAgGBEEQBCHCiWBAEARBECKcCAYEQRAEIcKJYEAQBEEQIpwIBgRBEAQhwrV7MPDSSy8hSRKHDh360cfeeeedSJJEXV3dL1aeI+f8IWVlZfz+979n0qRJxMbGIkkSL7300nfuv2zZMsaMGYPNZiMxMZFLL72UmpqaX6zc32fy5MlMnjy5Ta4VSTpr3T3igw8+YNKkSURHR2O32+nXrx/PPPPMMfuJutu5ddZ6erzP2JaWFv7+978zefJkUlNTcTgcDBgwgAceeACfz3fM/sFgkLvuuoucnBzMZjN5eXk8/vjjv8St/aBDhw794HdFe2n3YKCzOnDgAK+99homk4lTTz31e/ddsWIFp5xyCikpKXzwwQc8+uijLFu2jGnTpuH3+094WZ966imeeuqpE34dofO4//77mTdvHv3792f+/Pl8+OGHXHfddQQCgaP2E3VXaC/H+4wtKSnhkUceYejQoTzzzDN8+OGHnHXWWdx5553MmjWLb2bcv+6667jvvvv4zW9+w6effsrcuXO54YYbuPfee0/0LZGWlsaaNWs47bTTTvi1fixDexegs5o4cSK1tbUAbNy4kTfeeOM7973pppvo3bs377zzDgZD+CPPzc1l3LhxvPDCC1x77bUntKz5+fkn9PxC57Jp0yZuvfVW7rvvPv70pz+1bp82bdox+4q6K7SX433G5ubmcujQIex2e+u2qVOnYrfbuemmm1i9ejXjx48HYNeuXTz//PP8/e9/56abbgLCrU/19fXcc889XHPNNcTHx5+wezKbzYwePfqEnf/n6JAtA0uXLmXOnDlkZmZisVjo2bMnV1999Xc2VZWWljJv3jyio6OJiYnhV7/6VWsl+rq33nqLMWPGYLfbcTgczJgxgy1btvykMsry8X105eXlbNiwgYsuuqj1YQowduxYevfuzXvvvfe9xx9pVvrHP/7BAw88QE5ODlarlcmTJ7Nv3z6CwSA333wz6enpxMTEMHfu3GOacL/Z1HrknA899BAPP/wwubm5OBwOxowZw9q1a4//QxCO0Rnq7hNPPIHZbOb666//3v1E3e26OkM9Pd5nrN1uPyoQOGLkyJGtZT/i/fffR9d1LrvssqP2veyyy/B6vSxevPh7r3Wki2P79u2cffbZxMTEEB8fzx/+8AdCoRAFBQXMnDmTqKgocnJyePDBB486/tu6CY6cc9euXZx//vnExMSQkpLC5ZdfTnNz83F9Br+EDhkMFBYWMmbMGP7973+zZMkSbr/9dtatW8f48eMJBoPH7D937lx69uzJO++8w5133sn777/PjBkzjtr33nvv5fzzzyc/P5/58+fz3//+F6fTyYQJE9i9e/cJu5edO3cCMHDgwGN+N3DgwNbf/5Ann3yS1atX8+STT/Lcc8+xd+9eZs+ezRVXXEFtbS0vvPACDz74IMuWLePXv/71cZ9z6dKlPPLII7z22mu43W5OPfXUNq2AXU1nqLsrV66kb9++vPvuu/Tp0wdFUcjMzOTmm28+qptA1N2uqzPU05/r888/B6Bfv36t23bu3ElSUhKpqalH7Xukjh9vnT7nnHMYNGgQ7777LldeeSX/+te/uPHGGznjjDM47bTTeO+995g6dSp//vOfWbBgwXGd88wzz6R37968++673Hzzzbz++uvceOONx3XsL0JvZy+++KIO6EVFRd/6e03T9GAwqBcXF+uA/sEHH7T+7o477tAB/cYbbzzqmNdee00H9FdffVXXdV0vKSnRDQaDfv311x+1n9Pp1FNTU/VzzjnnmHP+GBs2bNAB/cUXXzzmd0fKsmbNmmN+d9VVV+kmk+l7z11UVKQD+qBBg3RVVVu3P/LIIzqgn3766Uft//vf/14H9Obm5tZtkyZN0idNmnTMOQcMGKCHQqHW7evXr9cB/Y033vihWxb0zlt3zWazHhUVpcfFxelPPPGE/vnnn+u33nqrriiKfsEFFxxTFlF3O7fOWk+/7vuesd9m27ZtutVq1efOnXvU9unTp+t9+vT51mNMJpN+1VVXfe95j5T9n//851Hb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61+zZs2aE34dofP44osvGDlyJC0tLfznP/9hyZIl3H333VgslqP2E3VXaE/H+4y94447cDgc3HvvvSxevJg//elPfPTRRwwbNozq6uqj9n3ttdc4//zzGTFiBJ988gl33HEHL730EvPmzTvRtwPAe++9x2233dYm1/pJ9C7A4/H87HMUFRXpgP7iiy/+4L6qqrb+v91u1y+55JJv3e+mm27SjUajfujQodZtzc3NemJion7OOef83CILXUBb1l23262npaXpp512mq5p2vfuK+qu8HUd9RlbXV19zLYNGzbogH733Xe3bguFQnpaWpp+8sknH7Xva6+9pgP6okWLju8murAO0TJwpElwy5YtzJs3j+joaGJiYvjVr35FbW3tUfvm5OQwa9YsFixYwJAhQ7BYLNx1110AVFVVcfXVV5OZmYnJZCI3N5e77rqLUCh01DkqKio455xziIqKIiYmhnPPPZeqqqrjLq8sH9/H9t577zF16lS6devWui06Opp58+axcOHCY8r1TUfu9aOPPmLIkCFYrVb69u3LRx99BMBLL71E3759sdvtjBw5ko0bNx51/Lc1tR455+LFixk6dChWq5W8vDxeeOGF47on4Widqe6+/fbbVFZWctNNN/1gE7you11LZ6qn/9/eXYfXcZ2JH//OzGXUlXTFTJaZOXEccBIncRgaaNJuIaVtt9uUud3ibrf02zKkadqmYUbbsR0zyGzLsixmvkwDvz8UK3XsJk5qW5J1Ps+T54mu7sycc/1q7jsH4fTvsVlZWSe9NnfuXBRFobW1deS1rVu30tnZyfvf//4T3nvLLbfgcrl44okn3vI669atQ5Ik/vrXv/L5z3+e3NxcXC4Xq1atoru7m1AoxIc//GEyMzPJzMzk/e9//0ndD2/uJjh+zr/97W98+ctfJi8vD4/Hw2WXXXZOWt/ezHTOr/gWbrjhBm699VY+8pGPcPDgQb761a9y6NAhtm3bhtlsHnlfTU0Nhw8f5itf+QqlpaU4nU66urpYsGABsizzta99jfLycrZs2cJ//dd/0dTUxB//+EcAYrEYl112GR0dHXzve9+jqqqK5557jttuu+2M1iUWi3Hs2DFuuOGGk343Y8YMYrEYDQ0NVFVVveV59u7dyxe/+EW+/OUv4/V6+eY3v8mNN97IF7/4RdasWcN3v/tdJEni85//PNdccw2NjY3Y7fa3PednPvMZvvCFL5Cdnc3vfvc7PvCBD1BRUcGyZcv+pXpPVOMhdjds2ACApmlccMEFbN++HafTyZVXXsmPfvQj8vLyRq4jYvf8NB7i9F+1fv16NE1j6tSpI68dOHAAGI7ff2Q2m6murh75/dv50pe+xMUXX8z9999PU1MT9913H7fffjsmk4mZM2fyt7/9jd27d/OlL30Jt9vNz372s9M659KlS/nd735HMBjk85//PKtWreLw4cMoivIOav4vGu2mCcMwjK9//esGYHz6058+4fXjTTgPPvjgyGvFxcWGoijGkSNHTnjvvffea7hcLqO5ufmE1//nf/7HAIyDBw8ahmEYv/zlLw3AeOqpp05434c+9KHTbsL6R/+sCau9vd0AjO9973sn/e6vf/2rARibN29+y3MXFxcbdrvdaGtrG3ltz549BmDk5uYakUhk5PUnn3zSAIynn3565LXjn+ubz2mz2U74nGKxmJGenm7ce++9b1tf4UTjKXavuOIKAzDS0tKMz33uc8batWuNX/3qV0ZGRoZRUVExEk8ids8/4ylO3+ytugneLBgMGpMnTzYKCwuNUCg08vp3vvMdAzA6OztPOubyyy83qqqq3vK8r776qgEYq1atOuH1//iP/zAA45Of/OQJr19//fVGenr6Ca8VFxefUI/j57zqqqtOeN/DDz9sAMaWLVveskxn2pjoJjjuzjvvPOHnW2+9FZPJxKuvvnrC6zNmzDjpqeTZZ5/l4osvJi8vD1VVR/5buXIlMJwtwvAAKrfbzbXXXnvC8XfccceZrg7AWzbHns5o6VmzZpGfnz/y8+TJkwFYvnw5DofjpNebm5tP65xFRUUjP9tsNqqqqk7rWOHUxkPs6roOwG233cYPfvADLr74Yu69915+//vfU19fz1//+tcT3i9i9/wzHuL03YrH49x44400NzfzyCOP4HK5TnrPP4vb0525cs0115zw8/HYvfrqq096fWBg4LRmKrz5czreenGuY3pMdRPk5OSc8LPJZCIjI4P+/v4TXs/NzT3p2O7ubp555pkTmrr+UV9fHwD9/f1kZ2e/7bX/VT6fD0mSTio7wMDAAADp6elve543v+f4yNp/9no8Hn/bc2ZkZJz0mtVqJRaLve2xwqmNh9g9/u9+xRVXnPD6FVdcgSRJI9MGReyev8ZDnL4biUSC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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], "source": [ "data_params = config.get(\"data\")\n", "test_dataset_generator = RadarData(data_params, run_mode='test', module_name=\"evolution\")\n", @@ -2866,14 +2794,14 @@ "# data = next(test_dataset.create_dict_iterator())\n", "steps = 1\n", "for d in test_dataset.create_dict_iterator():\n", - " if steps == 5:\n", + " if steps == 6:\n", " data = d\n", " break\n", " steps += 1\n", "inputs = data['inputs']\n", "pred = evo_inference.forecast(inputs)\n", "labels = inputs[:, data_params.get(\"t_in\"):]\n", - "plt_idx = [x // data_params.get(\"time_interval\") - 1 for x in data_params.get(\"key_info_timestep\", [10, 60, 120])]\n", + "plt_idx = [x // data_params.get(\"data_frequency\") - 1 for x in data_params.get(\"key_info_timestep\", [10, 60, 120])]\n", "plt_img(field=pred[0].asnumpy(), label=labels[0].asnumpy(), idx=plt_idx, fig_name=\"./evolution_example.png\")" ] }, @@ -2892,7 +2820,7 @@ "collapsed": false }, "source": [ - "### 模型训练" + "### Model Training" ] }, { @@ -2911,14 +2839,15 @@ "config[\"data\"][\"batch_size\"] = 1\n", "config[\"summary\"][\"visual\"] = False\n", "config[\"summary\"][\"save_checkpoint_epochs\"] = 1\n", + "logger = get_logger(config)\n", "train_params = config.get(\"train\")\n", + "data_params = config.get(\"data\")\n", "summary_params = config.get(\"summary\")\n", - "g_model = GenerationNet(config)\n", - "d_model = TemporalDiscriminator(data_params.get(\"t_in\", 9) + data_params.get(\"t_out\", 20))\n", - "g_model.set_train()\n", - "d_model.set_train()\n", - "g_model = amp.auto_mixed_precision(g_model, amp_level=train_params.get(\"amp_level\", 'O2'))\n", - "d_model = amp.auto_mixed_precision(d_model, amp_level=train_params.get(\"amp_level\", 'O2'))" + "loss_scale = nn.DynamicLossScaleUpdateCell(loss_scale_value=2 ** 12, scale_factor=2, scale_window=1000)\n", + "g_model, d_model = init_generation_model(config)\n", + "g_loss_fn = GenerateLoss(g_model, d_model)\n", + "d_loss_fn = DiscriminatorLoss(g_model, d_model)\n", + "trainer = GenerationTrainer(config, g_model, d_model, g_loss_fn, d_loss_fn, logger, loss_scale)" ] }, { @@ -2929,10 +2858,6 @@ }, "outputs": [], "source": [ - "loss_scale = nn.DynamicLossScaleUpdateCell(loss_scale_value=2 ** 12, scale_factor=2, scale_window=1000)\n", - "g_loss_fn = GenerateLoss(g_model, d_model)\n", - "d_loss_fn = DiscriminatorLoss(g_model, d_model)\n", - "trainer = GenerationTrainer(config, g_model, d_model, g_loss_fn, d_loss_fn, logger, loss_scale)\n", "trainer.train()" ] }, @@ -2942,9 +2867,9 @@ "collapsed": false }, "source": [ - "### generation评估和可视化\n", + "### Evaluation and Visualization\n", "\n", - "完成训练后,我们使用ckpt进行推理,下述展示了推理的可视化图片" + "After training, we use the checkpoint for inference. The visualization of predictions, ground truth and their error is shown below." ] }, { @@ -2960,8 +2885,8 @@ "outputs": [], "source": [ "config[\"summary\"][\"visual\"] = True\n", - "config[\"summary\"][\"generate_ckpt_path\"] = \"./ckpt/generator5_5w_beta10.ckpt\"\n", "config[\"train\"][\"load_ckpt\"] = True\n", + "config[\"summary\"][\"generate_ckpt_path\"] = './summary/ckpt/generator_15.ckpt'\n", "gen_inference = GenerationPredictor(config, g_model, logger)" ] }, @@ -3004,13 +2929,7 @@ " num_workers=data_params.get('num_workers', 1),\n", " shuffle=False)\n", "test_dataset = test_dataset.create_dataset(data_params.get('batch_size', 1))\n", - "# data = next(test_dataset.create_dict_iterator())\n", - "steps = 1\n", - "for d in test_dataset.create_dict_iterator():\n", - " if steps == 5:\n", - " data = d\n", - " break\n", - " steps += 1\n", + "data = next(test_dataset.create_dict_iterator())\n", "inp, evo_result, labels = data.get(\"inputs\"), data.get(\"evo\"), data.get(\"labels\")\n", "noise_scale = data_params.get(\"noise_scale\", 32)\n", "threshold = summary_params.get(\"csin_threshold\", 16)\n", @@ -3020,7 +2939,8 @@ "ngf = model_params.get(\"ngf\", 32)\n", "noise = ms.tensor(ms.numpy.randn((batch_size, ngf, h_size // noise_scale, w_size // noise_scale)), inp.dtype)\n", "pred = gen_inference.generator(inp, evo_result, noise)\n", - "plt_img(field=pred[0].asnumpy(), label=labels[0].asnumpy(), idx=plt_idx, fig_name=\"./generation_example.png\")" + "plt_idx = [x // data_params.get(\"data_frequency\") - 1 for x in data_params.get(\"key_info_timestep\", [10, 60, 120])]\n", + "plt_img(field=pred[0].asnumpy(), label=labels[0].asnumpy(), idx=plt_idx, fig_name=\"./generation_example.png\", evo=evo_result[0].asnumpy() * 128, plot_evo=False)" ] } ], diff --git a/MindEarth/applications/nowcasting/Nowcastnet/Nowcastnet_CN.ipynb b/MindEarth/applications/nowcasting/Nowcastnet/Nowcastnet_CN.ipynb index d55f05f0ff768a2c15fd24800f657092083a11ad..33527e1548483c6f77431b0c32033baf035cb479 100644 --- a/MindEarth/applications/nowcasting/Nowcastnet/Nowcastnet_CN.ipynb +++ b/MindEarth/applications/nowcasting/Nowcastnet/Nowcastnet_CN.ipynb @@ -94,10 +94,11 @@ ], "source": [ "import random\n", + "import os\n", "\n", "import mindspore as ms\n", "import numpy as np\n", - "from mindspore import context, nn, amp, set_seed\n", + "from mindspore import context, nn, set_seed\n", "from mindspore.train.serialization import load_checkpoint, load_param_into_net" ] }, @@ -117,10 +118,10 @@ "from src import EvolutionTrainer, GenerationTrainer, GenerateLoss, DiscriminatorLoss, EvolutionLoss\n", "from src import EvolutionPredictor, GenerationPredictor\n", "from src import RadarData, NowcastDataset\n", + "from src import init_generation_model\n", "from src.evolution import EvolutionNet\n", - "from src.generator import GenerationNet\n", - "from src.discriminator import TemporalDiscriminator\n", "from src.visual import plt_img\n", + "from mindearth.utils import make_dir\n", "from mindearth.utils.tools import load_yaml_config" ] }, @@ -154,7 +155,9 @@ "outputs": [], "source": [ "config = load_yaml_config(\"./configs/Nowcastnet.yaml\")\n", - "context.set_context(mode=context.GRAPH_MODE, device_target=\"Ascend\", device_id=1)" + "make_dir(os.path.join(config['summary'][\"summary_dir\"], \"img\"))\n", + "context.set_context(mode=context.GRAPH_MODE, device_target=\"Ascend\", device_id=1)\n", + "logger = get_logger(config)" ] }, { @@ -533,14 +536,16 @@ } ], "source": [ - "logger = get_logger(config)\n", "config[\"model\"][\"module_name\"] = 'evolution'\n", "config[\"data\"][\"batch_size\"] = 4\n", "config[\"summary\"][\"eval_interval\"] = 1\n", "config[\"summary\"][\"visual\"] = False\n", "train_params = config.get(\"train\")\n", "summary_params = config.get(\"summary\")\n", - "evo_model = EvolutionNet(config)\n", + "evo_model = EvolutionNet(config.get('data').get(\"t_in\", 9),\n", + " config.get('data').get(\"t_out\", 20),\n", + " config.get('data').get(\"h_size\", 512),\n", + " config.get('data').get(\"w_size\", 512))\n", "evo_model.set_train()" ] }, @@ -2755,7 +2760,7 @@ "source": [ "config[\"data\"][\"batch_size\"] = 1\n", "config[\"summary\"][\"visual\"] = True\n", - "params = load_checkpoint('./summary/ckpt/evolution-3_200.ckpt')\n", + "params = load_checkpoint('./summary/ckpt/evolution_2-15_380.ckpt')\n", "evo_model.set_train(False)\n", "load_param_into_net(evo_model, params)\n", "evo_inference = EvolutionPredictor(config, evo_model, logger)" @@ -2791,7 +2796,7 @@ "inputs = data['inputs']\n", "pred = evo_inference.forecast(inputs)\n", "labels = inputs[:, data_params.get(\"t_in\"):]\n", - "plt_idx = [x // data_params.get(\"time_interval\") - 1 for x in data_params.get(\"key_info_timestep\", [10, 60, 120])]\n", + "plt_idx = [x // data_params.get(\"data_frequency\") - 1 for x in data_params.get(\"key_info_timestep\", [10, 60, 120])]\n", "plt_img(field=pred[0].asnumpy(), label=labels[0].asnumpy(), idx=plt_idx, fig_name=\"./evolution_example.png\")" ] }, @@ -2825,18 +2830,23 @@ "config[\"data\"][\"batch_size\"] = 1\n", "config[\"summary\"][\"visual\"] = False\n", "config[\"summary\"][\"save_checkpoint_epochs\"] = 1\n", + "logger = get_logger(config)\n", "train_params = config.get(\"train\")\n", + "data_params = config.get(\"data\")\n", "summary_params = config.get(\"summary\")\n", - "g_model = GenerationNet(config)\n", - "d_model = TemporalDiscriminator(data_params.get(\"t_in\", 9) + data_params.get(\"t_out\", 20))\n", - "g_model.set_train()\n", - "d_model.set_train()\n", - "g_model = amp.auto_mixed_precision(g_model, amp_level=train_params.get(\"amp_level\", 'O2'))\n", - "d_model = amp.auto_mixed_precision(d_model, amp_level=train_params.get(\"amp_level\", 'O2'))\n", "loss_scale = nn.DynamicLossScaleUpdateCell(loss_scale_value=2 ** 12, scale_factor=2, scale_window=1000)\n", + "g_model, d_model = init_generation_model(config)\n", "g_loss_fn = GenerateLoss(g_model, d_model)\n", "d_loss_fn = DiscriminatorLoss(g_model, d_model)\n", - "trainer = GenerationTrainer(config, g_model, d_model, g_loss_fn, d_loss_fn, logger, loss_scale)\n", + "trainer = GenerationTrainer(config, g_model, d_model, g_loss_fn, d_loss_fn, logger, loss_scale)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ "trainer.train()" ] }, @@ -2861,6 +2871,7 @@ "source": [ "config[\"summary\"][\"visual\"] = True\n", "config[\"train\"][\"load_ckpt\"] = True\n", + "config[\"summary\"][\"generate_ckpt_path\"] = './summary/ckpt/generator_15.ckpt'\n", "gen_inference = GenerationPredictor(config, g_model, logger)" ] }, @@ -2891,7 +2902,8 @@ "ngf = model_params.get(\"ngf\", 32)\n", "noise = ms.tensor(ms.numpy.randn((batch_size, ngf, h_size // noise_scale, w_size // noise_scale)), inp.dtype)\n", "pred = gen_inference.generator(inp, evo_result, noise)\n", - "plt_img(field=pred[0].asnumpy(), label=labels[0].asnumpy(), idx=plt_idx, fig_name=\"./generation_example.png\", evo=evo_result[0].asnumpy() * 128, plot_evo=True)" + "plt_idx = [x // data_params.get(\"data_frequency\") - 1 for x in data_params.get(\"key_info_timestep\", [10, 60, 120])]\n", + "plt_img(field=pred[0].asnumpy(), label=labels[0].asnumpy(), idx=plt_idx, fig_name=\"./generation_example.png\", evo=evo_result[0].asnumpy() * 128, plot_evo=False)" ] } ], diff --git a/MindEarth/applications/nowcasting/Nowcastnet/configs/Nowcastnet.yaml b/MindEarth/applications/nowcasting/Nowcastnet/configs/Nowcastnet.yaml index cac0f0f288c16803a8e9e270e54ffae28ced2f7b..e9a8776f0a76e78d1862261fd51278e8d08ff036 100644 --- a/MindEarth/applications/nowcasting/Nowcastnet/configs/Nowcastnet.yaml +++ b/MindEarth/applications/nowcasting/Nowcastnet/configs/Nowcastnet.yaml @@ -11,7 +11,7 @@ data: h_size: 512 w_size: 512 data_frequency: 10 - num_workers: 1 + num_workers: 4 data_sink: False batch_size: 1 noise_scale: 32 @@ -20,7 +20,7 @@ optimizer-gen: beta1: 0.01 beta2: 0.9 g_lr: 1.5e-5 - d_lr: 6e-6 + d_lr: 1e-6 epochs: 15 optimizer-evo: name: "adam" @@ -31,7 +31,7 @@ optimizer-evo: motion_lambda: 1e-2 summary: summary_dir: "./summary/" - eval_interval: 2 + eval_interval: 1 save_checkpoint_epochs: 1 keep_checkpoint_max: 4 key_info_timestep: [10, 60, 120] diff --git a/MindEarth/applications/nowcasting/Nowcastnet/main.py b/MindEarth/applications/nowcasting/Nowcastnet/main.py index 64ffe6d5839b4dd2109e11291b9267315cea7662..a01366a52e8f2fc440217ece0d60db3ce57c9f5d 100644 --- a/MindEarth/applications/nowcasting/Nowcastnet/main.py +++ b/MindEarth/applications/nowcasting/Nowcastnet/main.py @@ -72,6 +72,7 @@ def train(cfg, logger): def test(cfg, logger): """test""" + cfg["train"]["load_ckpt"] = "True" train_params = cfg.get("train") data_params = cfg.get("data") module_name = cfg.get("model").get("module_name", "generation") diff --git a/MindEarth/applications/nowcasting/Nowcastnet/src/evolution.py b/MindEarth/applications/nowcasting/Nowcastnet/src/evolution.py index f1c0a776b90f2780baeddd11e061f60aa4f38c54..f0786151f9329c5d4b4b226937308d58c2ecf750 100644 --- a/MindEarth/applications/nowcasting/Nowcastnet/src/evolution.py +++ b/MindEarth/applications/nowcasting/Nowcastnet/src/evolution.py @@ -44,9 +44,8 @@ class SpectralNormal(nn.Cell): Outputs: The forward propagation of containing module. """ - def __init__(self, module, n_power_iterations=1, dim=0, eps=1e-12, n1=1.0, n2=0, l=0): + def __init__(self, module, n_power_iterations=1, dim=0, eps=1e-12, n1=1.0, n2=0): super(SpectralNormal, self).__init__() - self.l = l self.parametrizations = module self.weight = module.weight ndim = self.weight.ndim @@ -67,7 +66,7 @@ class SpectralNormal(nn.Cell): weight_mat = self._reshape_weight_to_matrix() h, w = weight_mat.shape u = initializer(Normal(n1, n2), [h]).init_data() - v = initializer(Normal(n1, n1), [w]).init_data() + v = initializer(Normal(n1, n2), [w]).init_data() self._u = Parameter(self.l2_normalize(u), requires_grad=False) # 封装成Parameter对象 self._v = Parameter(self.l2_normalize(v), requires_grad=False) @@ -91,8 +90,8 @@ class SpectralNormal(nn.Cell): def _power_method(self, weight_mat, n_power_iterations): for _ in range(n_power_iterations): self._u = self.l2_normalize(mnp.multi_dot([weight_mat, self.expand_dims(self._v, -1)]).flatten()) - temp = mnp.multi_dot([weight_mat.T, self.expand_dims(self._u, -1)]).flatten() - self._v = self.l2_normalize(temp) + self._u += 0 + self._v = self.l2_normalize(mnp.multi_dot([weight_mat.T, self.expand_dims(self._u, -1)]).flatten()) return self._u, self._v def _reshape_weight_to_matrix(self): diff --git a/MindEarth/applications/nowcasting/Nowcastnet/src/forecast.py b/MindEarth/applications/nowcasting/Nowcastnet/src/forecast.py index 8ef3f74e99d1345714cbc16ecc7b0a8a13220c07..74e9382d5305d074c5bebc146e886c59bfd57b3b 100644 --- a/MindEarth/applications/nowcasting/Nowcastnet/src/forecast.py +++ b/MindEarth/applications/nowcasting/Nowcastnet/src/forecast.py @@ -118,7 +118,7 @@ class GenerationPredictor(nn.Cell): self.h_size // self.noise_scale, self.w_size // self.noise_scale)), inp.dtype) pred = self.generator(inp, evo_result, noise) - metrics = cal_csi(pred=pred, target=labels, threshold=7) + metrics = cal_csin(pred=pred, target=labels, threshold=self.threshold) np_metrics = metrics.asnumpy() np_metrics_avg = np.mean(np_metrics) # print('np_metrics',np_metrics) @@ -131,7 +131,7 @@ class GenerationPredictor(nn.Cell): idx=plt_idx, fig_name=os.path.join(self.vis_save_path, f"generation_{steps}_{j}.jpg"), evo=evo_result[j].asnumpy() * 128, - plot_evo=True) + plot_evo=False) step_cost = (time.time() - t1) * 1000 self.logger.info("step {}, cost: {:.2f} ms".format(steps, step_cost)) steps += 1 @@ -193,9 +193,8 @@ class EvolutionPredictor: inp = data.get("inputs") pred = self.forecast(inp) labels = inp[:, self.t_in:] - metrics = cal_csi(pred=pred, target=labels, threshold=7) + metrics = cal_csin(pred=pred, target=labels, threshold=self.threshold) np_metrics = metrics.asnumpy() - # print('np_metrics',np_metrics) metrics_list.append(np_metrics) self.print_csi_metrics(np_metrics, info_prefix=f'CSI Neighborhood threshold {self.threshold}') if self.summary_params.get("visual", True): diff --git a/MindEarth/applications/nowcasting/Nowcastnet/src/generator.py b/MindEarth/applications/nowcasting/Nowcastnet/src/generator.py index aaaf550572948985b9795364c74128498aa5479f..1dd4017eb13b362365f0794ed3d6ec63f453a139 100644 --- a/MindEarth/applications/nowcasting/Nowcastnet/src/generator.py +++ b/MindEarth/applications/nowcasting/Nowcastnet/src/generator.py @@ -58,7 +58,7 @@ class GenBlock(nn.Cell): has_bias=True, dilation=dilation ) - self.conv_0 = SpectralNormal(self.conv_0, l=0) + self.conv_0 = SpectralNormal(self.conv_0) self.norm_0 = SPADE(in_channels, data_params.get("t_out", 20)) self.conv_1 = nn.Conv2d(mid_channels, out_channels, @@ -67,12 +67,12 @@ class GenBlock(nn.Cell): has_bias=True, dilation=dilation ) - self.conv_1 = SpectralNormal(self.conv_1, l=1) + self.conv_1 = SpectralNormal(self.conv_1) self.norm_1 = SPADE(mid_channels, data_params.get("t_out", 20)) if self.learned_shortcut: self.conv_s = nn.Conv2d(in_channels, out_channels, kernel_size=1, pad_mode='pad') # self.conv_s = nn.Conv2d(in_channels, out_channels, kernel_size=1, pad_mode='valid') - self.conv_s = SpectralNormal(self.conv_s, l=0) + self.conv_s = SpectralNormal(self.conv_s) self.norm_s = SPADE(in_channels, data_params.get("t_out", 20)) self.leaky_relu = nn.LeakyReLU(2e-1) @@ -99,15 +99,13 @@ class SPADE(nn.Cell): self.param_free_norm = nn.BatchNorm2d(norm_channels, affine=False) self.pad_head = ReflectPad(kernel_size // 2) self.mlp_shared = nn.SequentialCell( - # nn.Conv2d(label_nc, hidden, kernel_size=kernel_size, pad_mode='valid', has_bias=True), nn.Conv2d(label_nc, hidden, kernel_size=kernel_size, pad_mode='pad', has_bias=True), nn.ReLU() ) self.pad = ReflectPad(kernel_size // 2) self.mlp_gamma = nn.Conv2d(hidden, norm_channels, kernel_size=kernel_size, pad_mode='pad', has_bias=True) self.mlp_beta = nn.Conv2d(hidden, norm_channels, kernel_size=kernel_size, pad_mode='pad', has_bias=True) - # self.mlp_gamma = nn.Conv2d(hidden, norm_channels, kernel_size=kernel_size, pad_mode='valid', has_bias=True) - # self.mlp_beta = nn.Conv2d(hidden, norm_channels, kernel_size=kernel_size, pad_mode='valid', has_bias=True) + def construct(self, x, evo): normalized = self.param_free_norm(x) @@ -130,7 +128,7 @@ class NoiseProjector(nn.Cell): pad_mode='pad', padding=1, has_bias=True - ), l=2 + ), ) self.block1 = ProjBlock(t_in * 2, t_in * 4) self.block2 = ProjBlock(t_in * 4, t_in * 8) @@ -151,17 +149,13 @@ class ProjBlock(nn.Cell): def __init__(self, in_channels, out_channels): super(ProjBlock, self).__init__() self.one_conv = SpectralNormal(nn.Conv2d(in_channels, out_channels - in_channels, - kernel_size=1, has_bias=True), l=4) - # self.one_conv = nn.Conv2d(in_channels, out_channels - in_channels, kernel_size=1, has_bias=True) + kernel_size=1, has_bias=True)) self.double_conv = nn.SequentialCell( SpectralNormal(nn.Conv2d(in_channels, out_channels, kernel_size=3, pad_mode='pad', - padding=1, has_bias=True), l=2), + padding=1, has_bias=True),), nn.ReLU(), SpectralNormal(nn.Conv2d(out_channels, out_channels, kernel_size=3, pad_mode='pad', - padding=1, has_bias=True), l=2) - # nn.Conv2d(in_channels, out_channels, kernel_size=3, pad_mode='pad', padding=1, has_bias=True), - # nn.ReLU(), - # nn.Conv2d(out_channels, out_channels, kernel_size=3, pad_mode='pad', padding=1, has_bias=True) + padding=1, has_bias=True)) ) def construct(self, x): diff --git a/MindEarth/applications/nowcasting/Nowcastnet/src/loss.py b/MindEarth/applications/nowcasting/Nowcastnet/src/loss.py index 105fe1753845a999f37a3bfe9ff89dfc532d2575..94cb4ba18bae81ed30daccf2de3e417da0330272 100644 --- a/MindEarth/applications/nowcasting/Nowcastnet/src/loss.py +++ b/MindEarth/applications/nowcasting/Nowcastnet/src/loss.py @@ -155,13 +155,14 @@ class EvolutionLoss(nn.Cell): self.loss_fn_motion = MotionLossNet(in_channels=1, out_channels=1, kernel_size=3) self.t_in = self.config.get('data').get("t_in", 9) self.t_out = self.config.get('data').get('t_out', 20) - sample_tensor = np.zeros( - (1, 1, self.config.get('data').get("h_size", 512), self.config.get('data').get("w_size", 512))).astype( - np.float32) + sample_tensor = np.zeros((1, + 1, + self.config.get('data').get("h_size", 512), + self.config.get('data').get("w_size", 512))).astype(np.float32) self.grid = Tensor(make_grid(sample_tensor), ms.float32) self.lamb = float(config.get('optimizer-evo').get("motion_lambda", 1e-2)) - def construct(self, inputs, weights): + def construct(self, inputs): """last frame of inputs""" intensity, motion = self.model(inputs) batch, _, height, width = inputs.shape @@ -173,12 +174,13 @@ class EvolutionLoss(nn.Cell): motion = 0 for i in range(self.t_out): next_frame = inputs[:, self.t_in + i, :, :] + weights = ops.where(next_frame > 23., 24., next_frame + 1) xt_1 = warp(last_frame, motion_[:, i], grid, mode="bilinear", padding_mode="border") - accum += self.loss_fn_accum(next_frame, xt_1[:, 0], weights[:, i]) + accum += self.loss_fn_accum(next_frame, xt_1[:, 0], weights) last_frame = warp(last_frame, motion_[:, i], grid, mode="nearest", padding_mode="border") last_frame = last_frame + intensity_[:, i] - accum += self.loss_fn_accum(next_frame, last_frame[:, 0], weights[:, i]) + accum += self.loss_fn_accum(next_frame, last_frame[:, 0], weights) last_frame = ops.stop_gradient(last_frame) - motion += self.loss_fn_motion(motion_[:, i], weights[:, i]) + motion += self.loss_fn_motion(motion_[:, i], weights) loss = (accum + self.lamb * motion) / self.t_out return loss diff --git a/MindEarth/applications/nowcasting/Nowcastnet/src/solver.py b/MindEarth/applications/nowcasting/Nowcastnet/src/solver.py index 1bf317ccfc993a7a59d912364e858874b78ac50a..f646e5f63e989dd8b28662ccf3724e568def4a59 100644 --- a/MindEarth/applications/nowcasting/Nowcastnet/src/solver.py +++ b/MindEarth/applications/nowcasting/Nowcastnet/src/solver.py @@ -14,11 +14,11 @@ # ============================================================================== """NowcastNet Trainer""" import math -import pickle import numpy as np import mindspore as ms from mindspore import nn, Model, ops +from mindspore.train.callback import LossMonitor, TimeMonitor from .dataset import RadarData, NowcastDataset from .callback import NowcastCallBack, EvolutionCallBack @@ -74,17 +74,19 @@ class GenerationTrainer: self.predictor = GenerationPredictor(config, self.g_model, logger) self.g_grad_fn = ms.value_and_grad(self.g_forward_fn, None, self.g_optimizer.parameters) self.d_grad_fn = ms.value_and_grad(self.d_forward_fn, None, self.d_optimizer.parameters) - self.i = 1 @staticmethod def _get_cosine_annealing_lr(lr_init, steps_per_epoch, epochs, eta_min=1e-6): - """cosine annealing lr""" + "cosine annealing lr" total_steps = epochs * steps_per_epoch delta = 0.5 * (lr_init - eta_min) lr = [] - for i in range(total_steps): - tmp_epoch = min(math.floor(i / steps_per_epoch), epochs) # math.floor() 结果向下取整 - lr.append(eta_min + delta * (1 + math.cos(math.pi * tmp_epoch / epochs))) + try: + for i in range(total_steps): + tmp_epoch = min(math.floor(i / steps_per_epoch), epochs) + lr.append(eta_min + delta * (1 + math.cos(math.pi * tmp_epoch / epochs))) + except ZeroDivisionError: + return lr return lr def get_dataset(self): @@ -166,14 +168,6 @@ class GenerationTrainer: loss = self.d_loss_fn(inputs, evo_result, noise, real_image) return loss - def savenp(self, loss): - if isinstance(loss, tuple): - with open('out_2.3_.pkl', 'wb') as f: - pickle.dump(loss, f) - else: - np_loss = loss.copy() - np_loss = np_loss.asnumpy() - np.save('./grads_{}.npy'.format('2.2'), np_loss) def train_step(self, inputs, evo_result, real_image, weights): """train step""" @@ -228,7 +222,6 @@ class EvolutionTrainer: self.solver = self.get_solver() self.pred_cb = self.get_callback() self.ckpt_cb = self.pred_cb.save_evolution_ckpt() - self.grad_fn = ms.value_and_grad(self.forward_fn, None, self.optimizer.parameters) def get_dataset(self): """ @@ -244,12 +237,15 @@ class EvolutionTrainer: train_dataset_generator = RadarData(self.data_params, run_mode='train', module_name='evolution') valid_dataset_generator = RadarData(self.data_params, run_mode='valid', module_name='evolution') - train_dataset = NowcastDataset(train_dataset_generator, module_name='evolution', + train_dataset = NowcastDataset(train_dataset_generator, + module_name='evolution', distribute=self.train_params.get('distribute', False), num_workers=self.data_params.get('num_workers', 1)) - valid_dataset = NowcastDataset(valid_dataset_generator, module_name='evolution', + valid_dataset = NowcastDataset(valid_dataset_generator, + module_name='evolution', distribute=self.train_params.get('distribute', False), - num_workers=self.data_params.get('num_workers', 1), shuffle=False) + num_workers=self.data_params.get('num_workers', 1), + shuffle=False) train_dataset = train_dataset.create_dataset(self.data_params.get('batch_size', 8)) valid_dataset = valid_dataset.create_dataset(self.data_params.get('batch_size', 8)) return train_dataset, valid_dataset @@ -287,19 +283,8 @@ class EvolutionTrainer: def train(self): """ train """ - for epoch in range(self.optimizer_params.get("epochs", 50)): - for i, data in enumerate(self.train_dataset.create_dict_iterator()): - inp = data.get("inputs") - weights = ops.where(inp[:, self.data_params.get("t_in", 9):] > 23., 24., - inp[:, self.data_params.get("t_in", 9):] + 1) - loss = self.train_step(inp, weights) - print(f"epochs:{epoch + 1}, steps:{i + 1}, loss: {loss.asnumpy():>7f}") - - def forward_fn(self, data, weights): - loss = self.loss_fn(data, weights) - return loss - - def train_step(self, data, weights): - loss, grads = self.grad_fn(data, weights) - self.optimizer(grads) - return loss + callback_lst = [LossMonitor(), TimeMonitor(), self.pred_cb, self.ckpt_cb] + self.solver.train(epoch=self.optimizer_params.get("epochs", 200), + train_dataset=self.train_dataset, + callbacks=callback_lst, + dataset_sink_mode=self.data_params.get('data_sink')) diff --git a/MindEarth/applications/nowcasting/Nowcastnet/src/visual.py b/MindEarth/applications/nowcasting/Nowcastnet/src/visual.py index 153568e0ce2897f806c2508382c5f8bd30b75fd4..7ac2bcaaea91a1bc5afa6ad3a5ee96bdb6657ed4 100644 --- a/MindEarth/applications/nowcasting/Nowcastnet/src/visual.py +++ b/MindEarth/applications/nowcasting/Nowcastnet/src/visual.py @@ -67,4 +67,5 @@ def plt_img(field, label, idx, plot_evo=False, evo=None, interval=10, fig_name=" _ = axs[2][2].imshow(evo[idx[2]], alpha=alpha, vmin=vmin, vmax=vmax, cmap=cmap) axs[2][2].set_title(f"evo results {idx[2] * interval + interval} min") plt.savefig(fig_name, dpi=180) + plt.show() plt.close()