From f5082733ce624b7a44d7a86d906899a7de6d1e0c Mon Sep 17 00:00:00 2001 From: Harold-Ran <56714856+Harold-Ran@users.noreply.github.com> Date: Wed, 10 Nov 2021 21:04:28 +0800 Subject: [PATCH] =?UTF-8?q?Delete=20Task3=20=E6=A8=A1=E5=9E=8B=E5=BB=BA?= =?UTF-8?q?=E7=AB=8B=E4=B9=8BCNN+LSTM.ipynb?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Task3/Task3 模型建立之CNN+LSTM.ipynb | 2173 -------------------------- 1 file changed, 2173 deletions(-) delete mode 100644 Task3/Task3 模型建立之CNN+LSTM.ipynb diff --git a/Task3/Task3 模型建立之CNN+LSTM.ipynb b/Task3/Task3 模型建立之CNN+LSTM.ipynb deleted file mode 100644 index 1f9bf7a..0000000 --- a/Task3/Task3 模型建立之CNN+LSTM.ipynb +++ /dev/null @@ -1,2173 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 0.041973, - "end_time": "2021-10-21T08:26:40.951999", - "exception": false, - "start_time": "2021-10-21T08:26:40.910026", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "# Datawhale 气象海洋预测-Task3 模型建立之 CNN+LSTM\n", - "本次任务我们将学习来自TOP选手“学习AI的打工人”的建模方案,该方案中采用的模型是CNN+LSTM。\n", - "\n", - "在Task2的数据分析中我们发现,构建新的特征是很困难的,因此本赛题是一个模型问题,我们的主要目标是构造一个能够从小数据集中充分挖掘空间信息和时间信息的模型。那么,说到挖掘空间信息的模型,我们会很自然的想到CNN,同样的,挖掘时间信息的模型我们会很容易想到LSTM,我们本次学习的这个TOP方案正是构造了CNN+LSTM的串行结构。" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 0.038898, - "end_time": "2021-10-21T08:26:41.029700", - "exception": false, - "start_time": "2021-10-21T08:26:40.990802", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "## 学习目标\n", - "1. 学习TOP方案的数据处理方法。\n", - "2. 学习TOP方案的模型构建方法。" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 0.037798, - "end_time": "2021-10-21T08:26:41.105682", - "exception": false, - "start_time": "2021-10-21T08:26:41.067884", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "## 内容介绍\n", - "1. 数据处理\n", - " - 增加月特征\n", - " - 数据扁平化\n", - " - 空值填充\n", - " - 构造数据集\n", - "2. 模型构建\n", - " - 构造评估函数\n", - " - 模型构造与训练\n", - " - 模型评估\n", - "3. 总结" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 0.039388, - "end_time": "2021-10-21T08:26:41.184055", - "exception": false, - "start_time": "2021-10-21T08:26:41.144667", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "## 代码示例" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 0.040442, - "end_time": "2021-10-21T08:26:41.263590", - "exception": false, - "start_time": "2021-10-21T08:26:41.223148", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "### 数据处理" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 0.03883, - "end_time": "2021-10-21T08:26:41.341357", - "exception": false, - "start_time": "2021-10-21T08:26:41.302527", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "该TOP方案的数据处理主要包括四部分:\n", - "\n", - "1. 增加月特征。将序列数据的起始月份作为新的特征。\n", - "2. 数据扁平化。将序列数据按月拼接起来通过滑窗增加数据量。\n", - "3. 空值填充。\n", - "4. 构造数据集。随机采样构造数据集。" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 0.039658, - "end_time": "2021-10-21T08:26:41.419379", - "exception": false, - "start_time": "2021-10-21T08:26:41.379721", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "在本次任务中我们需要用到TensorFlow Probability(TFP)这个库来计算皮尔逊相关系数,TFP是TensorFlow生态的一部分,它继承了TensorFlow的优势,主要用于概率推理和统计分析。使用方法可以参考TensorFlow Probability指南:https://tensorflow.google.cn/probability/overview?hl=zh-cn\n", - "\n", - "在TensorFlow 1.x中也有计算皮尔逊相关系数的函数tf.contrib.metrics.streaming_pearson_correlation,这里使用的是TensorFlow 2.x,没有相应的函数,因此需要借助TFP这个库,在使用时需要注意与TensorFlow的版本匹配。" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "execution": { - "iopub.execute_input": "2021-10-21T08:26:41.578690Z", - "iopub.status.busy": "2021-10-21T08:26:41.577976Z", - "iopub.status.idle": "2021-10-21T08:26:50.062707Z", - "shell.execute_reply": "2021-10-21T08:26:50.062123Z", - "shell.execute_reply.started": "2021-10-21T07:24:47.91831Z" - }, - "papermill": { - "duration": 8.603525, - "end_time": "2021-10-21T08:26:50.062852", - "exception": false, - "start_time": "2021-10-21T08:26:41.459327", - "status": "completed" - }, - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: tensorflow-probability in /opt/conda/lib/python3.7/site-packages (0.12.2)\r\n", - "Requirement already satisfied: six>=1.10.0 in /opt/conda/lib/python3.7/site-packages (from tensorflow-probability) (1.15.0)\r\n", - "Requirement already satisfied: gast>=0.3.2 in /opt/conda/lib/python3.7/site-packages (from tensorflow-probability) (0.3.3)\r\n", - "Requirement already satisfied: numpy>=1.13.3 in /opt/conda/lib/python3.7/site-packages (from tensorflow-probability) (1.19.5)\r\n", - "Requirement already satisfied: decorator in /opt/conda/lib/python3.7/site-packages (from tensorflow-probability) (5.0.9)\r\n", - "Requirement already satisfied: cloudpickle>=1.3 in /opt/conda/lib/python3.7/site-packages (from tensorflow-probability) (1.6.0)\r\n", - "Requirement already satisfied: dm-tree in /opt/conda/lib/python3.7/site-packages (from tensorflow-probability) (0.1.6)\r\n", - "\u001b[33mWARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv\u001b[0m\r\n" - ] - } - ], - "source": [ - "# 安装TensorFlow Probability\n", - "!pip install tensorflow-probability" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "execution": { - "iopub.execute_input": "2021-10-21T08:26:50.151992Z", - "iopub.status.busy": "2021-10-21T08:26:50.151202Z", - "iopub.status.idle": "2021-10-21T08:26:55.755035Z", - "shell.execute_reply": "2021-10-21T08:26:55.755518Z", - "shell.execute_reply.started": "2021-10-21T07:24:55.960084Z" - }, - "papermill": { - "duration": 5.652932, - "end_time": "2021-10-21T08:26:55.755685", - "exception": false, - "start_time": "2021-10-21T08:26:50.102753", - "status": "completed" - }, - "tags": [] - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2021-10-21 08:26:51.500316: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcudart.so.11.0\n" - ] - } - ], - "source": [ - "import math\n", - "import pandas as pd\n", - "import numpy as np\n", - "\n", - "import netCDF4 as nc\n", - "from netCDF4 import Dataset\n", - "\n", - "import matplotlib.pyplot as plt\n", - "%matplotlib inline\n", - "\n", - "import seaborn as sns\n", - "color = sns.color_palette()\n", - "sns.set_style('darkgrid')\n", - "\n", - "#忽略警告\n", - "import warnings\n", - "def ignore_warn(*args, **kwargs):\n", - " pass\n", - "warnings.warn = ignore_warn\n", - "\n", - "from sklearn.model_selection import KFold, train_test_split\n", - "from sklearn.metrics import mean_squared_error\n", - "\n", - "import tensorflow as tf\n", - "import tensorflow_probability as tfp\n", - "from tensorflow.keras.models import Model, Sequential\n", - "from tensorflow.keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPooling2D, AveragePooling2D, TimeDistributed, BatchNormalization, Activation, LSTM\n", - "from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping\n", - "from tensorflow.keras.regularizers import L2" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "execution": { - "iopub.execute_input": "2021-10-21T08:26:55.843982Z", - "iopub.status.busy": "2021-10-21T08:26:55.842111Z", - "iopub.status.idle": "2021-10-21T08:26:55.844663Z", - "shell.execute_reply": "2021-10-21T08:26:55.845106Z", - "shell.execute_reply.started": "2021-10-21T07:25:02.223502Z" - }, - "papermill": { - "duration": 0.049636, - "end_time": "2021-10-21T08:26:55.845243", - "exception": false, - "start_time": "2021-10-21T08:26:55.795607", - "status": "completed" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# 固定随机种子\n", - "SEED = 42\n", - "\n", - "tf.random.set_seed(SEED)\n", - "np.random.seed(SEED)" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "execution": { - "iopub.execute_input": "2021-10-21T08:26:56.002932Z", - "iopub.status.busy": "2021-10-21T08:26:56.002033Z", - "iopub.status.idle": "2021-10-21T08:26:56.128559Z", - "shell.execute_reply": "2021-10-21T08:26:56.129041Z", - "shell.execute_reply.started": "2021-10-21T07:25:02.230095Z" - }, - "papermill": { - "duration": 0.245418, - "end_time": "2021-10-21T08:26:56.129219", - "exception": false, - "start_time": "2021-10-21T08:26:55.883801", - "status": "completed" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# 读取数据\n", - "\n", - "# 存放数据的路径\n", - "path = '/kaggle/input/ninoprediction/'\n", - "soda_train = Dataset(path + 'SODA_train.nc')\n", - "soda_label = Dataset(path + 'SODA_label.nc')\n", - "cmip_train = Dataset(path + 'CMIP_train.nc')\n", - "cmip_label = Dataset(path + 'CMIP_label.nc')" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 0.039342, - "end_time": "2021-10-21T08:26:56.208644", - "exception": false, - "start_time": "2021-10-21T08:26:56.169302", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "#### 增加月特征" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 0.039664, - "end_time": "2021-10-21T08:26:56.287668", - "exception": false, - "start_time": "2021-10-21T08:26:56.248004", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "本赛题的线上测试集是任意选取某个月为起始的长度为12的序列,因此该方案中增加了起始月份作为新的特征。但是使用整数1~12不能反映12月与1月相邻这一特点,因此需要借助三角函数的周期性,同时考虑到单独使用sin函数或cos函数会存在某些月份的函数值相同的现象,因此同时使用sin函数和cos函数作为两个新增月份特征,保证每个起始月份的这两个特征组合都是独一无二的,并且又能够很好地表现出月份的周期性特征。" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 0.038898, - "end_time": "2021-10-21T08:26:56.366035", - "exception": false, - "start_time": "2021-10-21T08:26:56.327137", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "我们可以通过可视化直观地感受下每个月份所构造的月份特征组合。" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": { - "execution": { - "iopub.execute_input": "2021-10-21T08:26:56.455220Z", - "iopub.status.busy": "2021-10-21T08:26:56.454443Z", - "iopub.status.idle": "2021-10-21T08:26:56.972668Z", - "shell.execute_reply": "2021-10-21T08:26:56.972243Z", - "shell.execute_reply.started": "2021-10-21T07:25:02.336139Z" - }, - "papermill": { - "duration": 0.567654, - "end_time": "2021-10-21T08:26:56.972785", - "exception": false, - "start_time": "2021-10-21T08:26:56.405131", - "status": "completed" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "months = range(0, 12)\n", - "month_labels = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec']\n", - "# sin月份特征\n", - "months_sin = map(lambda x: math.sin(2 * math.pi * x / len(months)), months)\n", - "# cos月份特征\n", - "months_cos = map(lambda x: math.cos(2 * math.pi * x / len(months)), months)\n", - "\n", - "# 绘制每个月的月份特征组合\n", - "plt.figure(figsize=(20, 5))\n", - "x_axis = np.arange(-1, 13, 1e-2)\n", - "sns.lineplot(x=x_axis, y=np.sin(2 * math.pi * x_axis / len(months)))\n", - "sns.lineplot(x=x_axis, y=np.cos(2 * math.pi * x_axis / len(months)))\n", - "sns.scatterplot(x=months, y=months_sin, s=200)\n", - "sns.scatterplot(x=months, y=months_cos, s=200)\n", - "plt.xticks(ticks=months, labels=month_labels)\n", - "plt.show()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 0.041907, - "end_time": "2021-10-21T08:26:57.057907", - "exception": false, - "start_time": "2021-10-21T08:26:57.016000", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "构造SODA数据的sin月份特征。" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": { - "execution": { - "iopub.execute_input": "2021-10-21T08:26:57.166982Z", - "iopub.status.busy": "2021-10-21T08:26:57.157887Z", - "iopub.status.idle": "2021-10-21T08:27:01.880468Z", - "shell.execute_reply": "2021-10-21T08:27:01.879972Z", - "shell.execute_reply.started": "2021-10-21T07:25:02.899195Z" - }, - "papermill": { - "duration": 4.782342, - "end_time": "2021-10-21T08:27:01.880605", - "exception": false, - "start_time": "2021-10-21T08:26:57.098263", - "status": "completed" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "(100, 36, 24, 72)" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# 构造一个维度为100*36*24*72的矩阵,矩阵中的每个值为所在月份的sin函数值\n", - "soda_month_sin = np.zeros((100, 36, 24, 72))\n", - "for y in range(100):\n", - " for m in range(36):\n", - " for lat in range(24):\n", - " for lon in range(72):\n", - " soda_month_sin[y, m, lat, lon] = math.sin(2 * math.pi * (m % 12) / 12)\n", - " \n", - "soda_month_sin.shape" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 0.042435, - "end_time": "2021-10-21T08:27:01.965928", - "exception": false, - "start_time": "2021-10-21T08:27:01.923493", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "构造SODA数据的cos月份特征。" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "execution": { - "iopub.execute_input": "2021-10-21T08:27:02.087139Z", - "iopub.status.busy": "2021-10-21T08:27:02.086186Z", - "iopub.status.idle": "2021-10-21T08:27:07.087092Z", - "shell.execute_reply": "2021-10-21T08:27:07.087525Z", - "shell.execute_reply.started": "2021-10-21T07:25:07.740353Z" - }, - "papermill": { - "duration": 5.078888, - "end_time": "2021-10-21T08:27:07.087684", - "exception": false, - "start_time": "2021-10-21T08:27:02.008796", - "status": "completed" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "(100, 36, 24, 72)" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# 构造一个维度为100*36*24*72的矩阵,矩阵中的每个值为所在月份的cos函数值\n", - "soda_month_cos = np.zeros((100, 36, 24, 72))\n", - "for y in range(100):\n", - " for m in range(36):\n", - " for lat in range(24):\n", - " for lon in range(72):\n", - " soda_month_cos[y, m, lat, lon] = math.cos(2 * math.pi * (m % 12) / 12)\n", - " \n", - "soda_month_cos.shape" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 0.048171, - "end_time": "2021-10-21T08:27:07.180529", - "exception": false, - "start_time": "2021-10-21T08:27:07.132358", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "构造CMIP数据的sin月份特征。" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": { - "execution": { - "iopub.execute_input": "2021-10-21T08:27:07.290837Z", - "iopub.status.busy": "2021-10-21T08:27:07.280656Z", - "iopub.status.idle": "2021-10-21T08:30:55.702184Z", - "shell.execute_reply": "2021-10-21T08:30:55.702653Z", - "shell.execute_reply.started": "2021-10-21T07:25:12.923041Z" - }, - "papermill": { - "duration": 228.478925, - "end_time": "2021-10-21T08:30:55.702836", - "exception": false, - "start_time": "2021-10-21T08:27:07.223911", - "status": "completed" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "(4645, 36, 24, 72)" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# 构造一个维度为4645*36*24*72的矩阵,矩阵中的每个值为所在月份的sin函数值\n", - "cmip_month_sin = np.zeros((4645, 36, 24, 72))\n", - "for y in range(4645):\n", - " for m in range(36):\n", - " for lat in range(24):\n", - " for lon in range(72):\n", - " cmip_month_sin[y, m, lat, lon] = math.sin(2 * math.pi * (m % 12) / 12)\n", - " \n", - "cmip_month_sin.shape" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 0.042186, - "end_time": "2021-10-21T08:30:55.786961", - "exception": false, - "start_time": "2021-10-21T08:30:55.744775", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "构造CMIP数据的cos月份特征。" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": { - "execution": { - "iopub.execute_input": "2021-10-21T08:30:55.914614Z", - "iopub.status.busy": "2021-10-21T08:30:55.894214Z", - "iopub.status.idle": "2021-10-21T08:34:38.857298Z", - "shell.execute_reply": "2021-10-21T08:34:38.857759Z", - "shell.execute_reply.started": "2021-10-21T07:29:05.42979Z" - }, - "papermill": { - "duration": 223.028423, - "end_time": "2021-10-21T08:34:38.857922", - "exception": false, - "start_time": "2021-10-21T08:30:55.829499", - "status": "completed" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "(4645, 36, 24, 72)" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# 构造一个维度为4645*36*24*72的矩阵,矩阵中的每个值为所在月份的cos函数值\n", - "cmip_month_cos = np.zeros((4645, 36, 24, 72))\n", - "for y in range(4645):\n", - " for m in range(36):\n", - " for lat in range(24):\n", - " for lon in range(72):\n", - " cmip_month_cos[y, m, lat, lon] = math.cos(2 * math.pi * (m % 12) / 12)\n", - " \n", - "cmip_month_cos.shape" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 0.044049, - "end_time": "2021-10-21T08:34:38.943900", - "exception": false, - "start_time": "2021-10-21T08:34:38.899851", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "#### 数据扁平化" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 0.043104, - "end_time": "2021-10-21T08:34:39.028555", - "exception": false, - "start_time": "2021-10-21T08:34:38.985451", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "在Task2中我们发现,赛题中给出的数据量非常少,如何增加数据量呢?对于时序数据,一种常用的做法就是滑窗。\n", - "\n", - "由于每条数据在时间上有重叠,我们取数据的前12个月拼接起来,就得到了长度为(数据条数×12个月)的序列数据,如图1所示:\n", - "\n", - "\n", - "然后我们以每个月为起始月,接下来的12个月作为模型输入X,后24个月的Nino3.4指数作为预测目标Y构建训练样本,如图2所示:\n", - "\n", - "\n", - "需要注意的是,CMIP数据提供了不同的拟合模式,只有在同种模式下各个年份的数据在时间上是连续的,因此同种模式的数据才能在时间上拼接起来,除去最后11个月不能构成训练样本外,滑窗最终能获得的训练样本数量可以按以下方式计算得到:\n", - "\n", - "- SODA:1种模式×(100年×12-11)=1189条样本\n", - "- CMIP6:15种模式×(151年×12-11)=27015条样本\n", - "- CMIP5:17种模式×(140年×12-11)=28373条样本" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 0.042601, - "end_time": "2021-10-21T08:34:39.113004", - "exception": false, - "start_time": "2021-10-21T08:34:39.070403", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "在下面的代码中,我们只将各个模式的数据拼接起来而没有采用滑窗,这是因为考虑到采用滑窗得到的训练样本维度是(数据条数×12×24×72),需要占用大量的内存资源。我们在之后构建数据集时,随机抽取了部分样本,大家在实际问题中,如果资源足够的话,可以采用滑窗构建的全部的数据,不过需要注意数据量大的情况下可以考虑构建更深的模型来挖掘更多信息。" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": { - "execution": { - "iopub.execute_input": "2021-10-21T08:34:39.207580Z", - "iopub.status.busy": "2021-10-21T08:34:39.206804Z", - "iopub.status.idle": "2021-10-21T08:34:39.209617Z", - "shell.execute_reply": "2021-10-21T08:34:39.209152Z", - "shell.execute_reply.started": "2021-10-21T07:32:53.823861Z" - }, - "papermill": { - "duration": 0.054979, - "end_time": "2021-10-21T08:34:39.209722", - "exception": false, - "start_time": "2021-10-21T08:34:39.154743", - "status": "completed" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "def make_flatted(train_ds, label_ds, month_sin, month_cos, info, start_idx=0):\n", - " keys = ['sst', 't300', 'ua', 'va']\n", - " label_key = 'nino'\n", - " # 年数\n", - " years = info[1]\n", - " # 模式数\n", - " models = info[2]\n", - " \n", - " train_list = []\n", - " label_list = []\n", - " \n", - " # 将同种模式下的数据拼接起来\n", - " for model_i in range(models):\n", - " blocks = []\n", - " \n", - " # 对每个特征,取每条数据的前12个月进行拼接\n", - " for key in keys:\n", - " block = train_ds[key][start_idx + model_i * years: start_idx + (model_i + 1) * years, :12].reshape(-1, 24, 72, 1).data\n", - " blocks.append(block)\n", - " # 增加sin月份特征\n", - " block_sin = month_sin[start_idx + model_i * years: start_idx + (model_i + 1) * years, :12].reshape(-1, 24, 72, 1)\n", - " blocks.append(block_sin)\n", - " # 增加cos月份特征\n", - " block_cos = month_cos[start_idx + model_i * years: start_idx + (model_i + 1) * years, :12].reshape(-1, 24, 72, 1)\n", - " blocks.append(block_cos)\n", - " \n", - " # 将所有特征在最后一个维度上拼接起来\n", - " train_flatted = np.concatenate(blocks, axis=-1)\n", - " \n", - " # 取12-23月的标签进行拼接,注意加上最后一年的最后12个月的标签(与最后一年12-23月的标签共同构成最后一年前12个月的预测目标)\n", - " label_flatted = np.concatenate([\n", - " label_ds[label_key][start_idx + model_i * years: start_idx + (model_i + 1) * years, 12: 24].reshape(-1).data,\n", - " label_ds[label_key][start_idx + (model_i + 1) * years - 1, 24: 36].reshape(-1).data\n", - " ], axis=0)\n", - " \n", - " train_list.append(train_flatted)\n", - " label_list.append(label_flatted)\n", - " \n", - " return train_list, label_list" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": { - "execution": { - "iopub.execute_input": "2021-10-21T08:34:39.300341Z", - "iopub.status.busy": "2021-10-21T08:34:39.295314Z", - "iopub.status.idle": "2021-10-21T08:35:49.014752Z", - "shell.execute_reply": "2021-10-21T08:35:49.015219Z", - "shell.execute_reply.started": "2021-10-21T07:32:53.840256Z" - }, - "papermill": { - "duration": 69.763875, - "end_time": "2021-10-21T08:35:49.015384", - "exception": false, - "start_time": "2021-10-21T08:34:39.251509", - "status": "completed" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "((1, 1200, 24, 72, 6), (15, 1812, 24, 72, 6), (17, 1680, 24, 72, 6))" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "soda_info = ('soda', 100, 1)\n", - "cmip6_info = ('cmip6', 151, 15)\n", - "cmip5_info = ('cmip5', 140, 17)\n", - "\n", - "soda_trains, soda_labels = make_flatted(soda_train, soda_label, soda_month_sin, soda_month_cos, soda_info)\n", - "cmip6_trains, cmip6_labels = make_flatted(cmip_train, cmip_label, cmip_month_sin, cmip_month_cos, cmip6_info)\n", - "cmip5_trains, cmip5_labels = make_flatted(cmip_train, cmip_label, cmip_month_sin, cmip_month_cos, cmip5_info, cmip6_info[1]*cmip6_info[2])\n", - "\n", - "# 得到扁平化后的数据维度为(模式数×序列长度×纬度×经度×特征数),其中序列长度=年数×12\n", - "np.shape(soda_trains), np.shape(cmip6_trains), np.shape(cmip5_trains)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 0.042107, - "end_time": "2021-10-21T08:35:49.362792", - "exception": false, - "start_time": "2021-10-21T08:35:49.320685", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "#### 空值填充" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 0.041358, - "end_time": "2021-10-21T08:35:49.446119", - "exception": false, - "start_time": "2021-10-21T08:35:49.404761", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "在Task2中我们发现,除SST外,其它特征中都存在空值,这些空值基本都在陆地上,因此我们直接将空值填充为0。" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": { - "execution": { - "iopub.execute_input": "2021-10-21T08:35:49.534919Z", - "iopub.status.busy": "2021-10-21T08:35:49.533787Z", - "iopub.status.idle": "2021-10-21T08:35:49.605898Z", - "shell.execute_reply": "2021-10-21T08:35:49.605473Z", - "shell.execute_reply.started": "2021-10-21T07:33:48.224046Z" - }, - "papermill": { - "duration": 0.118158, - "end_time": "2021-10-21T08:35:49.606021", - "exception": false, - "start_time": "2021-10-21T08:35:49.487863", - "status": "completed" - }, - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Number of null in soda_trains after fillna: 0\n" - ] - } - ], - "source": [ - "# 填充SODA数据中的空值\n", - "soda_trains = np.array(soda_trains)\n", - "soda_trains_nan = np.isnan(soda_trains)\n", - "soda_trains[soda_trains_nan] = 0\n", - "print('Number of null in soda_trains after fillna:', np.sum(np.isnan(soda_trains)))" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": { - "execution": { - "iopub.execute_input": "2021-10-21T08:35:49.696602Z", - "iopub.status.busy": "2021-10-21T08:35:49.695359Z", - "iopub.status.idle": "2021-10-21T08:35:51.395952Z", - "shell.execute_reply": "2021-10-21T08:35:51.396546Z", - "shell.execute_reply.started": "2021-10-21T07:33:48.30097Z" - }, - "papermill": { - "duration": 1.748184, - "end_time": "2021-10-21T08:35:51.396739", - "exception": false, - "start_time": "2021-10-21T08:35:49.648555", - "status": "completed" - }, - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Number of null in cmip6_trains after fillna: 0\n" - ] - } - ], - "source": [ - "# 填充CMIP6数据中的空值\n", - "cmip6_trains = np.array(cmip6_trains)\n", - "cmip6_trains_nan = np.isnan(cmip6_trains)\n", - "cmip6_trains[cmip6_trains_nan] = 0\n", - "print('Number of null in cmip6_trains after fillna:', np.sum(np.isnan(cmip6_trains)))" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": { - "execution": { - "iopub.execute_input": "2021-10-21T08:35:51.488203Z", - "iopub.status.busy": "2021-10-21T08:35:51.487121Z", - "iopub.status.idle": "2021-10-21T08:35:53.450965Z", - "shell.execute_reply": "2021-10-21T08:35:53.451563Z", - "shell.execute_reply.started": "2021-10-21T07:33:50.049562Z" - }, - "papermill": { - "duration": 2.011353, - "end_time": "2021-10-21T08:35:53.451778", - "exception": false, - "start_time": "2021-10-21T08:35:51.440425", - "status": "completed" - }, - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Number of null in cmip6_trains after fillna: 0\n" - ] - } - ], - "source": [ - "# 填充CMIP5数据中的空值\n", - "cmip5_trains = np.array(cmip5_trains)\n", - "cmip5_trains_nan = np.isnan(cmip5_trains)\n", - "cmip5_trains[cmip5_trains_nan] = 0\n", - "print('Number of null in cmip6_trains after fillna:', np.sum(np.isnan(cmip5_trains)))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 0.050131, - "end_time": "2021-10-21T08:35:53.573739", - "exception": false, - "start_time": "2021-10-21T08:35:53.523608", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "#### 构造数据集" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 0.042524, - "end_time": "2021-10-21T08:35:53.658902", - "exception": false, - "start_time": "2021-10-21T08:35:53.616378", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "在划分训练/验证集时,一个需要考虑的问题是训练集、验证集、测试集三者的分布是否是一致的。在本赛题中我们拿到的是两份数据,其中CMIP数据是CMIP5/6模式模拟的历史数据,SODA数据是由SODA模式重建的的历史观测同化数据,线上测试集则是来自国际多个海洋资料的同化数据,由此看来,SODA数据和线上测试集的分布是较为一致的,CMIP数据的分布则与测试集不同。在三者不一致的情况下,我们通常会尽可能使验证集与测试集的分布一致,这样当模型在验证集上有较好的表现时,在测试集上也会有较好的表现。\n", - "\n", - "因此,我们从CMIP数据的每个模式中各抽取100条数据作为训练集(这里抽取的样本数只是作为一个示例,实际模型训练的时候使用多少样本需要综合考虑可用的资源条件和构建的模型深度),从SODA模式中抽取100条数据作为验证集。有的同学可能会疑惑,既然这里只用了100条SODA数据,那么为什么还要对SODA数据扁平化后再抽样而不直接用原始数据呢,因为直接取原始数据的前12个月作为输入,后24个月作为标签所得到的验证集每一条都是从0月开始的,而线上的测试集起始月份是随机抽取的,因此这里仍然要尽可能保证验证集与测试集的数据分布一致,使构建的验证集的起始月份也是随机的。\n", - "\n", - "我们这里没有构造测试集,因为线上的测试集已经公开了,可以直接使用,在比赛时,线上的测试集是保密的,需要构造线下的测试集来评估模型效果,同时需要注意线下的评估结果和线上的提交结果是否差距不大或者变化趋势是一致的,如果不是就需要调整线下的测试集,保证它和线上测试集的分布尽可能一致,能够较为准确地指示模型的调整方向。" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": { - "execution": { - "iopub.execute_input": "2021-10-21T08:35:53.763983Z", - "iopub.status.busy": "2021-10-21T08:35:53.762838Z", - "iopub.status.idle": "2021-10-21T08:35:54.728136Z", - "shell.execute_reply": "2021-10-21T08:35:54.729211Z", - "shell.execute_reply.started": "2021-10-21T07:33:51.83364Z" - }, - "papermill": { - "duration": 1.028157, - "end_time": "2021-10-21T08:35:54.729418", - "exception": false, - "start_time": "2021-10-21T08:35:53.701261", - "status": "completed" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# 构造训练集\n", - "\n", - "X_train = []\n", - "y_train = []\n", - "# 从CMIP5的17种模式中各抽取100条数据\n", - "for model_i in range(17):\n", - " samples = np.random.choice(cmip5_trains.shape[1]-12, size=100)\n", - " for ind in samples:\n", - " X_train.append(cmip5_trains[model_i, ind: ind+12])\n", - " y_train.append(cmip5_labels[model_i][ind: ind+24])\n", - "# 从CMIP6的15种模式种各抽取100条数据\n", - "for model_i in range(15):\n", - " samples = np.random.choice(cmip6_trains.shape[1]-12, size=100)\n", - " for ind in samples:\n", - " X_train.append(cmip6_trains[model_i, ind: ind+12])\n", - " y_train.append(cmip6_labels[model_i][ind: ind+24])\n", - "X_train = np.array(X_train)\n", - "y_train = np.array(y_train)" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": { - "execution": { - "iopub.execute_input": "2021-10-21T08:35:54.882229Z", - "iopub.status.busy": "2021-10-21T08:35:54.880518Z", - "iopub.status.idle": "2021-10-21T08:35:54.910195Z", - "shell.execute_reply": "2021-10-21T08:35:54.910622Z", - "shell.execute_reply.started": "2021-10-21T07:33:52.757012Z" - }, - "papermill": { - "duration": 0.111207, - "end_time": "2021-10-21T08:35:54.910781", - "exception": false, - "start_time": "2021-10-21T08:35:54.799574", - "status": "completed" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# 构造测试集\n", - "\n", - "X_valid = []\n", - "y_valid = []\n", - "samples = np.random.choice(soda_trains.shape[1]-12, size=100)\n", - "for ind in samples:\n", - " X_valid.append(soda_trains[0, ind: ind+12])\n", - " y_valid.append(soda_labels[0][ind: ind+24])\n", - "X_valid = np.array(X_valid)\n", - "y_valid = np.array(y_valid)" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": { - "execution": { - "iopub.execute_input": "2021-10-21T08:35:55.001890Z", - "iopub.status.busy": "2021-10-21T08:35:55.001275Z", - "iopub.status.idle": "2021-10-21T08:35:55.003840Z", - "shell.execute_reply": "2021-10-21T08:35:55.004277Z", - "shell.execute_reply.started": "2021-10-21T07:33:52.794851Z" - }, - "papermill": { - "duration": 0.050316, - "end_time": "2021-10-21T08:35:55.004411", - "exception": false, - "start_time": "2021-10-21T08:35:54.954095", - "status": "completed" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "((3200, 12, 24, 72, 6), (3200, 24), (100, 12, 24, 72, 6), (100, 24))" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# 查看数据集维度\n", - "X_train.shape, y_train.shape, X_valid.shape, y_valid.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": { - "execution": { - "iopub.execute_input": "2021-10-21T08:35:55.250106Z", - "iopub.status.busy": "2021-10-21T08:35:55.249593Z", - "iopub.status.idle": "2021-10-21T08:36:01.890746Z", - "shell.execute_reply": "2021-10-21T08:36:01.890235Z", - "shell.execute_reply.started": "2021-10-21T07:33:52.823277Z" - }, - "papermill": { - "duration": 6.689256, - "end_time": "2021-10-21T08:36:01.890867", - "exception": false, - "start_time": "2021-10-21T08:35:55.201611", - "status": "completed" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# 保存数据集\n", - "np.save('X_train_sample.npy', X_train)\n", - "np.save('y_train_sample.npy', y_train)\n", - "np.save('X_valid_sample.npy', X_valid)\n", - "np.save('y_valid_sample.npy', y_valid)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 0.098733, - "end_time": "2021-10-21T08:36:12.211923", - "exception": false, - "start_time": "2021-10-21T08:36:12.113190", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "### 模型构建" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 1.773797, - "end_time": "2021-10-21T08:36:16.291282", - "exception": false, - "start_time": "2021-10-21T08:36:14.517485", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "在模型构建部分的通用流程是:构造评估函数 -> 构建并训练模型 -> 模型评估,后两步是循环的,可以根据评估结果重新调整并训练模型,再重新进行评估。" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 0.075668, - "end_time": "2021-10-21T08:36:17.665470", - "exception": false, - "start_time": "2021-10-21T08:36:17.589802", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "#### 构造评估函数" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 0.043698, - "end_time": "2021-10-21T08:36:17.765711", - "exception": false, - "start_time": "2021-10-21T08:36:17.722013", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "模型的评估函数通常就是官方给出的评估指标,不过在比赛中经常会出现线下的评估结果和提交后的线上评估结果不一致的情况,这通常是线下测试集和线上测试集不一致造成的。" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": { - "execution": { - "iopub.execute_input": "2021-10-21T08:36:17.860280Z", - "iopub.status.busy": "2021-10-21T08:36:17.859645Z", - "iopub.status.idle": "2021-10-21T08:36:44.573957Z", - "shell.execute_reply": "2021-10-21T08:36:44.573443Z", - "shell.execute_reply.started": "2021-10-21T07:33:59.28935Z" - }, - "papermill": { - "duration": 26.763626, - "end_time": "2021-10-21T08:36:44.574113", - "exception": false, - "start_time": "2021-10-21T08:36:17.810487", - "status": "completed" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# 读取数据集\n", - "X_train = np.load('../input/ai-earth-task03-samples/X_train_sample.npy')\n", - "y_train = np.load('../input/ai-earth-task03-samples/y_train_sample.npy')\n", - "X_valid = np.load('../input/ai-earth-task03-samples/X_valid_sample.npy')\n", - "y_valid = np.load('../input/ai-earth-task03-samples/y_valid_sample.npy')" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": { - "execution": { - "iopub.execute_input": "2021-10-21T08:36:44.667621Z", - "iopub.status.busy": "2021-10-21T08:36:44.667025Z", - "iopub.status.idle": "2021-10-21T08:36:44.669573Z", - "shell.execute_reply": "2021-10-21T08:36:44.669973Z", - "shell.execute_reply.started": "2021-10-21T07:34:22.47373Z" - }, - "papermill": { - "duration": 0.051375, - "end_time": "2021-10-21T08:36:44.670108", - "exception": false, - "start_time": "2021-10-21T08:36:44.618733", - "status": "completed" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "((3200, 12, 24, 72, 6), (3200, 24), (100, 12, 24, 72, 6), (100, 24))" - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "X_train.shape, y_train.shape, X_valid.shape, y_valid.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": { - "execution": { - "iopub.execute_input": "2021-10-21T08:36:44.765455Z", - "iopub.status.busy": "2021-10-21T08:36:44.764773Z", - "iopub.status.idle": "2021-10-21T08:36:44.767388Z", - "shell.execute_reply": "2021-10-21T08:36:44.766961Z", - "shell.execute_reply.started": "2021-10-21T07:34:22.482705Z" - }, - "papermill": { - "duration": 0.054133, - "end_time": "2021-10-21T08:36:44.767495", - "exception": false, - "start_time": "2021-10-21T08:36:44.713362", - "status": "completed" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "def rmse(y_true, y_preds):\n", - " return np.sqrt(mean_squared_error(y_pred = y_preds, y_true = y_true))\n", - "\n", - "# 评估函数\n", - "def score(y_true, y_preds):\n", - " # 相关性技巧评分\n", - " accskill_score = 0\n", - " # RMSE\n", - " rmse_scores = 0\n", - " a = [1.5] * 4 + [2] * 7 + [3] * 7 + [4] * 6\n", - " y_true_mean = np.mean(y_true, axis=0)\n", - " y_pred_mean = np.mean(y_preds, axis=0)\n", - " for i in range(24):\n", - " fenzi = np.sum((y_true[:, i] - y_true_mean[i]) * (y_preds[:, i] - y_pred_mean[i]))\n", - " fenmu = np.sqrt(np.sum((y_true[:, i] - y_true_mean[i])**2) * np.sum((y_preds[:, i] - y_pred_mean[i])**2))\n", - " cor_i = fenzi / fenmu\n", - " accskill_score += a[i] * np.log(i+1) * cor_i\n", - " rmse_score = rmse(y_true[:, i], y_preds[:, i])\n", - " rmse_scores += rmse_score\n", - " return 2/3.0 * accskill_score - rmse_scores" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 0.043425, - "end_time": "2021-10-21T08:36:44.854247", - "exception": false, - "start_time": "2021-10-21T08:36:44.810822", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "#### 模型构造与训练" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 0.043281, - "end_time": "2021-10-21T08:36:44.941695", - "exception": false, - "start_time": "2021-10-21T08:36:44.898414", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "这部分是赛题的重点,该TOP方案采用的是CNN+LSTM的串行结构,其中CNN用来提取空间信息,LSTM用来提取时间信息。\n", - "\n", - "- CNN部分\n", - "\n", - "CNN常用于处理图像信息,它在处理空间信息上也有很好的表现。CNN的输入尺寸是(Batch,H,W,C),其中Batch是批量梯度下降中一个批次的样本数量,H和W分别是输入图像的高和宽,C是输入图像的通道数,对于本题中的空间数据,H和W就对应数据的纬度和经度,C对应特征数。我们的训练样本中还多了一个时间维度,因此需要用TimeDistributed来包装卷积层。\n", - "\n", - "TimeDistributed是一个层封装器,它的参数是一个神经网络层,它的作用是将这个网络层应用到输入的每一个时间步上。例如,我们的每个输入样本的维度是(12,24,72,6),用TimeDistributed包装卷积层Conv2D,它就会将卷积层应用于这12个时间步的每一个,而卷积层作用的输入维度就是(24,72,6)。说明文档可以参考https://keras.io/zh/layers/wrappers/\n", - "\n", - "BatchNormalization(后面简称BN)是批标准化层,通常放在卷积层后用于标准化数据的分布,能够减少各层不同数据分布之间的相互影响和依赖,具有加快模型训练速度、避免梯度爆炸、在一定程度上能增强模型泛化能力等优点,是神经网络问题中常用的“大杀器”。不过目前关于BN层和ReLU激活函数的放置顺序孰先孰后的问题众说纷纭,具体还是看模型的效果。关于这个问题的讨论可以参考https://www.zhihu.com/question/283715823\n", - "\n", - "总体来看CNN这一部分采用的是比较通用的结构,第一层采用比较大的卷积核(7×7),后面接多层的小卷积核(3×3),并用BN提升模型效果,用池化层减少模型参数,池化层常用的有MaxPooling和AveragePooling,通常MaxPooling效果更好,不过具体看模型效果。模型的主要难点就在于调参,目前模型调参没有标准的答案,更多地是参考前人的经验以及不断地尝试。\n", - "\n", - "- LSTM部分\n", - "\n", - "CNN部分经过Flatten层将除时间维度以外的维度压平(即除时间步长12外的其它维度大小相乘,例如CNN部分最后的池化层输出维度是(T,H,W,C),则压平后的维度是(T,H×W×C)),输入LSTM层。LSTM层接受的输入维度为(Time_steps,Input_size),其中Time_steps就是时间步长12,Input_size是压平后的维度大小。keras中LSTM的主要参数是units(输出维度)、activation(激活函数)、return_sequences(是否返回最后一个输出),return_sequences为True时返回的是全部的时间序列,即维度是(Time_steps,units),为False时只返回最后一个时间步的输出,即维度(units)。LSTM的使用方法可以参考https://keras.io/zh/layers/recurrent/\n", - "\n", - "LSTM的参数量是4倍的Input_size×units,参数量过多就容易过拟合,同时我们之间构建的训练样本也不够多,因此该方案中只堆叠了两个LSTM层。" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": { - "execution": { - "iopub.execute_input": "2021-10-21T08:36:45.040366Z", - "iopub.status.busy": "2021-10-21T08:36:45.038883Z", - "iopub.status.idle": "2021-10-21T08:36:45.041004Z", - "shell.execute_reply": "2021-10-21T08:36:45.041437Z", - "shell.execute_reply.started": "2021-10-21T07:34:22.495345Z" - }, - "papermill": { - "duration": 0.056263, - "end_time": "2021-10-21T08:36:45.041562", - "exception": false, - "start_time": "2021-10-21T08:36:44.985299", - "status": "completed" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# 模型构造\n", - "def build_model(learning_rate, reg_lambda = 0.001): \n", - " # 定义模型输入\n", - " inp = tf.keras.layers.Input(shape=(12, 24, 72, 6))\n", - "\n", - " # CNN部分\n", - " x = TimeDistributed(Conv2D(32, (7, 7), strides=(2, 2), padding='same', kernel_regularizer=L2(reg_lambda)))(inp)\n", - " x = TimeDistributed(BatchNormalization())(x)\n", - " x = TimeDistributed(Activation('relu'))(x)\n", - " x = TimeDistributed(Conv2D(32, (3, 3), padding='same', kernel_regularizer=L2(reg_lambda)))(x)\n", - " x = TimeDistributed(BatchNormalization())(x)\n", - " x = TimeDistributed(Activation('relu'))(x)\n", - " x = TimeDistributed(AveragePooling2D((2, 2), strides=(2, 2)))(x)\n", - " x = TimeDistributed(Flatten())(x)\n", - "\n", - " # LSTM部分\n", - " x = LSTM(2048, return_sequences=True, dropout=0.5)(x)\n", - " x = LSTM(1024, return_sequences=False)(x)\n", - "\n", - " # 模型输出\n", - " out = Dense(24, activation='linear')(x)\n", - " # 建立模型\n", - " model = Model(inputs=inp, outputs=out)\n", - " # 使用RMSprop作为模型优化器\n", - " opt = tf.optimizers.RMSprop(lr=learning_rate)\n", - " # 模型编译,损失函数是MSE,赛题的评估指标中包括相关系数,因此用皮尔逊相关系数作为评价指标\n", - " model.compile(optimizer = opt, loss = 'mean_squared_error', metrics=[tfp.stats.correlation])\n", - "\n", - " return model" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "metadata": { - "execution": { - "iopub.execute_input": "2021-10-21T08:36:45.132800Z", - "iopub.status.busy": "2021-10-21T08:36:45.132250Z", - "iopub.status.idle": "2021-10-21T08:36:56.798808Z", - "shell.execute_reply": "2021-10-21T08:36:56.799273Z", - "shell.execute_reply.started": "2021-10-21T07:34:22.509438Z" - }, - "papermill": { - "duration": 11.713938, - "end_time": "2021-10-21T08:36:56.799449", - "exception": false, - "start_time": "2021-10-21T08:36:45.085511", - "status": "completed" - }, - "tags": [] - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2021-10-21 08:36:45.169856: I tensorflow/compiler/jit/xla_cpu_device.cc:41] Not creating XLA devices, tf_xla_enable_xla_devices not set\n", - "2021-10-21 08:36:45.188233: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcuda.so.1\n", - "2021-10-21 08:36:45.232270: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:941] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", - "2021-10-21 08:36:45.232902: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1720] Found device 0 with properties: \n", - "pciBusID: 0000:00:04.0 name: Tesla P100-PCIE-16GB computeCapability: 6.0\n", - "coreClock: 1.3285GHz coreCount: 56 deviceMemorySize: 15.90GiB deviceMemoryBandwidth: 681.88GiB/s\n", - "2021-10-21 08:36:45.232956: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcudart.so.11.0\n", - "2021-10-21 08:36:45.257289: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcublas.so.11\n", - "2021-10-21 08:36:45.257378: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcublasLt.so.11\n", - "2021-10-21 08:36:45.272163: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcufft.so.10\n", - "2021-10-21 08:36:45.282284: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcurand.so.10\n", - "2021-10-21 08:36:45.304691: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcusolver.so.10\n", - "2021-10-21 08:36:45.311689: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcusparse.so.11\n", - "2021-10-21 08:36:45.315511: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcudnn.so.8\n", - "2021-10-21 08:36:45.315715: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:941] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", - "2021-10-21 08:36:45.316504: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:941] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", - "2021-10-21 08:36:45.318221: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1862] Adding visible gpu devices: 0\n", - "2021-10-21 08:36:45.319598: I tensorflow/core/platform/cpu_feature_guard.cc:142] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2 AVX512F FMA\n", - "To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.\n", - "2021-10-21 08:36:45.320163: I tensorflow/compiler/jit/xla_gpu_device.cc:99] Not creating XLA devices, tf_xla_enable_xla_devices not set\n", - "2021-10-21 08:36:45.320318: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:941] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", - "2021-10-21 08:36:45.320903: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1720] Found device 0 with properties: \n", - "pciBusID: 0000:00:04.0 name: Tesla P100-PCIE-16GB computeCapability: 6.0\n", - "coreClock: 1.3285GHz coreCount: 56 deviceMemorySize: 15.90GiB deviceMemoryBandwidth: 681.88GiB/s\n", - "2021-10-21 08:36:45.320949: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcudart.so.11.0\n", - "2021-10-21 08:36:45.320972: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcublas.so.11\n", - "2021-10-21 08:36:45.320989: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcublasLt.so.11\n", - "2021-10-21 08:36:45.321007: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcufft.so.10\n", - "2021-10-21 08:36:45.321024: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcurand.so.10\n", - "2021-10-21 08:36:45.321041: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcusolver.so.10\n", - "2021-10-21 08:36:45.321074: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcusparse.so.11\n", - "2021-10-21 08:36:45.321094: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcudnn.so.8\n", - "2021-10-21 08:36:45.321172: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:941] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", - "2021-10-21 08:36:45.321788: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:941] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", - "2021-10-21 08:36:45.322321: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1862] Adding visible gpu devices: 0\n", - "2021-10-21 08:36:45.323423: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcudart.so.11.0\n", - "2021-10-21 08:36:46.735623: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1261] Device interconnect StreamExecutor with strength 1 edge matrix:\n", - "2021-10-21 08:36:46.735693: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1267] 0 \n", - "2021-10-21 08:36:46.735705: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1280] 0: N \n", - "2021-10-21 08:36:46.738201: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:941] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", - "2021-10-21 08:36:46.738896: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:941] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", - "2021-10-21 08:36:46.739585: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:941] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", - "2021-10-21 08:36:46.740224: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1406] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 14957 MB memory) -> physical GPU (device: 0, name: Tesla P100-PCIE-16GB, pci bus id: 0000:00:04.0, compute capability: 6.0)\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Model: \"model\"\n", - "_________________________________________________________________\n", - "Layer (type) Output Shape Param # \n", - "=================================================================\n", - "input_1 (InputLayer) [(None, 12, 24, 72, 6)] 0 \n", - "_________________________________________________________________\n", - "time_distributed (TimeDistri (None, 12, 12, 36, 32) 9440 \n", - "_________________________________________________________________\n", - "time_distributed_1 (TimeDist (None, 12, 12, 36, 32) 128 \n", - "_________________________________________________________________\n", - "time_distributed_2 (TimeDist (None, 12, 12, 36, 32) 0 \n", - "_________________________________________________________________\n", - "time_distributed_3 (TimeDist (None, 12, 12, 36, 32) 9248 \n", - "_________________________________________________________________\n", - "time_distributed_4 (TimeDist (None, 12, 12, 36, 32) 128 \n", - "_________________________________________________________________\n", - "time_distributed_5 (TimeDist (None, 12, 12, 36, 32) 0 \n", - "_________________________________________________________________\n", - "time_distributed_6 (TimeDist (None, 12, 6, 18, 32) 0 \n", - "_________________________________________________________________\n", - "time_distributed_7 (TimeDist (None, 12, 3456) 0 \n", - "_________________________________________________________________\n", - "lstm (LSTM) (None, 12, 2048) 45096960 \n", - "_________________________________________________________________\n", - "lstm_1 (LSTM) (None, 1024) 12587008 \n", - "_________________________________________________________________\n", - "dense (Dense) (None, 24) 24600 \n", - "=================================================================\n", - "Total params: 57,727,512\n", - "Trainable params: 57,727,384\n", - "Non-trainable params: 128\n", - "_________________________________________________________________\n" - ] - } - ], - "source": [ - "learning_rate = 3e-4\n", - "model = build_model(learning_rate)\n", - "model.summary()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 0.086136, - "end_time": "2021-10-21T08:36:56.959801", - "exception": false, - "start_time": "2021-10-21T08:36:56.873665", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "在模型训练时,有一些常用的回调函数:\n", - "\n", - "- ModelCheckPoint:在每个训练周期后保存模型,其中参数monitor为模型的监测指标,save_best_only设为True时监测指标最优的模型不会被覆盖,mode用来定义监测指标为最大或最小时模型最优。\n", - "\n", - "- EarlyStopping:早停,当监测指标在设定的训练轮数内不再提升时停止训练,其中参数patience为可容忍的指标不提升的训练轮数。\n", - "\n", - "- ReduceLROnPlateau:当监测指标在设定的训练轮数内不提升时降低学习率,其中参数factor为学习率降低的因数,新的学习率=factor×学习率。\n", - "\n", - "也可以通过扩展keras.callbacks.Callback子类自定义回调函数,回调函数的详细说明文档参考https://keras.io/zh/callbacks/" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": { - "execution": { - "iopub.execute_input": "2021-10-21T08:36:57.116361Z", - "iopub.status.busy": "2021-10-21T08:36:57.115544Z", - "iopub.status.idle": "2021-10-21T08:37:47.289623Z", - "shell.execute_reply": "2021-10-21T08:37:47.290008Z", - "shell.execute_reply.started": "2021-10-21T07:34:34.87517Z" - }, - "papermill": { - "duration": 50.257025, - "end_time": "2021-10-21T08:37:47.290202", - "exception": false, - "start_time": "2021-10-21T08:36:57.033177", - "status": "completed" - }, - "tags": [] - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2021-10-21 08:36:57.784602: W tensorflow/core/framework/cpu_allocator_impl.cc:80] Allocation of 1592524800 exceeds 10% of free system memory.\n", - "2021-10-21 08:36:59.036796: I tensorflow/compiler/mlir/mlir_graph_optimization_pass.cc:116] None of the MLIR optimization passes are enabled (registered 2)\n", - "2021-10-21 08:36:59.047003: I tensorflow/core/platform/profile_utils/cpu_utils.cc:112] CPU Frequency: 2000175000 Hz\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Epoch 1/100\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2021-10-21 08:37:02.406166: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcublas.so.11\n", - "2021-10-21 08:37:03.215041: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcublasLt.so.11\n", - "2021-10-21 08:37:03.263644: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcudnn.so.8\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "13/13 - 14s - loss: 1.3441 - correlation: 0.1157 - val_loss: 0.6378 - val_correlation: 0.0037\n", - "Epoch 2/100\n", - "13/13 - 3s - loss: 0.7360 - correlation: 0.3312 - val_loss: 0.6181 - val_correlation: -2.5095e-02\n", - "Epoch 3/100\n", - "13/13 - 3s - loss: 0.6452 - correlation: 0.3593 - val_loss: 0.6477 - val_correlation: 0.0056\n", - "Epoch 4/100\n", - "13/13 - 3s - loss: 0.6014 - correlation: 0.3569 - val_loss: 0.5507 - val_correlation: 0.0564\n", - "Epoch 5/100\n", - "13/13 - 3s - loss: 0.5556 - correlation: 0.3744 - val_loss: 0.7436 - val_correlation: 0.0612\n", - "Epoch 6/100\n", - "13/13 - 3s - loss: 0.5406 - correlation: 0.3820 - val_loss: 0.5429 - val_correlation: 0.0884\n", - "Epoch 7/100\n", - "13/13 - 3s - loss: 0.5221 - correlation: 0.3952 - val_loss: 0.5681 - val_correlation: 0.0911\n", - "Epoch 8/100\n", - "13/13 - 3s - loss: 0.5108 - correlation: 0.3954 - val_loss: 0.5944 - val_correlation: 0.0773\n", - "Epoch 9/100\n", - "13/13 - 3s - loss: 0.5015 - correlation: 0.3890 - val_loss: 0.5569 - val_correlation: 0.0708\n", - "Epoch 10/100\n", - "13/13 - 3s - loss: 0.4667 - correlation: 0.4111 - val_loss: 0.6913 - val_correlation: 0.0682\n", - "Epoch 11/100\n", - "13/13 - 3s - loss: 0.4765 - correlation: 0.3947 - val_loss: 0.5667 - val_correlation: 0.0573\n" - ] - } - ], - "source": [ - "# 模型权重的保存路径\n", - "model_weights = './cnn_lstm_baseline.h5'\n", - "# 设置回调函数\n", - "checkpoint = ModelCheckpoint(model_weights, monitor='val_loss', verbose=0, save_best_only=True, mode='min',\n", - " save_weights_only=True)\n", - "early_stopping = EarlyStopping(monitor=\"val_loss\", patience=5)\n", - "# 训练模型并保存训练历史\n", - "history = model.fit(X_train, y_train,\n", - " validation_data=(X_valid, y_valid),\n", - " batch_size=256, epochs=100,\n", - " callbacks=[checkpoint, early_stopping],\n", - " verbose=2)" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": { - "execution": { - "iopub.execute_input": "2021-10-21T08:37:47.395893Z", - "iopub.status.busy": "2021-10-21T08:37:47.395241Z", - "iopub.status.idle": "2021-10-21T08:37:47.397833Z", - "shell.execute_reply": "2021-10-21T08:37:47.398300Z", - "shell.execute_reply.started": "2021-10-21T07:35:18.697369Z" - }, - "papermill": { - "duration": 0.057627, - "end_time": "2021-10-21T08:37:47.398433", - "exception": false, - "start_time": "2021-10-21T08:37:47.340806", - "status": "completed" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "dict_keys(['loss', 'correlation', 'val_loss', 'val_correlation'])" - ] - }, - "execution_count": 27, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# 查看训练历史中保存的监测指标\n", - "history.history.keys()" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": { - "execution": { - "iopub.execute_input": "2021-10-21T08:37:47.506459Z", - "iopub.status.busy": "2021-10-21T08:37:47.500913Z", - "iopub.status.idle": "2021-10-21T08:37:47.508858Z", - "shell.execute_reply": "2021-10-21T08:37:47.508473Z", - "shell.execute_reply.started": "2021-10-21T07:35:18.710206Z" - }, - "papermill": { - "duration": 0.060176, - "end_time": "2021-10-21T08:37:47.508960", - "exception": false, - "start_time": "2021-10-21T08:37:47.448784", - "status": "completed" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# 绘制训练/验证曲线\n", - "def training_vis(hist):\n", - " loss = hist.history['loss']\n", - " val_loss = hist.history['val_loss']\n", - " corr = hist.history['correlation']\n", - " val_corr = hist.history['val_correlation']\n", - " \n", - " # 绘制损失函数曲线\n", - " fig = plt.figure(figsize=(8,4))\n", - " # subplot loss\n", - " ax1 = fig.add_subplot(121)\n", - " ax1.plot(loss,label='train_loss')\n", - " ax1.plot(val_loss,label='val_loss')\n", - " ax1.set_xlabel('Epochs')\n", - " ax1.set_ylabel('Loss')\n", - " ax1.set_title('Loss on Training and Validation Data')\n", - " ax1.legend()\n", - " # 绘制皮尔逊相关系数曲线\n", - " ax2 = fig.add_subplot(122)\n", - " ax2.plot(corr,label='train_pearson_correction')\n", - " ax2.plot(val_corr,label='val_pearson_correction')\n", - " ax2.set_xlabel('Epochs')\n", - " ax2.set_ylabel('Pearson Correction')\n", - " ax2.set_title('Pearson Correction on Training and Validation Data')\n", - " ax2.legend()\n", - " plt.tight_layout()" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "metadata": { - "execution": { - "iopub.execute_input": "2021-10-21T08:37:47.616609Z", - "iopub.status.busy": "2021-10-21T08:37:47.615925Z", - "iopub.status.idle": "2021-10-21T08:37:48.168871Z", - "shell.execute_reply": "2021-10-21T08:37:48.169327Z", - "shell.execute_reply.started": "2021-10-21T07:35:18.734126Z" - }, - "papermill": { - "duration": 0.610561, - "end_time": "2021-10-21T08:37:48.169482", - "exception": false, - "start_time": "2021-10-21T08:37:47.558921", - "status": "completed" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "image/png": "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Zjz++ONERUUBsH//flasWMGPP/5IWFiYtSHh7u8gi8XCsmXL6NSpE23atGHq1Kmkp6cDWPehP/zwAx07drzvd8PdnJ2dady4McuXLyclJYWNGzcCxd+PQ+4PqkcffZTmzZvzxBNPWPdVBZLKoU6dOkl//PHHPcsXLVokDRo0SLp586Z069YtaciQIdLChQslSZKkefPmSTNmzJAMBoNkMBikI0eOSBaLRbp06ZLUvn17KSEhQZIkSYqNjZViYmLyvd8pU6ZIY8aMkdLT06XY2FipW7du0nfffSdJkiR9//33UoMGDaRvv/1WMplM0ldffSU9+uijksViKfJjOXTokFS/fn3pgw8+kPR6vZSdnS0lJSVJO3fulLKysqT09HRp3Lhx0osvvmi9/ZNPPlnkDMVZd/DgwdJ7770n6fV66ciRI1JYWJg0adKkfB9DUTJ27txZunz5spSdnS09+eST0ocffihJkiRduHBBatq0qXT48GFJr9dL7777rlS/fv18X19JkqTNmzdLXbt2tV6+dOmSFBoaKt26davYz9XQoUMlSZKkW7duSU2bNpV+/PFHyWAwSGvWrJHq169vXTc6Olr6/fffJb1eL926dUsaPny49M477+T7GkpS7nuoTp06ktFolCRJkoYPHy69+eabUk5OjnT27FmpVatW0oEDByRJkqSPPvpIatiwobR3717JZDJJ8+bNkwYNGpTvY5ckSapTp44UHR2dZ5nBYJDq168v7d27V5IkSdqzZ48UExMjWSwW6c8//5QaN24snT59WpKk3PdYu3bt8tz+1KlT0rFjxySj0SjFxsZKPXr0kNasWVNghodx93MVFxcn9erVS1q4cKGUkJAgtWzZUtq7d69kNpul33//XWrZsqV069atIj2m/35uCvq8GwwGqUuXLtLy5cslvV4vHThwQGratKl06dIlSZIkadq0aVLLli2lEydOSEajUZo4caL08ssv5/tYPvzwQ+mJJ54o9PHe77Vv0KCB9Msvv0hms9n62ejQoYP0zz//SEajUUpLS5Pat28vbdiwQTIajdKZM2ekli1bShcuXJAkSZJmzZolPfnkk1JCQoJkMpmkv/76S9Lr9fe8ByUp73s+OTlZCg8Pl3744QfJaDRKW7dulcLDw6WkpCRJkgr/zP7XgQMHpJYtW0qnT5+W9Hq9NHv2bGn48OHW6+vU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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "training_vis(history)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 0.052239, - "end_time": "2021-10-21T08:37:48.274375", - "exception": false, - "start_time": "2021-10-21T08:37:48.222136", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "我们通常会绘制训练/验证曲线来观察模型的拟合情况,上图中我们分别绘制了训练过程中训练集和验证集损失函数变化曲线及皮尔逊相关系数变化曲线。可以看到,训练集的损失函数下降很快,但是验证集的损失函数是震荡的,没有明显的下降,这说明模型的学习效果较差,并存在过拟合问题,需要调整相关的参数。" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 0.052433, - "end_time": "2021-10-21T08:37:48.378513", - "exception": false, - "start_time": "2021-10-21T08:37:48.326080", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "#### 模型评估" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 0.052227, - "end_time": "2021-10-21T08:37:48.482691", - "exception": false, - "start_time": "2021-10-21T08:37:48.430464", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "最后,我们在测试集上评估模型的训练结果。" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "metadata": { - "execution": { - "iopub.execute_input": "2021-10-21T08:37:48.591549Z", - "iopub.status.busy": "2021-10-21T08:37:48.589978Z", - "iopub.status.idle": "2021-10-21T08:37:48.592228Z", - "shell.execute_reply": "2021-10-21T08:37:48.592641Z", - "shell.execute_reply.started": "2021-10-21T07:35:19.299402Z" - }, - "papermill": { - "duration": 0.058168, - "end_time": "2021-10-21T08:37:48.592764", - "exception": false, - "start_time": "2021-10-21T08:37:48.534596", - "status": "completed" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# 测试集路径\n", - "test_path = '../input/ai-earth-tests/'\n", - "# 测试集标签路径\n", - "test_label_path = '../input/ai-earth-tests-labels/'" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": { - "execution": { - "iopub.execute_input": "2021-10-21T08:37:48.700839Z", - "iopub.status.busy": "2021-10-21T08:37:48.700337Z", - "iopub.status.idle": "2021-10-21T08:37:50.775691Z", - "shell.execute_reply": "2021-10-21T08:37:50.775160Z", - "shell.execute_reply.started": "2021-10-21T07:35:19.305668Z" - }, - "papermill": { - "duration": 2.131472, - "end_time": "2021-10-21T08:37:50.775812", - "exception": false, - "start_time": "2021-10-21T08:37:48.644340", - "status": "completed" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "import os\n", - "\n", - "# 读取测试数据和测试数据的标签,并记录每个测试样本的起始月份用于之后构造月份特征\n", - "files = os.listdir(test_path)\n", - "X_test = []\n", - "y_test = []\n", - "first_months = [] # 样本起始月份\n", - "for file in files:\n", - " X_test.append(np.load(test_path + file))\n", - " y_test.append(np.load(test_label_path + file))\n", - " first_months.append(int(file.split('_')[2]))" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "metadata": { - "execution": { - "iopub.execute_input": "2021-10-21T08:37:50.883377Z", - "iopub.status.busy": "2021-10-21T08:37:50.882583Z", - "iopub.status.idle": "2021-10-21T08:37:50.915462Z", - "shell.execute_reply": "2021-10-21T08:37:50.915886Z", - "shell.execute_reply.started": "2021-10-21T07:35:20.609718Z" - }, - "papermill": { - "duration": 0.087729, - "end_time": "2021-10-21T08:37:50.916030", - "exception": false, - "start_time": "2021-10-21T08:37:50.828301", - "status": "completed" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "((103, 12, 24, 72, 4), (103, 24))" - ] - }, - "execution_count": 32, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "X_test = np.array(X_test)\n", - "y_test = np.array(y_test)\n", - "X_test.shape, y_test.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "metadata": { - "execution": { - "iopub.execute_input": "2021-10-21T08:37:51.041980Z", - "iopub.status.busy": "2021-10-21T08:37:51.026639Z", - "iopub.status.idle": "2021-10-21T08:37:53.550451Z", - "shell.execute_reply": "2021-10-21T08:37:53.549927Z", - "shell.execute_reply.started": "2021-10-21T07:35:20.64156Z" - }, - "papermill": { - "duration": 2.582112, - "end_time": "2021-10-21T08:37:53.550590", - "exception": false, - "start_time": "2021-10-21T08:37:50.968478", - "status": "completed" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "(103, 12, 24, 72, 1)" - ] - }, - "execution_count": 33, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# 构造一个维度为103*12*24*72的矩阵,矩阵中的每个值为所在月份的sin函数值\n", - "test_month_sin = np.zeros((103, 12, 24, 72, 1))\n", - "for y in range(103):\n", - " for m in range(12):\n", - " for lat in range(24):\n", - " for lon in range(72):\n", - " test_month_sin[y, m, lat, lon] = math.sin(2 * math.pi * ((m + first_months[y]-1) % 12) / 12)\n", - " \n", - "test_month_sin.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "metadata": { - "execution": { - "iopub.execute_input": "2021-10-21T08:37:53.675778Z", - "iopub.status.busy": "2021-10-21T08:37:53.670723Z", - "iopub.status.idle": "2021-10-21T08:37:56.410740Z", - "shell.execute_reply": "2021-10-21T08:37:56.409934Z", - "shell.execute_reply.started": "2021-10-21T07:35:23.273485Z" - }, - "papermill": { - "duration": 2.807623, - "end_time": "2021-10-21T08:37:56.410875", - "exception": false, - "start_time": "2021-10-21T08:37:53.603252", - "status": "completed" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "(103, 12, 24, 72, 1)" - ] - }, - "execution_count": 34, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# 构造一个维度为103*12*24*72的矩阵,矩阵中的每个值为所在月份的cos函数值\n", - "test_month_cos = np.zeros((103, 12, 24, 72, 1))\n", - "for y in range(103):\n", - " for m in range(12):\n", - " for lat in range(24):\n", - " for lon in range(72):\n", - " test_month_cos[y, m, lat, lon] = math.cos(2 * math.pi * ((m + first_months[y]-1) % 12) / 12)\n", - " \n", - "test_month_cos.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "metadata": { - "execution": { - "iopub.execute_input": "2021-10-21T08:37:56.523692Z", - "iopub.status.busy": "2021-10-21T08:37:56.522698Z", - "iopub.status.idle": "2021-10-21T08:37:56.621342Z", - "shell.execute_reply": "2021-10-21T08:37:56.621786Z", - "shell.execute_reply.started": "2021-10-21T07:35:26.130568Z" - }, - "papermill": { - "duration": 0.156901, - "end_time": "2021-10-21T08:37:56.621938", - "exception": false, - "start_time": "2021-10-21T08:37:56.465037", - "status": "completed" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "(103, 12, 24, 72, 6)" - ] - }, - "execution_count": 35, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# 构造测试集\n", - "X_test = np.concatenate([X_test, test_month_sin, test_month_cos], axis=-1)\n", - "X_test.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "metadata": { - "execution": { - "iopub.execute_input": "2021-10-21T08:37:56.737281Z", - "iopub.status.busy": "2021-10-21T08:37:56.736222Z", - "iopub.status.idle": "2021-10-21T08:37:57.539110Z", - "shell.execute_reply": "2021-10-21T08:37:57.538581Z", - "shell.execute_reply.started": "2021-10-21T07:35:26.223121Z" - }, - "papermill": { - "duration": 0.862712, - "end_time": "2021-10-21T08:37:57.539248", - "exception": false, - "start_time": "2021-10-21T08:37:56.676536", - "status": "completed" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# 模型预测\n", - "test_preds = model.predict(X_test)" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "metadata": { - "execution": { - "iopub.execute_input": "2021-10-21T08:37:57.651690Z", - "iopub.status.busy": "2021-10-21T08:37:57.651142Z", - "iopub.status.idle": "2021-10-21T08:37:57.661968Z", - "shell.execute_reply": "2021-10-21T08:37:57.661476Z", - "shell.execute_reply.started": "2021-10-21T07:35:27.056238Z" - }, - "papermill": { - "duration": 0.068392, - "end_time": "2021-10-21T08:37:57.662122", - "exception": false, - "start_time": "2021-10-21T08:37:57.593730", - "status": "completed" - }, - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "22.950661372376207\n" - ] - } - ], - "source": [ - "# 模型评估\n", - "score = score(y_test, test_preds)\n", - "print(score)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 0.052837, - "end_time": "2021-10-21T08:37:57.768864", - "exception": false, - "start_time": "2021-10-21T08:37:57.716027", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "## 总结" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 0.055249, - "end_time": "2021-10-21T08:37:57.877253", - "exception": false, - "start_time": "2021-10-21T08:37:57.822004", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "- 该方案在数据处理部分增加了一组月份特征,个人认为在使用了时序模型的情况下增加的这组特征收益不高,并且由于维度增加会使得训练数据占用内存大大增加,在本赛题中对模型的效果提升不明显。不过在其他场景中这种特征构造方法仍然是值得借鉴的。\n", - "- 该方案构造模型的思路非常适合初学者学习,灵活地将不同模型串行结合能够结合模型各自的优势,这种模型构造方法需要注意的是一个模型的输出维度与另一个模型接受的输入维度要相互匹配。" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "papermill": { - "duration": 0.053315, - "end_time": "2021-10-21T08:37:57.984690", - "exception": false, - "start_time": "2021-10-21T08:37:57.931375", - "status": "completed" - }, - "tags": [] - }, - "source": [ - "## 参考文献\n", - "1. “学习AI的打工人”经验分享:https://tianchi.aliyun.com/notebook-ai/detail?spm=5176.12586969.1002.18.561d5330HKwYOW&postId=196536" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "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.7.3" - }, - "papermill": { - "default_parameters": {}, - "duration": 686.839871, - "end_time": "2021-10-21T08:38:01.166078", - "environment_variables": {}, - "exception": null, - "input_path": "__notebook__.ipynb", - "output_path": "__notebook__.ipynb", - "parameters": {}, - "start_time": "2021-10-21T08:26:34.326207", - "version": "2.3.3" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -}