使用 dill 库保存和加载 neupy 算法可以 return 同一时间段的不同预测?
Saving and loading neupy algorithm with dill library can return different predictions for the same time period?
首先感谢您阅读本文,如果您能提供帮助,在此先感谢您。
这是我用于监督学习的算法:
# Define neural network
cgnet = algorithms.LevenbergMarquardt(
connection=[
layers.Input(XTrain.shape[1]),
layers.Relu(6),
layers.Linear(1)
],
mu_update_factor=2,
mu=0.1,
shuffle_data=True,
verbose=True,
decay_rate=0.1,
addons=[algorithms.WeightElimination]
)
交叉验证结果良好 (k=10):
[0.16767815652364237, 0.13396493112368024, 0.19033966833586402, 0.12023567250054788, 0.11826824035439124, 0.13115856672872392, 0.14250003819441104, 0.12729442202775898, 0.31073760721487326, 0.19299511349686768]
[0.9395976956178138, 0.9727526340820827, 0.9410503161549465, 0.9740922179654977, 0.9764171089773663, 0.9707258917808179, 0.9688830174583372, 0.973160633351555, 0.8551738446276884, 0.936661707991699]
MEA: 0.16 (+/- 0.11)
R2: 0.95 (+/- 0.07)
训练后我用 dill 保存了算法:
with open('network-storage.dill', 'wb') as f:
dill.dump(cgnet, f)
然后,如果我用 dill 加载网络并考虑整个训练集的 X 值,我得到相同的 R2 (0.9691),直到现在一切正常。这是结果:
如果我尝试做同样的事情但只在最近几年 [2018-2022] 我得到这个(用 X 训练值(2018 到 2022)预测 y):
而不是这个(用 X 训练值(1992 到 2022)预测 y):
为什么当我加载不同的X值范围时,同一时期得到不同的预测? (1992 年到 2022 年的 X 输入:1992 年到 2022 年的 y 预测是可以的。
(X input from 2018 to 2022: y prediction for 2018 to 2022 is not ok.
这是代码:
import numpy as np
import pandas as pd
import datetime as dt
import matplotlib.pyplot as plt
import dill
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn import metrics
from sklearn.model_selection import KFold
from scipy.interpolate import Rbf
from scipy import stats
from neupy import layers, environment, algorithms
from neupy import plots
# Import data
data = pd.read_excel('DataAL_Incremento.xlsx', index_col=0, header=1).iloc[:,[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,-1]]
data.columns = ['PPO4L(in)','PPO4(in)','NH4L(in)','NH4(in)','NO3L(in)','NNO3(in)','CBOL(in)', 'CBO(in)','Temp(In)','Temp(alb)','Tair ','Tdew',
'Wvel','Cl_aL(in)','Cl_a(in)','ODL(in)','OD(in)','Qin(in)','ODalb','PPO4(alb)','NNO3(alb)']
# Add filtered data
tmp0 = data.iloc[:,[9, 6, 14]].rolling(9, center=False, axis=0).mean()
tmp0.columns = ['Temp(alb)_09','CBOL(in)_09','Cl_a(in)_09']
tmp1 = data.iloc[:,[9, 6, 14]].rolling(15, center=False, axis=0).mean()
tmp1.columns = ['Temp(alb)_15', 'CBOL(in)_15','Cl_a(in)_15']
tmp2 = data.iloc[:,[9, 6, 14]].rolling(31, center=False, axis=0).mean()
tmp2.columns = ['Temp(alb)_31', 'CBOL(in)_31','Cl_a(in)_31']
data = pd.concat((data, tmp0, tmp1, tmp2), axis=1)
# Drop empty records
data = data.dropna()
# Define data
X = data.loc[:, ['CBOL(in)', 'CBO(in)','Temp(In)','Temp(alb)','Tair ','Cl_aL(in)','Cl_a(in)','OD(in)','Temp(alb)_31', 'CBOL(in)_31','Cl_a(in)_31']]
y = data.loc[:, ['ODalb']]
years = data.index.year
yearsTrain = range(1992,2022)
yearsTest = 2019,2020,2021
#yearsTrain, yearsTest = train_test_split(np.unique(years), test_size=0.2, train_size=0.8, random_state=None)
XTrain = X.query('@years in @yearsTrain')
yTrain = y.query('@years in @yearsTrain').values.ravel()
XTest = X.query('@years in @yearsTest')
yTest = y.query('@years in @yearsTest').values.ravel()
results = y.query('@years in @yearsTest')
#===============================================================================
# Neural network
#===============================================================================
# Define neural network
cgnet = algorithms.LevenbergMarquardt(
connection=[
layers.Input(XTrain.shape[1]),
layers.Relu(6),
layers.Linear(1)
],
mu_update_factor=2,
mu=0.1,
shuffle_data=True,
verbose=True,
decay_rate=0.1,
addons=[algorithms.WeightElimination]
)
# Scale
XScaler = StandardScaler()
XScaler.fit(XTrain)
XTrainScaled = XScaler.transform(XTrain)
XTestScaled = XScaler.transform(XTest)
yScaler = StandardScaler()
yScaler.fit(yTrain.reshape(-1, 1))
yTrainScaled = yScaler.transform(yTrain.reshape(-1, 1)).ravel()
yTestScaled = yScaler.transform(yTest.reshape(-1, 1)).ravel()
# Train
cgnet.train(XTrainScaled, yTrainScaled, XTestScaled, yTestScaled, epochs=30)
yEstTrain = yScaler.inverse_transform(cgnet.predict(XTrainScaled).reshape(-1, 1)).ravel()
mae = np.mean(np.abs(yTrain-yEstTrain))
results['ANN'] = yScaler.inverse_transform(cgnet.predict(XTestScaled).reshape(-1, 1)).ravel()
# Metrics
mse = np.mean((yTrain-yEstTrain)**2)
mseTes = np.mean((yTest-results['ANN'])**2)
maeTes = np.mean(np.abs(yTest-results['ANN']))
meantrain = np.mean(yTrain)
ssTest = (yTrain-meantrain)**2
r2=(1-(mse/(np.mean(ssTest))))
meantest = np.mean(yTest)
ssTrain = (yTest-meantest)**2
r2Tes=(1-(mseTes/(np.mean(ssTrain))))
# Plot results
print("NN MAE: %f (All), %f (Test) " % (mae, maeTes))
print ("NN MSE: %f (All), %f (Test) " % (mse, mseTes))
print ("NN R2: %f (All), %f (Test) " % (r2, r2Tes))
results.plot()
plt.show(block=True)
plots.error_plot(cgnet)
plt.show(block=True)
plt.scatter(yTest,results['ANN'])
plt.xlabel('True Values')
plt.ylabel('Predictions')
plt.show(block=True)
#===============================================================================
# Save algorithms - Neural network
#===============================================================================
with open('network-storage.dill', 'wb') as f:
dill.dump(cgnet, f)
#===============================================================================
# Load algorithms - Neural network
#===============================================================================
#Prepare data
dataVal = pd.read_excel('DataAL_IncrementoTeste.xlsx', index_col=0, header=1).iloc[:,[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,-1]]
dataVal.columns = ['PPO4L(in)','PPO4(in)','NH4L(in)','NH4(in)','NO3L(in)','NNO3(in)','CBOL(in)', 'CBO(in)','Temp(In)','Temp(alb)','Tair ','Tdew',
'Wvel','Cl_aL(in)','Cl_a(in)','ODL(in)','OD(in)','Qin(in)','ODalb','PPO4(alb)','NNO3(alb)']
# Add filtered data
tmp0 = dataVal.iloc[:,[9, 6, 14]].rolling(9, center=False, axis=0).mean()
tmp0.columns = ['Temp(alb)_09','CBOL(in)_09','Cl_a(in)_09']
tmp1 = dataVal.iloc[:,[9, 6, 14]].rolling(15, center=False, axis=0).mean()
tmp1.columns = ['Temp(alb)_15', 'CBOL(in)_15','Cl_a(in)_15']
tmp2 = dataVal.iloc[:,[9, 6, 14]].rolling(31, center=False, axis=0).mean()
tmp2.columns = ['Temp(alb)_31', 'CBOL(in)_31','Cl_a(in)_31']
dataVal = pd.concat((dataVal, tmp0, tmp1, tmp2), axis=1)
# Drop empty records (removes adjacent columns)
dataVal = dataVal.dropna()
# Define data
Xval = dataVal.loc[:, ['CBOL(in)', 'CBO(in)','Temp(In)','Temp(alb)','Tair ','Cl_aL(in)','Cl_a(in)','OD(in)','Temp(alb)_31', 'CBOL(in)_31','Cl_a(in)_31']]
yval = dataVal.loc[:, ['ODalb']]
years = dataVal.index.year
yearsTrain = range(2018,2022)
XFinalVal = Xval.query('@years in @yearsTrain')
yFinalVal = yval.query('@years in @yearsTrain').values.ravel()
resultsVal = yval.query('@years in @yearsTrain')
# Load algorithms
with open('network-storage.dill', 'rb') as f:
cgnet = dill.load(f)
# Scale X
XScaler = StandardScaler()
XScaler.fit(XFinalVal)
XFinalScaled = XScaler.transform(XFinalVal)
# Scale y
yScaler = StandardScaler()
yScaler.fit(yFinalVal.reshape(-1, 1))
yTrainScaled = yScaler.transform(yFinalVal.reshape(-1, 1)).ravel()
# Predict
y_predicted = yScaler.inverse_transform(cgnet.predict(XFinalScaled).reshape(-1, 1)).ravel()
resultsVal['ANN'] = y_predicted
scoreMean = metrics.mean_absolute_error(yFinalVal, y_predicted)
scoreR2 = metrics.r2_score(yFinalVal, y_predicted)
print(scoreMean)
print(scoreR2)
plt.scatter(yFinalVal,y_predicted)
plt.xlabel('True Values')
plt.ylabel('Predictions')
plt.show(block=True)
resultsVal.plot()
plt.show(block=True)
#===============================================================================
# Cross validation - Neural network
#===============================================================================
XScaler = StandardScaler()
XScaler.fit(XTrain)
XTrainScaled = XScaler.transform(XTrain)
XTestScaled = XScaler.transform(XTest)
yScaler = StandardScaler()
yScaler.fit(yTrain.reshape(-1, 1))
yTrainScaled = yScaler.transform(yTrain.reshape(-1, 1)).ravel()
yTestScaled = yScaler.transform(yTest.reshape(-1, 1)).ravel()
kfold = KFold(n_splits=10, shuffle=True, random_state=None)
scoresMean = []
scoresR2 = []
for train, test in kfold.split(XTrainScaled):
x_train, x_test = XTrainScaled[train], XTrainScaled[test]
y_train, y_test = yTrainScaled[train], yTrainScaled[test]
cgnet = algorithms.LevenbergMarquardt(
connection=[
layers.Input(XTrain.shape[1]),
layers.Relu(6),
layers.Linear(1)
],
mu_update_factor=2,
mu=0.1,
shuffle_data=True,
verbose=True,
decay_rate=0.1,
addons=[algorithms.WeightElimination]
)
cgnet.train(x_train, y_train, epochs=100)
y_predicted = cgnet.predict(x_test)
scoreMean = metrics.mean_absolute_error(y_test, y_predicted)
scoreR2 = metrics.r2_score(y_test, y_predicted)
scoresMean.append(scoreMean)
scoresR2.append(scoreR2)
print(scoresMean)
print(scoresR2)
scoresMean = np.array(scoresMean)
scoresR2 = np.array(scoresR2)
print("MEA: %0.2f (+/- %0.2f)" % (scoresMean.mean(), scoresMean.std() * 2))
print("R2: %0.2f (+/- %0.2f)" % (scoresR2.mean(), scoresR2.std() * 2))
我认为问题之一可能与您在训练前应用的缩放有关。在训练阶段,你使用训练数据拟合缩放函数
XScaler = StandardScaler()
XScaler.fit(XTrain)
但是在使用 dill 加载网络后,您已经为缩放器安装了不同的数据(特别是验证数据)
XScaler = StandardScaler()
XScaler.fit(XFinalVal)
在第二种情况下,您对网络在训练期间未见过的预测使用不同的缩放比例。与网络预期的样本相比,新的缩放比例可能会产生不同的样本分布。
为了使训练效果可重现,您还需要保存 XScaler
并在加载网络时同时加载它。
我所描述的一切也适用于 yScaler
首先感谢您阅读本文,如果您能提供帮助,在此先感谢您。 这是我用于监督学习的算法:
# Define neural network
cgnet = algorithms.LevenbergMarquardt(
connection=[
layers.Input(XTrain.shape[1]),
layers.Relu(6),
layers.Linear(1)
],
mu_update_factor=2,
mu=0.1,
shuffle_data=True,
verbose=True,
decay_rate=0.1,
addons=[algorithms.WeightElimination]
)
交叉验证结果良好 (k=10):
[0.16767815652364237, 0.13396493112368024, 0.19033966833586402, 0.12023567250054788, 0.11826824035439124, 0.13115856672872392, 0.14250003819441104, 0.12729442202775898, 0.31073760721487326, 0.19299511349686768]
[0.9395976956178138, 0.9727526340820827, 0.9410503161549465, 0.9740922179654977, 0.9764171089773663, 0.9707258917808179, 0.9688830174583372, 0.973160633351555, 0.8551738446276884, 0.936661707991699]
MEA: 0.16 (+/- 0.11)
R2: 0.95 (+/- 0.07)
训练后我用 dill 保存了算法:
with open('network-storage.dill', 'wb') as f:
dill.dump(cgnet, f)
然后,如果我用 dill 加载网络并考虑整个训练集的 X 值,我得到相同的 R2 (0.9691),直到现在一切正常。这是结果:
如果我尝试做同样的事情但只在最近几年 [2018-2022] 我得到这个(用 X 训练值(2018 到 2022)预测 y):
而不是这个(用 X 训练值(1992 到 2022)预测 y):
为什么当我加载不同的X值范围时,同一时期得到不同的预测? (1992 年到 2022 年的 X 输入:1992 年到 2022 年的 y 预测是可以的。 (X input from 2018 to 2022: y prediction for 2018 to 2022 is not ok.
这是代码:
import numpy as np
import pandas as pd
import datetime as dt
import matplotlib.pyplot as plt
import dill
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn import metrics
from sklearn.model_selection import KFold
from scipy.interpolate import Rbf
from scipy import stats
from neupy import layers, environment, algorithms
from neupy import plots
# Import data
data = pd.read_excel('DataAL_Incremento.xlsx', index_col=0, header=1).iloc[:,[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,-1]]
data.columns = ['PPO4L(in)','PPO4(in)','NH4L(in)','NH4(in)','NO3L(in)','NNO3(in)','CBOL(in)', 'CBO(in)','Temp(In)','Temp(alb)','Tair ','Tdew',
'Wvel','Cl_aL(in)','Cl_a(in)','ODL(in)','OD(in)','Qin(in)','ODalb','PPO4(alb)','NNO3(alb)']
# Add filtered data
tmp0 = data.iloc[:,[9, 6, 14]].rolling(9, center=False, axis=0).mean()
tmp0.columns = ['Temp(alb)_09','CBOL(in)_09','Cl_a(in)_09']
tmp1 = data.iloc[:,[9, 6, 14]].rolling(15, center=False, axis=0).mean()
tmp1.columns = ['Temp(alb)_15', 'CBOL(in)_15','Cl_a(in)_15']
tmp2 = data.iloc[:,[9, 6, 14]].rolling(31, center=False, axis=0).mean()
tmp2.columns = ['Temp(alb)_31', 'CBOL(in)_31','Cl_a(in)_31']
data = pd.concat((data, tmp0, tmp1, tmp2), axis=1)
# Drop empty records
data = data.dropna()
# Define data
X = data.loc[:, ['CBOL(in)', 'CBO(in)','Temp(In)','Temp(alb)','Tair ','Cl_aL(in)','Cl_a(in)','OD(in)','Temp(alb)_31', 'CBOL(in)_31','Cl_a(in)_31']]
y = data.loc[:, ['ODalb']]
years = data.index.year
yearsTrain = range(1992,2022)
yearsTest = 2019,2020,2021
#yearsTrain, yearsTest = train_test_split(np.unique(years), test_size=0.2, train_size=0.8, random_state=None)
XTrain = X.query('@years in @yearsTrain')
yTrain = y.query('@years in @yearsTrain').values.ravel()
XTest = X.query('@years in @yearsTest')
yTest = y.query('@years in @yearsTest').values.ravel()
results = y.query('@years in @yearsTest')
#===============================================================================
# Neural network
#===============================================================================
# Define neural network
cgnet = algorithms.LevenbergMarquardt(
connection=[
layers.Input(XTrain.shape[1]),
layers.Relu(6),
layers.Linear(1)
],
mu_update_factor=2,
mu=0.1,
shuffle_data=True,
verbose=True,
decay_rate=0.1,
addons=[algorithms.WeightElimination]
)
# Scale
XScaler = StandardScaler()
XScaler.fit(XTrain)
XTrainScaled = XScaler.transform(XTrain)
XTestScaled = XScaler.transform(XTest)
yScaler = StandardScaler()
yScaler.fit(yTrain.reshape(-1, 1))
yTrainScaled = yScaler.transform(yTrain.reshape(-1, 1)).ravel()
yTestScaled = yScaler.transform(yTest.reshape(-1, 1)).ravel()
# Train
cgnet.train(XTrainScaled, yTrainScaled, XTestScaled, yTestScaled, epochs=30)
yEstTrain = yScaler.inverse_transform(cgnet.predict(XTrainScaled).reshape(-1, 1)).ravel()
mae = np.mean(np.abs(yTrain-yEstTrain))
results['ANN'] = yScaler.inverse_transform(cgnet.predict(XTestScaled).reshape(-1, 1)).ravel()
# Metrics
mse = np.mean((yTrain-yEstTrain)**2)
mseTes = np.mean((yTest-results['ANN'])**2)
maeTes = np.mean(np.abs(yTest-results['ANN']))
meantrain = np.mean(yTrain)
ssTest = (yTrain-meantrain)**2
r2=(1-(mse/(np.mean(ssTest))))
meantest = np.mean(yTest)
ssTrain = (yTest-meantest)**2
r2Tes=(1-(mseTes/(np.mean(ssTrain))))
# Plot results
print("NN MAE: %f (All), %f (Test) " % (mae, maeTes))
print ("NN MSE: %f (All), %f (Test) " % (mse, mseTes))
print ("NN R2: %f (All), %f (Test) " % (r2, r2Tes))
results.plot()
plt.show(block=True)
plots.error_plot(cgnet)
plt.show(block=True)
plt.scatter(yTest,results['ANN'])
plt.xlabel('True Values')
plt.ylabel('Predictions')
plt.show(block=True)
#===============================================================================
# Save algorithms - Neural network
#===============================================================================
with open('network-storage.dill', 'wb') as f:
dill.dump(cgnet, f)
#===============================================================================
# Load algorithms - Neural network
#===============================================================================
#Prepare data
dataVal = pd.read_excel('DataAL_IncrementoTeste.xlsx', index_col=0, header=1).iloc[:,[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,-1]]
dataVal.columns = ['PPO4L(in)','PPO4(in)','NH4L(in)','NH4(in)','NO3L(in)','NNO3(in)','CBOL(in)', 'CBO(in)','Temp(In)','Temp(alb)','Tair ','Tdew',
'Wvel','Cl_aL(in)','Cl_a(in)','ODL(in)','OD(in)','Qin(in)','ODalb','PPO4(alb)','NNO3(alb)']
# Add filtered data
tmp0 = dataVal.iloc[:,[9, 6, 14]].rolling(9, center=False, axis=0).mean()
tmp0.columns = ['Temp(alb)_09','CBOL(in)_09','Cl_a(in)_09']
tmp1 = dataVal.iloc[:,[9, 6, 14]].rolling(15, center=False, axis=0).mean()
tmp1.columns = ['Temp(alb)_15', 'CBOL(in)_15','Cl_a(in)_15']
tmp2 = dataVal.iloc[:,[9, 6, 14]].rolling(31, center=False, axis=0).mean()
tmp2.columns = ['Temp(alb)_31', 'CBOL(in)_31','Cl_a(in)_31']
dataVal = pd.concat((dataVal, tmp0, tmp1, tmp2), axis=1)
# Drop empty records (removes adjacent columns)
dataVal = dataVal.dropna()
# Define data
Xval = dataVal.loc[:, ['CBOL(in)', 'CBO(in)','Temp(In)','Temp(alb)','Tair ','Cl_aL(in)','Cl_a(in)','OD(in)','Temp(alb)_31', 'CBOL(in)_31','Cl_a(in)_31']]
yval = dataVal.loc[:, ['ODalb']]
years = dataVal.index.year
yearsTrain = range(2018,2022)
XFinalVal = Xval.query('@years in @yearsTrain')
yFinalVal = yval.query('@years in @yearsTrain').values.ravel()
resultsVal = yval.query('@years in @yearsTrain')
# Load algorithms
with open('network-storage.dill', 'rb') as f:
cgnet = dill.load(f)
# Scale X
XScaler = StandardScaler()
XScaler.fit(XFinalVal)
XFinalScaled = XScaler.transform(XFinalVal)
# Scale y
yScaler = StandardScaler()
yScaler.fit(yFinalVal.reshape(-1, 1))
yTrainScaled = yScaler.transform(yFinalVal.reshape(-1, 1)).ravel()
# Predict
y_predicted = yScaler.inverse_transform(cgnet.predict(XFinalScaled).reshape(-1, 1)).ravel()
resultsVal['ANN'] = y_predicted
scoreMean = metrics.mean_absolute_error(yFinalVal, y_predicted)
scoreR2 = metrics.r2_score(yFinalVal, y_predicted)
print(scoreMean)
print(scoreR2)
plt.scatter(yFinalVal,y_predicted)
plt.xlabel('True Values')
plt.ylabel('Predictions')
plt.show(block=True)
resultsVal.plot()
plt.show(block=True)
#===============================================================================
# Cross validation - Neural network
#===============================================================================
XScaler = StandardScaler()
XScaler.fit(XTrain)
XTrainScaled = XScaler.transform(XTrain)
XTestScaled = XScaler.transform(XTest)
yScaler = StandardScaler()
yScaler.fit(yTrain.reshape(-1, 1))
yTrainScaled = yScaler.transform(yTrain.reshape(-1, 1)).ravel()
yTestScaled = yScaler.transform(yTest.reshape(-1, 1)).ravel()
kfold = KFold(n_splits=10, shuffle=True, random_state=None)
scoresMean = []
scoresR2 = []
for train, test in kfold.split(XTrainScaled):
x_train, x_test = XTrainScaled[train], XTrainScaled[test]
y_train, y_test = yTrainScaled[train], yTrainScaled[test]
cgnet = algorithms.LevenbergMarquardt(
connection=[
layers.Input(XTrain.shape[1]),
layers.Relu(6),
layers.Linear(1)
],
mu_update_factor=2,
mu=0.1,
shuffle_data=True,
verbose=True,
decay_rate=0.1,
addons=[algorithms.WeightElimination]
)
cgnet.train(x_train, y_train, epochs=100)
y_predicted = cgnet.predict(x_test)
scoreMean = metrics.mean_absolute_error(y_test, y_predicted)
scoreR2 = metrics.r2_score(y_test, y_predicted)
scoresMean.append(scoreMean)
scoresR2.append(scoreR2)
print(scoresMean)
print(scoresR2)
scoresMean = np.array(scoresMean)
scoresR2 = np.array(scoresR2)
print("MEA: %0.2f (+/- %0.2f)" % (scoresMean.mean(), scoresMean.std() * 2))
print("R2: %0.2f (+/- %0.2f)" % (scoresR2.mean(), scoresR2.std() * 2))
我认为问题之一可能与您在训练前应用的缩放有关。在训练阶段,你使用训练数据拟合缩放函数
XScaler = StandardScaler()
XScaler.fit(XTrain)
但是在使用 dill 加载网络后,您已经为缩放器安装了不同的数据(特别是验证数据)
XScaler = StandardScaler()
XScaler.fit(XFinalVal)
在第二种情况下,您对网络在训练期间未见过的预测使用不同的缩放比例。与网络预期的样本相比,新的缩放比例可能会产生不同的样本分布。
为了使训练效果可重现,您还需要保存 XScaler
并在加载网络时同时加载它。
我所描述的一切也适用于 yScaler