预测效果
代码功能
该代码实现了一个结合卷积神经网络(CNN)和Kolmogorov–Arnold网络(KAN)的混合模型(CNN-KAN),用于时间序列预测任务。核心功能包括:
- 数据加载与预处理:加载标准化后的训练集和测试集(时间序列数据)。
- 模型构建:
- CNN部分:提取时间序列的局部特征(使用1D卷积层和池化层)。
- KAN部分:替代全连接层,通过样条基函数增强非线性拟合能力,提高预测精度。
- 模型训练与评估:使用MSE损失和Adam优化器训练模型,保存最佳模型参数,并在测试集上计算评估指标(MSE、RMSE、MAE、R²)。
- 结果可视化:绘制训练/测试损失曲线,并反归一化预测结果。
算法步骤
-
数据加载
- 使用
joblib
加载预处理后的训练集(train_set
,train_label
)和测试集(test_set
,test_label
)。 - 封装为
DataLoader
(批量大小=64)。
- 使用
-
模型定义
KANLinear
层:- 基础线性变换 + 样条基函数(B-splines)的非线性变换。
- 支持动态网格更新和正则化损失计算。
CNN1DKANModel
:- 卷积块:多个
Conv1d + ReLU + MaxPool1d
层(参考VGG架构)。 - 自适应平均池化:替代全连接层,减少参数量。
- KAN输出层:生成最终预测结果。
- 卷积块:多个
-
模型训练
- 损失函数:均方误差(
MSELoss
)。 - 优化器:Adam(学习率=0.0003)。
- 训练循环:
- 前向传播 → 计算损失 → 反向传播 → 参数更新。
- 记录每个epoch的训练/测试MSE,保存最佳模型(最低测试MSE)。
- 损失函数:均方误差(
-
模型评估
- 加载最佳模型进行预测。
- 计算指标:
R²
(模型拟合优度)、MSE
、RMSE
、MAE
。 - 反归一化预测结果(使用预训练的
StandardScaler
)。
-
可视化
- 绘制训练/测试MSE随epoch的变化曲线。
- 输出评估指标和反归一化后的结果。
技术路线
- 框架:PyTorch(模型构建、训练、评估)。
- 数据预处理:使用
StandardScaler
标准化数据(通过joblib
保存/加载)。 - 模型架构:
- 特征提取:CNN(1D卷积层)捕获时间序列局部模式。
- 非线性映射:KAN层替代传统全连接层,通过样条函数灵活拟合复杂关系。
- 评估指标:
sklearn
计算R²
、MSE
等。 - 可视化:
matplotlib
绘制损失曲线。
关键参数设定
参数 | 值 | 说明 |
---|---|---|
batch_size | 64 | 数据批量大小 |
epochs | 50 | 训练轮数 |
learn_rate | 0.0003 | Adam优化器学习率 |
conv_archs | ((2, 32), (2, 64)) | CNN层配置(卷积层数×通道数) |
grid_size | 5 | KAN样条网格大小 |
spline_order | 3 | 样条多项式阶数 |
output_dim | 1 | 预测输出维度(回归任务) |
运行环境
- Python库:
torch, joblib, numpy, pandas, sklearn, matplotlib
- 硬件:支持CUDA的GPU(优先)或CPU(自动切换)。
- 数据依赖:
- 预处理的训练/测试集文件(
train_set
,train_label
等)。 - 预训练的
StandardScaler
(scaler
文件)。
- 预处理的训练/测试集文件(
应用场景
- 时间序列预测:
- 如股票价格、气象数据、电力负荷等序列数据的未来值预测。
- 高非线性关系建模:
- KAN层通过样条基函数灵活拟合复杂非线性模式,优于传统全连接层。
- 轻量化模型需求:
- 自适应池化替代全连接层,减少参数量(模型总参数量:22,432)。
- 研究验证:
- 探索CNN与KAN结合的混合架构在预测任务中的有效性(最终
R²=0.995
,拟合优度高)。
- 探索CNN与KAN结合的混合架构在预测任务中的有效性(最终
补充说明
- 创新点:KAN作为输出层,通过动态网格更新和正则化约束(L1 + 熵),增强模型表达能力。
- 性能:50个epoch后测试集
MSE=0.2627
(反归一化后MSE=0.0041
),预测精度高。 - 扩展性:可通过调整卷积架构、KAN参数适配不同时间序列长度和复杂度。
完整代码
- 完整代码订阅专栏获取
# 模型预测
# 模型 测试集 验证
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")# 模型加载
model = torch.load('best_model_cnn_kan.pt')
model = model.to(device)# 预测数据
original_data = []
pre_data = []
with torch.no_grad():for data, label in test_loader:origin_lable = label.tolist()original_data += origin_lablemodel.eval() # 将模型设置为评估模式data, label = data.to(device), label.to(device)# 预测test_pred = model(data) # 对测试集进行预测test_pred = test_pred.tolist()pre_data += test_pred
[8]
import numpy as np
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score# 模型分数
score = r2_score(original_data, pre_data)
print('*'*50)
print('模型分数--R^2:',score)print('*'*50)
# 测试集上的预测误差
test_mse = mean_squared_error(original_data, pre_data)
test_rmse = np.sqrt(test_mse)
test_mae = mean_absolute_error(original_data, pre_data)
print('测试数据集上的均方误差--MSE: ',test_mse)
print('测试数据集上的均方根误差--RMSE: ',test_rmse)
print('测试数据集上的平均绝对误差--MAE: ',test_mae)
**************************************************
模型分数--R^2: 0.9954956071920047
**************************************************
测试数据集上的均方误差--MSE: 0.004104453060426307
测试数据集上的均方根误差--RMSE: 0.06406600549766082
测试数据集上的平均绝对误差--MAE: 0.047805079976603375[19]
from sklearn.preprocessing import StandardScaler, MinMaxScaler# 将列表转换为 NumPy 数组
original_data = np.array(original_data)
pre_data = np.array(pre_data)# 反归一化处理
# 使用相同的均值和标准差对预测结果进行反归一化处理
# 反标准化
scaler = load('scaler')
original_data = scaler.inverse_transform(original_data)
pre_data = scaler.inverse_transform(pre_data)
[20]
# 可视化结果
plt.figure(figsize=(12, 6), dpi=100)
plt.plot(original_data, label='原始值',color='orange') # 真实值
plt.plot(pre_data, label='CNN-KAN预测值',color='green') # 预测值
plt.legend()
plt.show()