人工智能翻新挑战赛:陆地气象预测Baseline[4]完整版(TensorFlow、torch版本)含数据转化、模型构建、MLP、TCNN+RNN、LSTM模型训练以及预测
1.赛题简介
我的项目链接以及码源见文末
2021 “AI Earth” 人工智能翻新挑战赛,以 “AI 助力精准气象和陆地预测” 为主题,旨在摸索人工智能技术在气象和陆地畛域的利用。
本赛题的背景是厄尔尼诺 – 北方涛动(ENSO)景象。ENSO景象是厄尔尼诺(EN)景象和北方涛动(SO)景象的合称,其中厄尔尼诺景象是指赤道中东太平洋左近的海表面温度继续异样增暖的景象,北方涛动景象是指寒带东太平洋与寒带西太平洋气压场存在的气压变动相同的跷跷板景象。厄尔尼诺景象和北方涛动景象理论是反常气象别离在陆地和大气中的体现,二者密切相关,因而合称为厄尔尼诺 – 北方涛动景象。
ENSO景象会在世界大部分地区引起极其天气,对寰球的天气、气象以及粮食产量具备重要的影响,精确预测ENSO,是进步东亚和寰球气象预测程度和防灾减灾的要害。Nino3.4指数是ENSO景象监测的一个重要指标,它是指Nino3.4区(170°W – 120°W,5°S – 5°N)的均匀海温距平指数,用于反馈海表温度异样,若Nino3.4指数间断5个月超过0.5℃就断定为一次ENSO事件。本赛题的指标,就是基于历史气象观测和模式模仿数据,利用T时刻过来12个月(蕴含T时刻)的时空序列,预测将来1 – 24个月的Nino3.4指数。
基于以上信息能够看出,咱们本期的组队学习要实现的是一个时空序列的预测工作。
比赛题目
数据简介
本赛题应用的训练数据包含CMIP5中17个模式提供的140年的历史模仿数据、CMIP6中15个模式提供的151年的历史模仿数据和美国SODA模式重建的100年的历史观测异化数据,采纳nc格局保留,其中CMIP5和CMIP6别离是世界气象钻研打算(WCRP)的第5次和第6次耦合模式比拟打算,这二者都提供了多种不同的气象模式对于多种气象变量的模仿数据。这些数据蕴含四种气象变量:海表温度异样(SST)、热含量异样(T300)、纬向风异样(Ua)、经向风异样(Va),数据维度为(year, month, lat, lon),对于训练数据提供对应月份的Nino3.4指数标签数据。简而言之,提供的训练数据中的每个样本为某年、某月、某个维度、某个经度的SST、T300、Ua、Va数值,标签为对应年、对应月的Nino3.4指数。
须要留神的是,样本的第二维度month的长度不是12个月,而是36个月,对应从以后year开始间断三年的数据,例如SODA训练数据中year为0时蕴含的是从第1 – 第3年逐月的历史观测数据,year为1时蕴含的是从第2年 – 第4年逐月的历史观测数据,也就是说,样本在工夫上是有穿插的。
另外一点须要留神的是,Nino3.4指数是Nino3.4区域从以后月开始间断三个月的SST平均值,也就是说,咱们也能够不间接预测Nino3.4指数,而是以SST为预测指标,间接求得Nino3.4指数。
测试数据为国内多个陆地材料异化后果提供的随机抽取的$N$段长度为12个月的工夫序列,数据采纳npy格局保留,维度为(12, lat, lon, 4),第一维度为间断的12个月份,第四维度为4个气象变量,按SST、T300、Ua、Va的程序寄存。测试集文件序列的命名如test_00001_01_12.npy中00001示意编号,01示意起始月份,12示意终止月份。
训练数据阐明
每个数据样本第一维度(year)表征数据所对应起始年份,对于CMIP数据共4645年,其中1-2265为CMIP6中15个模式提供的151年的历史模仿数据(总共:151年 15 个模式=2265);2266-4645为CMIP5中17个模式提供的140年的历史模仿数据(总共:140年 17 个模式=2380)。对于历史观测异化数据为美国提供的SODA数据。
其中每个样本第二维度(mouth)表征数据对应的月份,对于训练数据均为36,对应的从以后年份开始间断三年数据(从1月开始,共36月),比方:
SODA_train.nc中[0,0:36,:,:]为第1-第3年逐月的历史观测数据;
SODA_train.nc中[1,0:36,:,:]为第2-第4年逐月的历史观测数据;
…,
SODA_train.nc中[99,0:36,:,:]为第100-102年逐月的历史观测数据。
和
CMIP_train.nc中[0,0:36,:,:]为CMIP6第一个模式提供的第1-第3年逐月的历史模仿数据;
…,
CMIP_train.nc中[150,0:36,:,:]为CMIP6第一个模式提供的第151-第153年逐月的历史模仿数据;
CMIP_train.nc中[151,0:36,:,:]为CMIP6第二个模式提供的第1-第3年逐月的历史模仿数据;
…,
CMIP_train.nc中[2265,0:36,:,:]为CMIP5第一个模式提供的第1-第3年逐月的历史模仿数据;
…,
CMIP_train.nc中[2405,0:36,:,:]为CMIP5第二个模式提供的第1-第3年逐月的历史模仿数据;
…,
CMIP_train.nc中[4644,0:36,:,:]为CMIP5第17个模式提供的第140-第142年逐月的历史模仿数据。
其中每个样本第三、第四维度别离代表经纬度(南纬55度北纬60度,东经0360度),所有数据的经纬度范畴雷同。
训练数据标签阐明
标签数据为Nino3.4 SST异样指数,数据维度为(year,month)。
CMIP(SODA)_train.nc对应的标签数据以后时刻Nino3.4 SST异样指数的三个月滑动平均值,因而数据维度与维度介绍同训练数据统一
注:三个月滑动平均值为以后月与将来两个月的平均值。
测试数据阐明
测试用的初始场(输出)数据为国内多个陆地材料异化后果提供的随机抽取的n段12个工夫序列,数据格式采纳NPY格局保留,维度为(12,lat,lon, 4),12为t时刻及过来11个时刻,4为预测因子,并依照SST,T300,Ua,Va的程序寄存。
测试集文件序列的命名规定:test_编号_起始月份_终止月份.npy,如test_00001_01_12_.npy。
评估指标
本赛题的评估指标如下:
$$
Score = \frac{2}{3} \times accskill – RMSE
$$
其中$accskill$为相关性技巧评分,计算形式如下:
$$
accskill = \sum_{i=1}^{24} a \times ln(i) \times cor_i \\
(i \leq 4, a = 1.5; 5 \leq i \leq 11, a = 2; 12 \leq i \leq 18, a = 3; 19 \leq i, a = 4)
$$
能够看出,月份$i$减少时系数$a$也增大,也就是说,模型能精确预测的工夫越长,评分就越高。
$cor_i$是对于$N$个测试集样本在时刻$i$的预测值与理论值的相关系数,计算公式如下:
$$
cor_i = \frac{\sum_{j=1}^N(y_{truej}-\bar{y}_{true})(y_{predj}-\bar{y}_{pred})}{\sqrt{\sum(y_{truej}-\bar{y}_{true})^2\sum(y_{predj}-\bar{y}_{pred})^2}}
$$
其中$y_{truej}$为时刻$i$样本$j$的理论Nino3.4指数,$\bar{y}_{true}$为该时刻$N$个测试集样本的Nino3.4指数的均值,$y_{predj}$为时刻$i$样本$j$的预测Nino3.4指数,$\bar{y}_{pred}$为该时刻$N$个测试集样本的预测Nino3.4指数的均值。
$RMSE$为24个月份的累计均方根误差,计算公式为:
$$
RMSE = \sum_{i=1}^{24}rmse_i \\
rmse = \sqrt{\frac{1}{N}\sum_{j=1}^N(y_{truej}-y_{predj})^2}
$$
赛题剖析
剖析上述赛题信息能够发现,咱们须要解决的是以下问题:
- 对于一个时空序列预测问题,要如何开掘工夫信息?如何开掘空间信息?
- 数据中给出的特色是四个气象畛域公认的、通用的气象变量,咱们很难再由此结构新的特色。如果不结构新的特色,要如何从给出的特色中挖掘出更多的信息?
-
训练集的数据量不大,总共只有$140\times17+151\times15+100=4745$个训练样本,对于数据量小的预测问题,咱们通常须要从以下两方面思考:
- 如何减少数据量?
- 如何结构小(参数量小,减小过拟合危险)而深(能提取出足够丰盛的信息)的模型?
2.线下数据转换
- 将数据转化为咱们所相熟的模式,每个人的格调不一样,此处能够作为如何将nc文件转化为csv等文件
数据转化
## 工具包导入&数据读取
### 工具包导入
'''
装置工具
# !pip install netCDF4
'''
import pandas as pd
import numpy as np
import tensorflow as tf
from tensorflow.keras.optimizers import Adam
import matplotlib.pyplot as plt
import scipy
from netCDF4 import Dataset
import netCDF4 as nc
import gc
%matplotlib inline
数据读取
SODA_label解决
- 标签含意
标签数据为Nino3.4 SST异样指数,数据维度为(year,month)。
CMIP(SODA)_train.nc对应的标签数据以后时刻Nino3.4 SST异样指数的三个月滑动平均值,因而数据维度与维度介绍同训练数据统一
注:三个月滑动平均值为以后月与将来两个月的平均值。
- 将标签转化为咱们相熟的pandas模式
label_path = './data/SODA_label.nc'
label_trans_path = './data/'
nc_label = Dataset(label_path,'r')
years = np.array(nc_label['year'][:])
months = np.array(nc_label['month'][:])
year_month_index = []
vs = []
for i,year in enumerate(years):
for j,month in enumerate(months):
year_month_index.append('year_{}_month_{}'.format(year,month))
vs.append(np.array(nc_label['nino'][i,j]))
df_SODA_label = pd.DataFrame({'year_month':year_month_index})
df_SODA_label['year_month'] = year_month_index
df_SODA_label['label'] = vs
df_SODA_label.to_csv(label_trans_path + 'df_SODA_label.csv',index = None)
df_SODA_label.head()
<div>
<style scoped>
.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
</style>
year_month | label | |
---|---|---|
0 | year_1_month_1 | -0.40720701217651367 |
1 | year_1_month_2 | -0.20244435966014862 |
2 | year_1_month_3 | -0.10386104136705399 |
3 | year_1_month_4 | -0.02910841442644596 |
4 | year_1_month_5 | -0.13252995908260345 |
</div>
转化
SODA_train解决
SODA_train.nc中[0,0:36,:,:]为第1-第3年逐月的历史观测数据;
SODA_train.nc中[1,0:36,:,:]为第2-第4年逐月的历史观测数据;
…,
SODA_train.nc中[99,0:36,:,:]为第100-102年逐月的历史观测数据。
SODA_path = './data/SODA_train.nc'
nc_SODA = Dataset(SODA_path,'r')
- 自定义抽取对应数据&转化为df的模式;
index为年月; columns为lat和lon的组合
def trans_df(df, vals, lats, lons, years, months):
'''
(100, 36, 24, 72) -- year, month,lat,lon
'''
for j,lat_ in enumerate(lats):
for i,lon_ in enumerate(lons):
c = 'lat_lon_{}_{}'.format(int(lat_),int(lon_))
v = []
for y in range(len(years)):
for m in range(len(months)):
v.append(vals[y,m,j,i])
df[c] = v
return df
year_month_index = []
years = np.array(nc_SODA['year'][:])
months = np.array(nc_SODA['month'][:])
lats = np.array(nc_SODA['lat'][:])
lons = np.array(nc_SODA['lon'][:])
for year in years:
for month in months:
year_month_index.append('year_{}_month_{}'.format(year,month))
df_sst = pd.DataFrame({'year_month':year_month_index})
df_t300 = pd.DataFrame({'year_month':year_month_index})
df_ua = pd.DataFrame({'year_month':year_month_index})
df_va = pd.DataFrame({'year_month':year_month_index})
%%time
df_sst = trans_df(df = df_sst, vals = np.array(nc_SODA['sst'][:]), lats = lats, lons = lons, years = years, months = months)
df_t300 = trans_df(df = df_t300, vals = np.array(nc_SODA['t300'][:]), lats = lats, lons = lons, years = years, months = months)
df_ua = trans_df(df = df_ua, vals = np.array(nc_SODA['ua'][:]), lats = lats, lons = lons, years = years, months = months)
df_va = trans_df(df = df_va, vals = np.array(nc_SODA['va'][:]), lats = lats, lons = lons, years = years, months = months)
label_trans_path = './data/'
df_sst.to_csv(label_trans_path + 'df_sst_SODA.csv',index = None)
df_t300.to_csv(label_trans_path + 'df_t300_SODA.csv',index = None)
df_ua.to_csv(label_trans_path + 'df_ua_SODA.csv',index = None)
df_va.to_csv(label_trans_path + 'df_va_SODA.csv',index = None)
CMIP_label解决
label_path = './data/CMIP_label.nc'
label_trans_path = './data/'
nc_label = Dataset(label_path,'r')
years = np.array(nc_label['year'][:])
months = np.array(nc_label['month'][:])
year_month_index = []
vs = []
for i,year in enumerate(years):
for j,month in enumerate(months):
year_month_index.append('year_{}_month_{}'.format(year,month))
vs.append(np.array(nc_label['nino'][i,j]))
df_CMIP_label = pd.DataFrame({'year_month':year_month_index})
df_CMIP_label['year_month'] = year_month_index
df_CMIP_label['label'] = vs
df_CMIP_label.to_csv(label_trans_path + 'df_CMIP_label.csv',index = None)
df_CMIP_label.head()
<div>
<style scoped>
.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
</style>
year_month | label | |
---|---|---|
0 | year_1_month_1 | -0.26102548837661743 |
1 | year_1_month_2 | -0.1332537680864334 |
2 | year_1_month_3 | -0.014831557869911194 |
3 | year_1_month_4 | 0.10506672412157059 |
4 | year_1_month_5 | 0.24070978164672852 |
</div>
CMIP_train解决
CMIP_train.nc中[0,0:36,:,:]为CMIP6第一个模式提供的第1-第3年逐月的历史模仿数据;
…,
CMIP_train.nc中[150,0:36,:,:]为CMIP6第一个模式提供的第151-第153年逐月的历史模仿数据;
CMIP_train.nc中[151,0:36,:,:]为CMIP6第二个模式提供的第1-第3年逐月的历史模仿数据;
…,
CMIP_train.nc中[2265,0:36,:,:]为CMIP5第一个模式提供的第1-第3年逐月的历史模仿数据;
…,
CMIP_train.nc中[2405,0:36,:,:]为CMIP5第二个模式提供的第1-第3年逐月的历史模仿数据;
…,
CMIP_train.nc中[4644,0:36,:,:]为CMIP5第17个模式提供的第140-第142年逐月的历史模仿数据。
其中每个样本第三、第四维度别离代表经纬度(南纬55度北纬60度,东经0360度),所有数据的经纬度范畴雷同。
CMIP_path = './data/CMIP_train.nc'
CMIP_trans_path = './data'
nc_CMIP = Dataset(CMIP_path,'r')
nc_CMIP.variables.keys()
dict_keys(['sst', 't300', 'ua', 'va', 'year', 'month', 'lat', 'lon'])
nc_CMIP['t300'][:].shape
(4645, 36, 24, 72)
year_month_index = []
years = np.array(nc_CMIP['year'][:])
months = np.array(nc_CMIP['month'][:])
lats = np.array(nc_CMIP['lat'][:])
lons = np.array(nc_CMIP['lon'][:])
last_thre_years = 1000
for year in years:
'''
数据的起因,咱们
'''
if year >= 4645 - last_thre_years:
for month in months:
year_month_index.append('year_{}_month_{}'.format(year,month))
df_CMIP_sst = pd.DataFrame({'year_month':year_month_index})
df_CMIP_t300 = pd.DataFrame({'year_month':year_month_index})
df_CMIP_ua = pd.DataFrame({'year_month':year_month_index})
df_CMIP_va = pd.DataFrame({'year_month':year_month_index})
- 因为内存限度,咱们临时取最初1000个year的数据
def trans_thre_df(df, vals, lats, lons, years, months, last_thre_years = 1000):
'''
(4645, 36, 24, 72) -- year, month,lat,lon
'''
for j,lat_ in (enumerate(lats)):
# print(j)
for i,lon_ in enumerate(lons):
c = 'lat_lon_{}_{}'.format(int(lat_),int(lon_))
v = []
for y_,y in enumerate(years):
'''
数据的起因,咱们
'''
if y >= 4645 - last_thre_years:
for m_,m in enumerate(months):
v.append(vals[y_,m_,j,i])
df[c] = v
return df
%%time
df_CMIP_sst = trans_thre_df(df = df_CMIP_sst, vals = np.array(nc_CMIP['sst'][:]), lats = lats, lons = lons, years = years, months = months)
df_CMIP_sst.to_csv(CMIP_trans_path + 'df_CMIP_sst.csv',index = None)
del df_CMIP_sst
gc.collect()
df_CMIP_t300 = trans_thre_df(df = df_CMIP_t300, vals = np.array(nc_CMIP['t300'][:]), lats = lats, lons = lons, years = years, months = months)
df_CMIP_t300.to_csv(CMIP_trans_path + 'df_CMIP_t300.csv',index = None)
del df_CMIP_t300
gc.collect()
df_CMIP_ua = trans_thre_df(df = df_CMIP_ua, vals = np.array(nc_CMIP['ua'][:]), lats = lats, lons = lons, years = years, months = months)
df_CMIP_ua.to_csv(CMIP_trans_path + 'df_CMIP_ua.csv',index = None)
del df_CMIP_ua
gc.collect()
df_CMIP_va = trans_thre_df(df = df_CMIP_va, vals = np.array(nc_CMIP['va'][:]), lats = lats, lons = lons, years = years, months = months)
df_CMIP_va.to_csv(CMIP_trans_path + 'df_CMIP_va.csv',index = None)
del df_CMIP_va
gc.collect()
(36036, 1729)
3.数据建模
工具包导入&数据读取
工具包导入
import pandas as pd
import numpy as np
import tensorflow as tf
from tensorflow.keras.optimizers import Adam
import joblib
from netCDF4 import Dataset
import netCDF4 as nc
import gc
from sklearn.metrics import mean_squared_error
import numpy as np
from tensorflow.keras.callbacks import LearningRateScheduler, Callback
import tensorflow.keras.backend as K
from tensorflow.keras.layers import *
from tensorflow.keras.models import *
from tensorflow.keras.optimizers import *
from tensorflow.keras.callbacks import *
from tensorflow.keras.layers import Input
%matplotlib inline
数据读取
SODA_label解决
- 标签含意
标签数据为Nino3.4 SST异样指数,数据维度为(year,month)。
CMIP(SODA)_train.nc对应的标签数据以后时刻Nino3.4 SST异样指数的三个月滑动平均值,因而数据维度与维度介绍同训练数据统一
注:三个月滑动平均值为以后月与将来两个月的平均值。
- 将标签转化为咱们相熟的pandas模式
df_SODA_label = pd.read_csv('./data/df_SODA_label.csv')
df_CMIP_label = pd.read_csv('./data/df_CMIP_label.csv')
训练集验证集构建
df_SODA_label['year'] = df_SODA_label['year_month'].apply(lambda x: x[:x.find('m') - 1])
df_SODA_label['month'] = df_SODA_label['year_month'].apply(lambda x: x[x.find('m') :])
df_train = pd.pivot_table(data = df_SODA_label, values = 'label',index = 'year', columns = 'month')
year_new_index = ['year_{}'.format(i+1) for i in range(df_train.shape[0])]
month_new_columns = ['month_{}'.format(i+1) for i in range(df_train.shape[1])]
df_train = df_train[month_new_columns].loc[year_new_index]
模型构建
MLP框架
def RMSE(y_true, y_pred):
return tf.sqrt(tf.reduce_mean(tf.square(y_true - y_pred)))
def RMSE_fn(y_true, y_pred):
return np.sqrt(np.mean(np.power(np.array(y_true, float).reshape(-1, 1) - np.array(y_pred, float).reshape(-1, 1), 2)))
def build_model(train_feat, test_feat): #allfeatures,
inp = Input(shape=(len(train_feat)))
x = Dense(1024, activation='relu')(inp)
x = Dropout(0.25)(x)
x = Dense(512, activation='relu')(x)
x = Dropout(0.25)(x)
output = Dense(len(test_feat), activation='linear')(x)
model = Model(inputs=inp, outputs=output)
adam = tf.optimizers.Adam(lr=1e-3,beta_1=0.99,beta_2 = 0.99)
model.compile(optimizer=adam, loss=RMSE)
return model
模型训练
feature_cols = ['month_{}'.format(i+1) for i in range(12)]
label_cols = ['month_{}'.format(i+1) for i in range(12, df_train.shape[1])]
model_mlp = build_model(feature_cols, label_cols)
model_mlp.summary()
Model: "model"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) [(None, 12)] 0
_________________________________________________________________
dense (Dense) (None, 1024) 13312
_________________________________________________________________
dropout (Dropout) (None, 1024) 0
_________________________________________________________________
dense_1 (Dense) (None, 512) 524800
_________________________________________________________________
dropout_1 (Dropout) (None, 512) 0
_________________________________________________________________
dense_2 (Dense) (None, 24) 12312
=================================================================
Total params: 550,424
Trainable params: 550,424
Non-trainable params: 0
_________________________________________________________________
tr_len = int(df_train.shape[0] * 0.8)
tr_fea = df_train[feature_cols].iloc[:tr_len,:].copy()
tr_label = df_train[label_cols].iloc[:tr_len,:].copy()
val_fea = df_train[feature_cols].iloc[tr_len:,:].copy()
val_label = df_train[label_cols].iloc[tr_len:,:].copy()
model_weights = './user_data/model_data/model_mlp_baseline.h5'
checkpoint = ModelCheckpoint(model_weights, monitor='val_loss', verbose=0, save_best_only=True, mode='min',
save_weights_only=True)
plateau = ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=5, verbose=1, min_delta=1e-4, mode='min')
early_stopping = EarlyStopping(monitor="val_loss", patience=20)
history = model_mlp.fit(tr_fea.values, tr_label.values,
validation_data=(val_fea.values, val_label.values),
batch_size=4096, epochs=200,
callbacks=[plateau, checkpoint, early_stopping],
verbose=2)
Epoch 00053: ReduceLROnPlateau reducing learning rate to 6.25000029685907e-05.
1/1 - 0s - loss: 0.6567 - val_loss: 0.6030
Epoch 54/200
1/1 - 0s - loss: 0.6571 - val_loss: 0.6030
Epoch 55/200
1/1 - 0s - loss: 0.6541 - val_loss: 0.6030
Epoch 56/200
1/1 - 0s - loss: 0.6539 - val_loss: 0.6030
Epoch 57/200
1/1 - 0s - loss: 0.6477 - val_loss: 0.6030
Epoch 58/200
Epoch 00058: ReduceLROnPlateau reducing learning rate to 3.125000148429535e-05.
1/1 - 0s - loss: 0.6498 - val_loss: 0.6029
Epoch 59/200
1/1 - 0s - loss: 0.6451 - val_loss: 0.6029
Epoch 60/200
1/1 - 0s - loss: 0.6458 - val_loss: 0.6029
Metrics
def rmse(y_true, y_preds):
return np.sqrt(mean_squared_error(y_pred = y_preds, y_true = y_true))
def score(y_true, y_preds):
accskill_score = 0
rmse_score = 0
a = [1.5] * 4 + [2] * 7 + [3] * 7 + [4] * 6
y_true_mean = np.mean(y_true,axis=0)
y_pred_mean = np.mean(y_true,axis=0)
for i in range(24):
fenzi = np.sum((y_true[:,i] - y_true_mean[i]) *(y_preds[:,i] - y_pred_mean[i]) )
fenmu = np.sqrt(np.sum((y_true[:,i] - y_true_mean[i])**2) * np.sum((y_preds[:,i] - y_pred_mean[i])**2) )
cor_i= fenzi / fenmu
accskill_score += a[i] * np.log(i+1) * cor_i
rmse_score += rmse(y_true[:,i], y_preds[:,i])
return 2 / 3.0 * accskill_score - rmse_score
y_val_preds = model_mlp.predict(val_fea.values, batch_size=1024)
print('score', score(y_true = val_label.values, y_preds = y_val_preds))
4.模型预测
模型构建
在下面的局部,咱们曾经训练好了模型,接下来就是提交模型并在线上进行预测,这块能够分为三步:
- 导入模型;
- 读取测试数据并且进行预测;
- 生成提交所需的版本;
import tensorflow as tf
import tensorflow.keras.backend as K
from tensorflow.keras.layers import *
from tensorflow.keras.models import *
from tensorflow.keras.optimizers import *
from tensorflow.keras.callbacks import *
from tensorflow.keras.layers import Input
import numpy as np
import os
import zipfile
def RMSE(y_true, y_pred):
return tf.sqrt(tf.reduce_mean(tf.square(y_true - y_pred)))
def build_model(train_feat, test_feat): #allfeatures,
inp = Input(shape=(len(train_feat)))
x = Dense(1024, activation='relu')(inp)
x = Dropout(0.25)(x)
x = Dense(512, activation='relu')(x)
x = Dropout(0.25)(x)
output = Dense(len(test_feat), activation='linear')(x)
model = Model(inputs=inp, outputs=output)
adam = tf.optimizers.Adam(lr=1e-3,beta_1=0.99,beta_2 = 0.99)
model.compile(optimizer=adam, loss=RMSE)
return model
feature_cols = ['month_{}'.format(i+1) for i in range(12)]
label_cols = ['month_{}'.format(i+1) for i in range(12, 36)]
model = build_model(train_feat=feature_cols, test_feat=label_cols)
model.load_weights('./user_data/model_data/model_mlp_baseline.h5')
模型预测
test_path = './tcdata/enso_round1_test_20210201/'
### 0. 模仿线上的测试汇合
# for i in range(10):
# x = np.random.random(12)
# np.save(test_path + "{}.npy".format(i+1),x)
### 1. 测试数据读取
files = os.listdir(test_path)
test_feas_dict = {}
for file in files:
test_feas_dict[file] = np.load(test_path + file)
### 2. 后果预测
test_predicts_dict = {}
for file_name,val in test_feas_dict.items():
test_predicts_dict[file_name] = model.predict(val.reshape([-1,12]))
# test_predicts_dict[file_name] = model.predict(val.reshape([-1,12])[0,:])
### 3.存储预测后果
for file_name,val in test_predicts_dict.items():
np.save('./result/' + file_name,val)
打包到run.sh目录下方
#打包目录为zip文件
def make_zip(source_dir='./result/', output_filename = 'result.zip'):
zipf = zipfile.ZipFile(output_filename, 'w')
pre_len = len(os.path.dirname(source_dir))
source_dirs = os.walk(source_dir)
print(source_dirs)
for parent, dirnames, filenames in source_dirs:
print(parent, dirnames)
for filename in filenames:
if '.npy' not in filename:
continue
pathfile = os.path.join(parent, filename)
arcname = pathfile[pre_len:].strip(os.path.sep) #相对路径
zipf.write(pathfile, arcname)
zipf.close()
make_zip()
我的项目链接以及码源
云端链接:
人工智能翻新挑战赛陆地气象预测Baseline[4]完整版
更多文章请关注公重号:汀丶人工智能
5.晋升方向
模型性能晋升能够参考:在下述根底上改变
“AI Earth”人工智能翻新挑战赛:助力精准气象和陆地预测Baseline[2]:数据探索性剖析(温度风场可视化)、CNN+LSTM模型建模
“AI Earth”人工智能翻新挑战赛:助力精准气象和陆地预测Baseline[3]:TCNN+RNN模型、SA-ConvLSTM模型
- 模型角度:咱们只应用了简略的MLP模型进行建模,能够思考应用其它的更加fancy的模型进行尝试;
- 数据层面:构建一些特色或者对数据进行一些数据变换等;
- 针对损失函数设计各种trick的晋升技巧;
发表回复