竞赛经历AI气象_nino_厄尔尼诺_预测

竞赛题目

官网地址
问题类型:时间序列预测问题。
基于历史气候观测和模式模拟数据,利用T时刻过去12个月(包含T时刻)的时空序列(气象因子),构建预测ENSO的深度学习模型,预测未来1-24个月的Nino3.4指数,如下图所示:
image.png

数据

东经 0°–360°,南纬 55°到北纬 60°-> 维度(24,72)

  • 海平面温度(SST)
  • 热含量异常(T300)
  • 纬向风异常(Ua)
  • 经向风异常(Va)

SODA数据:可以当成真实数据 100年

CMIP5/CMIP6:可以当成模拟数据(大气模型模拟) CMIP5: 151年 * 15 个模式=2265 140年 * 17 个模式=2380

Label: nino3.4指标

SODA_train、SODA_label、CMIP_train、CMIP_label

评估指标

评分细则说明:根据所提供的n个测试数据,对模型进行测试,得到n组未来1-24个月的序列选取对应预测时效的n个数据与标签值进行计算相关系数和均方根误差,如下图所示。并计算得分。

image-20210401224442956

赛题理解

Nino3.4(西经 170°–120°,南北纬 5°以内区域中的平均 SST 值)就是本次赛题的标签。

训练数据对应的标签数据是当前时刻Nino3.4 SST(170°–120°W,5°S–5°N)异常指数的三个月滑动平均值。三个月滑动平均值为当前月与未来两个月的平均值。红框内的区域SST(解释:计算出来当月的SST均值后,还需要计算未来两个月的SST均值,然后求平均才是本月的nino3.4指标)
image-20210401224652219

根据赛题本意,每一个月,在世界地图上(东经 0°–360°,南纬 55°到北纬 60°),标注了海平面温度(SST)、热含量异常(T300)、纬向风异常(Ua)、经向风异常(Va)数据,地图可以看做是一个4* 24* 72的图片(4个通道数代表SST/T300/UA/VA参数)。一个月对应了一张图片,而且每一张图片都能对应一个Nino3.4指数。
参考EDA
image-20210401224718756

具体来说,需要根据一年(12个月)的气候变化(sst/t300/ua/va),推断出未来2年(24个月)的nino3.4指标。
思路一:根据12张图片(4 * 24 * 72)推断未来24张图片(4 * 24 * 72),再根据推断的图片,计算得到每个月的nino3.4指标(流程1)。
思路二:根据12张图片(4 * 24 * 72)直接预测未来2年(24个月)的nino3.4指标(流程2)。
image-20210401224743945

数据探索

验证nino3.4标签

每一个月的nino3.4指标是根据每一个月的SST指数计算得来的吗(西经 170°–120°,南北纬 5°以内区域中的平均 SST 值,滑动三个月)?验证nino3.4指标是否是由此得来的。

  1. 提取西经 170°–120°,南北纬 5°以内区域中 SST 值,计算其与标签的关系。
  2. 根据测试结果,前24个月的SST指数均值滑动3个月,能够对应上nino3.4指标,但是之后的就对应不上了,但是总体相关系数达到0.991,平均绝对误差为0.087 左右,很奇怪,通过验证数据,没有发现问题所在。
  3. 对CMIP_train数据做同样测试,用SST指数均值滑动3个月,能够对应上nino3.4指标,相关系数以及平均绝对误差都可以对应。是否SODA数据存在问题?CMIP5和CMIP6都经过测试。
  • SODA 数据只有前24个月的数据符合nino3.4指标的构建规则,后面100年的数据趋势符合,但是不能完全重合
  • CMIP 数据符合nino3.4指标的构建规则
    image-20210401230504313
image-20210401225137389

结论

根据官方解释:
准确的label是根据标准1* 1的海温甚至更高精度的海温计算的,而本次比赛5* 5精度的海温计算的肯定有误差。
SODA前24个月的数据一致是因为前24个月没有1* 1的观测数据,只能用这个5* 5计算出来的代替,所以一致。
CMIP数据没有真实样本资料,而SODA观测是有真实样本的。所以SODA的label是更准确的。
数据是没有问题的

缺失值删除

样本个数大致可以看成:
CMIP5+CMIP6+SODA = 2265 + 2380 +100 = 4745
含有缺失值的样本个数有 775个
EDA中虽然说缺失值大多是陆地,但是还是将其删除了

image-20210401225226811

模型构建

思路

  • 模型构建参考了Baseline ,主要思路是利用CNN+LSTM来构建,B榜最高的一次分数是26分。

  • 经纬度外加4个特征,可以看作图片的长、宽和通道(4,24,72)

  • B榜分两次进行训练

  • 第一次是CMIP数据划分8:2 进行训练 将含有空值的样本去除了

  • 利用训练好的模型,在SODA数据上微调,SODA数据划分 8:2

训练过程参考

模型

class simpleSpatailTimeNN(nn.Module):
    
    def __init__(self, n_cnn_layer:int=1, kernals:list=[3], n_lstm_units:int=64):
        super(simpleSpatailTimeNN, self).__init__()
        self.conv1 = nn.Conv2d(4,4,3,padding = 1)
        self.batch_norm = nn.BatchNorm1d(12, affine=False)
        self.lstm = nn.LSTM(24*72*4, n_lstm_units, 2, bidirectional=True,batch_first=True)
        self.pool3 = nn.AdaptiveAvgPool2d((1, 128))
        self.linear = nn.Linear(128, 24)
        
    def forward(self, sst, t300, ua, va):
        Seqs = []
        for i in range(12):
            sst_tmp = sst[:,i,:,:].unsqueeze(1)   #[batch,1,24,72]
            t300_tmp = t300[:,i,:,:].unsqueeze(1)
            ua_tmp = ua[:,i,:,:].unsqueeze(1)
            va_tmp = va[:,i,:,:].unsqueeze(1)
            seq1 = torch.cat([sst_tmp,t300_tmp,ua_tmp,va_tmp],dim=1)  #[batch,4,24,72]
            seq1 = self.conv1(seq1)#[batch,4,24,72]
            seq1 = torch.flatten(seq1, start_dim=1).unsqueeze(1)#[batch,4*24*72]
            Seqs.append(seq1)#    [batch,1,4*24*72]  *  12
        x = torch.cat([Seqs[i] for i in range(12)], dim=1)    #[batch,12,4*24*72]  
        x = self.batch_norm(x)
        x, _ = self.lstm(x)
        x = self.pool3(x).squeeze(dim=-2)
        x = self.linear(x)
        return x

几次提交记录

image-20210401231621484

其他尝试

  • 使用SST训练
  • 使用SST+T300训练
  • 提取前12个月的nino3.4指数,使用全连接层直接训练
  • 使用Resnet18模型直接输出,线上-1.3573分
  • 使用ConvLstm模型,废了很大劲修改模型,线上22.7分
  • 使用6个月数据进行训练,1-6、2-7… 7-12分别进行训练,相当于构建了7个模型进行融合线上10分
  • 使用滑窗构建数据(测试集开始月份是随机的,并不是都从1月份开始),一共可以构建接近5W个样本,进行训练,效果很差。
  • 因为数据验证波动很大,所以在验证集如何构建上变化了很多次,最终选择了SODA再训练验证方式。

Docker常用操作

  1. 进入镜像仓库https://cr.console.aliyun.com ,创建一个命名空间、创建一个镜像(复制镜像地址)
  2. 在本机安装docker,安装完成后,使用命令行登录阿里云的仓库,输入密码
#登录  
docker login --username=xxx registry.cn-hangzhou.aliyuncs.com

#在本地构建镜像   本地Dockerfile文件构建   
#镜像地址registry.cn-hangzhou.aliyuncs.com/littlesix/ai_earth_submit     
docker build -t registry.cn-hangzhou.aliyuncs.com/littlesix/ai_earth_submit:1.0 .   

#开启一个bash命令行,运行本地镜像   
docker run -it registry.cn-hangzhou.aliyuncs.com/littlesix/ai_earth_submit:1.0 bash   
docker run -it registry.cn-hangzhou.aliyuncs.com/littlesix/ai_earth_submit:1.0 sh run.sh     

#推送镜像到云端   
docker push registry.cn-hangzhou.aliyuncs.com/littlesix/ai_earth_submit:1.0 

#挂在数据目录      -v 本地目录:镜像地址   当前目录用/  绝对目录用\  
docker run -it -v /tcdata/enso_round1_test_20210201/:/tcdata/enso_round1_test_20210201/ registry.cn-hangzhou.aliyuncs.com/littlesix/ai_earth_submit:4.0 sh run.sh

docker run -it -v D:\jupyter\WeatherOceanForecasts\tcdata\enso_round1_test_20210201\:/tcdata/enso_round1_test_20210201/ registry.cn-hangzhou.aliyuncs.com/littlesix/ai_submit_pytorch:1.0 sh run.sh       

docker run -it -v D:\jupyter\WeatherOceanForecasts\tcdata\enso_round1_test_20210201\:/tcdata/enso_round1_test_20210201/ registry.cn-hangzhou.aliyuncs.com/littlesix/ai_submit_pytorch:1.0 bash 

#提交容器 形成新镜像   
docker commit contain_id registry.cn-hangzhou.aliyuncs.com/littlesix/ai_earth_submit:6.0 

#在容器内删除tcdata文件夹   
rm tcdata -r 

#向容器中添加文件   
docker cp C:\Users\Administrator\Desktop\wheather\mlp_predict.py contain_id:./ 
docker cp D:\jupyter\WeatherOceanForecasts\user_data\ref.pt contain_id:./user_data

总结:

  1. 前期一定一定要确定自己的baseline以及线下验证方式。如果有相关比赛SOTA(state-of-the-art),或者baseline,会节省很多时间。
  2. 每次提交就是一次实验,实验记录一定要记清楚,所使用的方法,特征,模型等,形成一个单独的版本,方便复盘与思考。

通过这次比赛:

  1. 学习了pytorch的常用操作。数据集构建、模型构建、训练、测试等。
  2. 学习了RNN/LSTM的使用方式。
  3. 学习了pytorch中已有模型的修改方式,如Resnet18等。
  4. 学习了ConvLstm的使用方式,只能跑通,但是对使用效果、修改模型等还需要进一步了解。
  5. 巩固和学习了docker的使用。

参考

  1. Datewhale_Baseline
  2. CNN+LSTM_baselineNINO预测:22分baseline
  3. 「EDA」时空问题之厄尔尼诺预测
  4. 从0梳理1场时间序列赛事!
  5. 气象遇见机器学习
  6. 交叉新趋势|采用神经网络与深度学习来预报降水、温度等案例(附代码/数据/文献)
  7. 最新进展 | 深度学习在天气预测中的应用
  8. 基于气象模式、气象观测数据的深度学习预报方法总结(Deecamp 结营总结)
  9. 预测伦敦空气质量convlstm
  10. ConvLSTM_pytorch
  11. PyTorch_ConvLSTM代码(参数)解读笔记

代码地址

  • 3
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值