资讯动态

基于深度学习的台风预测:数据预处理、LSTM训练与避坑指南

发布时间:2026/10/2 6:56:22 来源:尧图企业网站定制
简介面向毕业设计、课程设计与期末大作业场景一套基于深度学习的台风预测项目资源包适合掌握一定Python基础并想了解YOLO等深度学习模型在气象领域应用的在校学生。压缩包共13个文件体积仅1.3MB涵盖6个csv台风数据集含CMA、JTWC路径与强度数据、2个Python工程脚本、1个YAML配置以及HTML展示页面与PNG可视化图表可完整体现从数据预处理、模型构建到结果展示的流程。目前已有60人学习下载。资源内含buildupDB.py核心脚本与templates/index.html前端展示页面解压后可查看数据结构、模型参数配置和台风预测成果图便于参考其目录组织方式与代码风格适合作为深度学习预测类课程项目的起步模板或答辩参考素材。1. 下载到手的“台风预测.zip”到底装了什么一个压缩包如果叫“基于深度学习的台风预测.zip”外行以为解压就是成品实际上它装的是从数据处理到模型训练的一整套方案。里面通常至少包含历史台风路径表、观测字段说明以及一份让你跑通某个深度学习模型的训练代码解决的核心问题是用过去24到72小时的实测数据预测未来24到48小时的台风强度或风圈变化。适合正在做气象课题、读研赶实验或者刚入门深度学习但不想只在MNIST上打转的人。这类项目最大的门槛不在模型本身的网络结构而在zip里那堆逗号错位、缺测漏测的原始csv以及解压之后目录一塌糊涂、一个月后连自己都复现不了的环境问题。2. 先过解压关zip伪加密、目录规划与原始数据整理2.1 拿到zip先别双击开看注释、验完整性和判断伪加密我见过太多人拿到压缩包的第一步就是右键解压到桌面解不开就到处找密码其实先把zip当普通文件“体检”一遍能省半天时间。用Python的zipfile模块看一下注释、文件清单和加密标志位比自己盲猜可靠得多。import zipfile from pathlib import Path archive_path Path(../台风预测.zip) with zipfile.ZipFile(archive_path) as zf: print(zip注释, zf.comment.decode(utf-8, errorsreplace)) print(文件清单) for info in zf.infolist(): flag info.flag_bits crypto 加密 if (flag 0x1) else 明文 print(f- {info.filename} {info.file_size/1024:.1f} KB {crypto} flag0x{flag:04x})这段代码做了两件事先把zipfile注释打出来很多共享数据包会把数据来源、Python版本和“先跑哪个脚本”写在注释里再列出每个文件的flag_bits最低位是0表示未加密是1表示文件有加密标志。看到“加密”先不要急着找密码很多共享包只是做了伪加密也就是只把加密标志位改了实际文件内容没有真正加锁这类包在Windows资源管理器里双击会弹密码框但zipfile读取时根本不需要密码。如果是自己参与生成、却忘了密码的数据包常见做法是把本地文件头里的加密标志位清掉再重新打包之后就能正常解压。这里要强调一句只处理自己参与制作、有权访问的数据包从别人手里拿到的压缩包正确路径是先找原作者要密码而不是用工具去撞。检查完加密再顺手验一遍完整性bad zf.testzip() if bad is not None: print(压缩包里有损坏文件, bad) else: print(压缩包完整性检查通过)testzip()会逐个解压文件并比对CRC32返回第一个损坏文件的名字。经常有课件或数据集包是“用聊天软件传了一半”或者网盘下载中断外层zip还能打开但解压到一半报invalid zip archive: could not find EOCD或者乱码文件。提前验一下至少能判断是“文件坏了”而不是“代码问题”。如果你不想写Python也可以直接用压缩工具打开看到文件列表却无法“测试压缩包”或者解压时反复要求输入密码基本就是上面这两种情况之一。2.2 建立data目录并要求“可复跑”读完zip注释和清单之后我一般不会急着解压到桌面而是先把目录结构规划好。深度学习项目跑三个月后最怕的不是模型不收敛而是“这个csv当初是哪来的”完全没记录。常见做法是固定一套分级目录raw放原始压缩包和下载文件interim放解压后未清洗的数据processed放滑窗后的npy或npz特征models放权重reports放训练曲线和指标。mkdir -p data/raw data/interim data/processed models reports mv ../台风预测.zip data/raw/这四行命令不解决任何算法问题但能让后续整个实验周期都变得可追溯。原始压缩包保留在raw里不参与后续处理解压得到的中间文件放在interim如果清洗脚本有bug随时能从raw重来processed只放程序生成的numpy数组和标签。这样逐日迭代时任何一步出错都能快速定位。解压到interim时注意看解压出来的是一个文件夹还是散落一地的csv。很多数据包解压后是嵌套三四层目录文件名还带中文括号和空格数据加载代码不建议依赖这类路径。我会先解压到interim然后做一层“扁平化”重命名from pathlib import Path import shutil src_dir Path(data/interim) dst_dir Path(data/interim) for p in src_dir.rglob(*.csv): # rglob会把所有子目录里的csv找出来 new_name dst_dir / f{p.parent.name}_{p.name} if not new_name.exists(): shutil.copy2(p, new_name) print(复制到, new_name)这里用rglob递归找出所有csv再用父目录名加文件名重命名避免多个同名 tc.csv 相互覆盖。shutil.copy2会保留文件时间戳方便后面看数据包的更新时间。如果你发现解压出来的文件没有扩展名或者一行里既有中文逗号又有英文逗号不要在这个阶段硬修先在interim留底后面统一写清洗脚本。还有一件容易忽略的事解压后先找README或数据说明。很多共享zip的实际内容和压缩包名有出入可能是台风最佳路径表也可能是某次比赛的预处理结果。如果README里写的字段含义和数据实际对不上后面所有特征工程都是白做。这一步花五分钟能避免后面拿着错误数据训三小时。3. 把台风路径数据切成监督学习样本滑窗、归一化与标签设计3.1 看懂字段时间、经纬度、中心气压与最大风速台风历史数据最常用的来源是IBTrACS和各气象台站发布的最佳路径数据集常见格式是每6小时一条记录字段至少包括台风编号、时间、经度、纬度、中心最低气压和近中心最大风速。不同数据源字段名差异很大但你基本只需要从里面挑出时间、空间位置和强度三个维度。import pandas as pd df pd.read_csv(data/interim/typhoon_records.csv, parse_dates[time]) print(df.head()) print(df.groupby(typhoon_id).size().describe())第一行读取历史路径表parse_dates把time列解析成datetime对象。第二行按台风编号统计每条台风的记录条数这一步很重要如果某条台风只有两三条记录它根本切不出满足窗口要求的训练样本适合直接过滤掉。一般能用于滑动窗口的台风至少要有“窗口长度预测时程1”条记录。字段含义典型单位处理注意time观测时刻UTC时间按台风分组后必须排序lat/lon中心纬度/经度度跨换日线时不要直接线性插值vmax近中心最大风速m/s或kt高位台风存在大量缺测pres中心最低气压hPa剧烈变化区往往缺测typhoon_id台风编号字符串同一编号内部才能滑窗读进来之后先做三件事按typhoon_id和time排序去掉明显在陆地上且结构已混乱的记录对经纬度做基本范围检查。跨换日线的台风是常见坑如果某条路径从179°连续变化到-179°直接按数值排序会出现一次复位式跳变需要先判断是连续移动还是异常数据。换日线附近的记录在滑窗时会同时包含正负经度如果不对180/-180做周期处理模型会认为台风瞬间穿越了半个地球。3.2 滑窗与标签预测未来48小时的风速变化监督学习要回答的问题是给定过去36小时6个时次的观测预测未来48小时第8个时次的近中心最大风速。滑窗函数按单条台风分组计算不能跨台风把前一条的结尾接到后一条的开头。import numpy as np WINDOW 6 # 用过去6个时次即36小时 HORIZON 8 # 预测未来第8个时次即48小时 FEATURES [lon, lat, vmax, pres] TARGET vmax def make_windows(group): src group[FEATURES].to_numpy(dtypenp.float32) xs, ys [], [] for i in range(len(src) - WINDOW - HORIZON 1): x src[i:i WINDOW] y src[i WINDOW HORIZON - 1, FEATURES.index(TARGET)] xs.append(x) ys.append(y) return np.asarray(xs, dtypenp.float32), np.asarray(ys, dtypenp.float32) samples df.groupby(typhoon_id).apply(make_windows)这里i的范围设计是重点len(src) - WINDOW - HORIZON 1保证最后一个样本的标签索引正好落在序列末尾不会越界。WINDOW取6对应36小时HORIZON取8对应48小时如果要改成“未来24小时”把HORIZON改成4就行。经纬度、风速、气压全部进输入但标签只取风速这是把问题定义为“强度回归”。从实际结果看台风强度变化明显是非平稳的眼壁置换阶段风速可能急降再回升海温变化引起的缓慢增强则持续几十小时。所以我在项目里一般不只看单一风速值还会把“未来48小时相对当前的风速增量”也作为另一个标签让模型同时输出绝对强度和增减趋势。如果你用的是分类方式比如“强热带风暴/台风/强台风/超强台风”四档标签就需要注意分层采样而不是简单随机抽样。3.3 归一化参数只允许用训练集计算特征拼接完毕、模型还没开始训练之前归一化是第一个容易出现数据泄漏的地方。很多入门教程直接对全数据集做MinMaxScaler这在普通分类问题里问题不大在时序问题里却会把未来信息提前泄露给模型。正确做法是把台风按编号或年份先拆成train/val/test三份再用训练集计算均值和标准差然后用同一组参数去变换验证集和测试集。train_raw_x np.concatenate([x for x, y in train_set]) train_raw_y np.concatenate([y for x, y in train_set]) mean_ train_raw_x.reshape(-1, train_raw_x.shape[-1]).mean(axis0) std_ train_raw_x.reshape(-1, train_raw_x.shape[-1]).std(axis0) 1e-8 train_x (train_raw_x - mean_) / std_ val_x (val_x_raw - mean_) / std_注意最后一行验证集用的是训练集的mean_和std_不是重新算。如果验证集自己算归一化模型在验证集上的表现会被高估到了真正预报新台风时马上翻车。加1e-8只是防止某个特征完全没有变化时除以零气压和纬度的标准差都不应该为0但旧数据里可能出现全部相同的占位符。注意归一化参数一旦用全数据集计算你的验证集就不再是“没见过”的数据了。调试时最好把mean_和std_保存成npy文件复现和部署时都要用同一份。这一步顺带解释了为什么前面说“先按台风分组”强台风主要发生在夏秋季如果按时间随机切分训练集里全是2015年前、验证集里全是2016年后模型学到的会偏向气候态变化而不是个体演变。按台风ID分组时可以把某年的台风整组从训练集拿走当验证集保证同一个台风的生命史不跨集合。4. 选模型并训练从LSTM到ConvLSTM小样本优先4.1 为什么不直接上Transformer样本量决定模型复杂度看到“深度学习”就堆Transformer是这类项目里最常见的误用。台风最佳路径数据经过滑窗后样本量通常在几千到几万条输入长度只有6到12个时次Transformer在这种量级下很难把注意力权重训稳反而LSTM加上一两个全连接层数据量小、收敛快、线上部署也省事。如果是直接对卫星云图做台风中心识别那是图像任务才适合上CNN如果输入是多通道时序格点场可以换成ConvLSTM但这时要准备TB级别的再分析数据不是一张csv就能喂出来的。选型原则是先跑通一个基线LSTM效果不满意再逐步加复杂度。很多时候预测误差卡在数据质量而不是模型容量换更大的模型只会让过拟合更严重。如果你手上的数据源只有路径表这种低维度表格CNN很难发挥优势这也是“基于深度学习的台风预测.zip”这类项目里最容易把新手带偏的地方。4.2 一个能训起来的PyTorch模型下面这个模型只做一件事吃过去6个时次、每步4个特征输出未来第8个时次的近中心最大风速。它小到CPU也能训练正好用来确认整条数据链路是否通顺。import torch import torch.nn as nn from torch.utils.data import TensorDataset, DataLoader class WindRNN(nn.Module): def __init__(self, n_features, hidden_size64, num_layers2): super().__init__() self.lstm nn.LSTM( input_sizen_features, hidden_sizehidden_size, num_layersnum_layers, batch_firstTrue, dropout0.1 ) self.head nn.Sequential( nn.Linear(hidden_size, 32), nn.ReLU(), nn.Linear(32, 1), nn.Softplus() ) def forward(self, x): out, _ self.lstm(x) return self.head(out[:, -1, :]).squeeze(-1) train_ds TensorDataset( torch.from_numpy(train_x), torch.from_numpy(train_y).float() ) train_loader DataLoader(train_ds, batch_size64, shuffleTrue)batch_firstTrue让输入形状保持为(batch, time_step, features)和滑窗代码里的(WINDOW, FEATURES)顺序对上新手在这里最容易把维度转错。out[:, -1, :]取最后一个时次的隐状态做预测你也可以用所有时次隐状态的平均池化但强度预测对最近状态最敏感取最后一步更直接。head最后接Softplus而不是裸线性层等于给风速输出加了非负约束防止出现负风速这种物理上不可能的预测。训练循环不需要花哨关键是早停和观察验证损失model WindRNN(n_featurestrain_x.shape[-1]) opt torch.optim.Adam(model.parameters(), lr1e-3) scheduler torch.optim.lr_scheduler.StepLR(opt, step10, gamma0.5) loss_fn nn.MSELoss() best_mae float(inf) for epoch in range(30): model.train() for xb, yb in train_loader: opt.zero_grad() loss loss_fn(model(xb), yb) loss.backward() opt.step() scheduler.step() model.eval() with torch.no_grad(): val_pred model(torch.from_numpy(val_x).float()) val_mae torch.abs(val_pred - torch.from_numpy(val_y).float()).mean().item() if val_mae best_mae: best_mae val_mae torch.save(model.state_dict(), models/windrnn_best.pt) print(fepoch {epoch:02d} val_mae {val_mae:.3f})学习率设1e-3对Adam来说是相对稳妥的起点StepLR每10个epoch把学习率减半是为了在后期缩小参数步长让loss落得更平。torch.save只在验证MAE下降时覆盖保存这样即使后面训练过拟合手里也留有一份最优权重。第一次跑如果val_mae完全不降不要急着调隐藏节点先回头检查归一化和滑窗代码八成是样本切错了。如果你手上有多通道网格数据比如把海温、风场、气压场叠成(time, lat, lon)的序列再考虑ConvLSTM。ConvLSTM把LSTM的矩阵乘换成卷积操作能同时捕捉空间偏移和时间演变。它比LSTM难训很多需要更大的显存和更久的数据预处理不建议在路径表数据上使用否则会陷入“数据维度撑不起模型”的尴尬。4.3 训练参数与部署压缩一组相对稳妥的基础参数如下参数建议值说明WINDOW636小时历史HORIZON848小时预报hidden_size64特征维度低时足够num_layers21到2层之间选batch_size64几千样本下适配lr1e-3Adam初始学习率max_epoch30配合早停dropout0.1防过拟合不追求大训练完成后直接交付源码没有太大意义我一般会把权重、推理入口和一份requirements.txt再打成zip交付。模型文件通过torch.quantization做动态量化后体积会明显缩小但量化对风速这种连续性小信号有一定精度损失上线前必须用验证集重新跑一遍MAE。常见做法是保留原始浮点权重和量化权重两个版本报告里同时给出两者在同一段回测期间的误差由业务方选择用哪一个。5. 避坑与常见问题EOCD报错、zip伪加密和数据泄漏5.1 数据泄漏验证集MAE漂亮得像假数据现象模型在验证集上MAE只有2到3米每秒比官方数值预报还好部署到新台风上却差得离谱。原因滑窗之后一条台风的前半段在训练集、后半段在验证集模型等于看过同一场台风的后半段剧情。解决严格按typhoon_id切分确保同一编号的所有记录都落在同一个集合里。我后来在切分时加了一行唯一性断言任何跨集合的台风编号直接抛异常比事后发现泄漏省时间。还有另一种泄漏来自滑窗算法的边界设计。如果训练样本的时间窗口终点和验证样本的时间窗口起点紧挨着模型虽然没有直接见过未来但训练样本的标签时刻可能和验证样本的输入窗口重合等于半个样本已经看过答案。处理办法是在训练集和验证集之间保留一个“空窗期”比如同一条台风的时间序列上训练样本标签之后、验证样本输入之前的记录直接丢出。5.2 解压报错invalid zip archive: could not find EOCD现象zipfile打开时报zipfile.BadZipFile: File is not a zip file或者解压到一半报could not find EOCD。原因最常见是zip文件没下载完整EOCD是zip结构末尾的中央目录结束标志文件被截断时它不在末尾。另一种情况是伪加密修改标志位后又被某些压缩软件重写导致内外标记不一致。解决先用unzip -t或testzip()检查整个包确认是下载截断就重新下载并核对大小如果只是伪加密按第2章的方法处理标志位后重新打包。5.3 风圈缺测模型学到的是气候平均值现象训练代码对缺失的风速、气压做了线性插值训练过程很平稳但预测出的风速曲线平得像平均场完全捕捉不到台风快速增强过程。原因台风实测序列中vmax缺测并不少见线性插值会把缺测点两端的值拉成一条直线模型学到的全是“平滑变化”这种伪规律。解决对vmax和pres不要盲目插值要么在特征里加一个mask指示缺失位要么直接丢弃缺失比例超过一半的台风。我的经验是丢掉一部分数据比编造数据更诚实宁可样本量少一些也不能让模型学会把一切变化都抹平。5.4 深度学习环境配置装了CUDA反而更慢现象同一套LSTM在笔记本CPU上跑得还行换到带独显的机器上反而每一步都变慢显存占用还高。原因小模型、小batch在GPU上的kernel启动开销和CPU到GPU的拷贝时间远大于计算本身的收益。解决先把batch_size从64调大到512再上GPU如果总样本量只有几千干脆就用CPU训练。判断自己处在哪种情况并不难打开任务管理器看计算期间GPU利用率是否超过60%不到就说明数据传输在拖后腿。深度学习环境配置这一步看起来不起眼但它比调网络结构更影响实际效率。强行追求CUDA版本反而会让pip环境装出一堆互不兼容的依赖不如先让CPU版本把流程跑通。5.5 强台风样本太少模型只会预测“偏弱”现象历史数据里强台风和超强台风只占很少比例训练出的模型对台风报得总是偏低MAE中等但高影响事件全部漏报。原因回归模型在均方误差指导下倾向于把输出压在样本分布的均值附近少数高风速样本贡献的梯度不够。解决对y_train做截断或分桶加权把高风速样本的loss权重提高也可以改用HuberLoss或把速度取对数后再回归缓解大值区域梯度被平均掉的问题。气象业务里“把强台风报弱”比“把弱台风报强”更致命这个坑必须主动处理。如果你做的是分类还能用类别权重采样但回归场景更常见的是直接改损失函数。6. 上线前回测把“预测”变成“可决策”模型训练不是终点最后一步是按台风做分组回测。不要只报告一个整体MAE我一般会额外输出按强台风分层的误差以及预测值与观测值的散点斜率。用PyTorch训练脚本里保存的最佳权重对验证集逐条预测然后用sklearn计算指标。from sklearn.metrics import mean_absolute_error, r2_score y_true val_y.flatten() y_pred val_pred.flatten() print(整体MAE: %.3f m/s % mean_absolute_error(y_true, y_pred)) strong_mask y_true 32.7 # 达到12级台风以上 print(强台风MAE: %.3f m/s % mean_absolute_error(y_true[strong_mask], y_pred[strong_mask])) print(R2: %.3f % r2_score(y_true, y_pred))风速32.7m/s是气象上12级台风的门槛单独看这一组的误差比整体MAE更容易暴露漏报问题。我还会把预测值和观测值画成散点顺便数一下“预测强但是实际弱”和“预测弱但实际强”两类样本的比例后者的比例是业务评审时最关心的一项。进阶玩法是量化模型预测的不确定性用集成多个随机种子的模型取预测分布的方差作为置信区间。台风决策喜欢看“可能达到的极端值”所以我在交付zip时通常把模型输出的90分位数单独存一列而不是只报平均预测。这套流程我自己走下来最大的教训是解压和数据切分的时间永远比模型调参长一份整齐的zip注释和目录结构抵得上十次重跑实验。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑