即使对于训练数据集,深度学习模型也没有获得完全超出范围的训练预测值,并且为 R2 提供了巨大的负值。
如果我运行以下代码,我会得到 R2 的巨大负值。数据集很大,尤其是有很多特征。这是一个简化的数据文件,仍然能够重现问题:text。如果我使用简单的线性回归或 SVR 算法运行相同的数据,我会得到一个很好的值(请参阅下一个代码)。
我摆弄了参数,主要是层数、每层单元数和学习率,没有成功。我还尝试标准化数据。
对于其他较小的问题,类似的代码也有效。你知道可能是什么问题吗?也许这对 DL 来说不是问题?
这里是深度学习模型:
import pandas as pd
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
from scikeras.wrappers import KerasRegressor
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import KFold
var='target'
matrixpd = pd.read_csv('data.csv', index_col=0)
md=matrixpd[var]
matrixpd = matrixpd.drop(columns=var)
def build_model():
model = keras.Sequential([
layers.Dense(16, activation='relu', input_shape=[len(matrixpd.keys())]),
# layers.Dense(16, activation='relu'),
layers.Dense(1)
])
optimizer = tf.keras.optimizers.RMSprop(0.01)
model.compile(loss='mse',
optimizer=optimizer,
metrics=['mae', 'mse'])
return model
EPOCHS = 100
estimator = KerasRegressor(model=build_model, epochs=EPOCHS, verbose=0)
kfold = KFold(n_splits=3)
results = cross_val_score(estimator, matrixpd, md, cv=kfold, scoring='r2')
print("R2: %.2f (%.2f)" % (results.mean(), results.std()))
这里是线性回归模型:
import pandas as pd
from sklearn import datasets, linear_model
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import KFold
var='target'
matrixpd = pd.read_csv('data.csv', index_col=0)
md=matrixpd[var]
matrixpd = matrixpd.drop(columns=var)
model = linear_model.LinearRegression()
kfold = KFold(n_splits=3)
results = cross_val_score(model, matrixpd, md, cv=kfold, scoring='r2')
print("R2: %.2f (%.2f)" % (results.mean(), results.std()))
谢谢!
我能够在 PyTorch 中使用该数据训练模型。与您的架构的主要区别是:
我发现它有助于逐渐缩小通道,而不是突然过渡到 16 单元层。有 500 个输入特征,我做了以下操作:
密集(out = 500),ReLU,BN
密集(250),ReLU,BN
密集(125),ReLU,BN
密集(64),ReLU,BN
密集(1)
您可以放弃一些批量规范(BN),根据一些快速实验,它仍然可以正常工作。
我发现
RMSprop
很难收敛,而学习率为 Adam
的 0.01
收敛得很好。
我运行了 200 个 epoch。列车MSE进展如下:
纪元 0 |损失:8250
第 20 纪元 |损失:7486
第 40 纪元 |损失:5677
第 60 纪元 |损失:2932
80纪元|损失:699
纪元 100 |损失:16
纪元 120 |损失:6
纪元 140 |损失:0.7
纪元 160 |损失:0.07
纪元180 |损失:0.01
如您所见,前 60-80 个 epoch 的初始值相对较高,之后急剧下降。
我使用下面的方法对数据进行归一化,但发现它对收敛影响不大,可能是因为 BN 执行了自己的标准化。
matrixpd_scaled = (matrixpd - matrixpd.mean(axis=0)) / matrixpd.std(axis=0)
仅供参考,我的 PyTorch 代码是:
import torch, torch.nn as nn
#load data and split into features/target
data = pd.read_csv('data.csv', index_col=0)
y = data['target'].to_numpy().ravel()
x = data.drop(columns='target')
#standardise features per channel
x_n = (x - x.mean(axis=0)) / x.std(axis=0)
torch.manual_seed(100) #for reproducible results
#Define the model. A tapered dense network.
model = nn.Sequential(nn.Linear(x.shape[1], 500), nn.ReLU(), nn.BatchNorm1d(500),
nn.Linear(500, 250), nn.ReLU(), nn.BatchNorm1d(250),
nn.Linear(250, 125), nn.ReLU(), nn.BatchNorm1d(125),
nn.Linear(125, 64), nn.ReLU(), nn.BatchNorm1d(64),
nn.Linear(64, 1))
#optim = torch.optim.RMSprop(model.parameters(), 0.01)
optim = torch.optim.Adam(model.parameters(), 0.01)
for epoch in range(200):
#prediction and MSE loss
yhat = model(torch.tensor(x_n.values).to(torch.float32))
loss = nn.MSELoss()(yhat.ravel(), torch.tensor(y).to(torch.float32))
#Backprop
optim.zero_grad()
loss.backward()
optim.step()
if epoch % 20 == 0:
print('epoch', epoch, '| loss:', loss.item())