为什么在神经网络训练期间损失没有下降?

数据挖掘 神经网络 喀拉斯 张量流
2021-10-02 13:06:58

我正在参加Kaggle 比赛,并尝试了 2 种不同的代码方法并遇到相同的问题:损失很大(18247478709991652.0000)并且没有下降或者是 nan。

我不确定代码或数据是否有问题。我尝试了缩放和非缩放数据并得到了相同的结果。我用完整的数据集(3,000 个示例)和一个简短的数据集进行了尝试。

这是缩写数据

import numpy
import pandas
from keras.models import Sequential
from keras.layers import Dense
from keras.wrappers.scikit_learn import KerasRegressor
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import KFold
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline

dataframe = pandas.read_csv('data/tmdb/train_processed.csv')
dataframe.drop('id', axis=1, inplace=True)

Y = dataframe['revenue'].values
dataframe.drop(columns=['revenue'], inplace=True)
X = dataframe.values

def baseline_model():
  model = Sequential()
  model.add(Dense(13, input_dim=3, kernel_initializer='normal', activation='relu'))
  model.add(Dense(1, kernel_initializer='normal'))
  model.compile(loss='mean_squared_error', optimizer='adam')
  return model

seed = 7
numpy.random.seed(seed)

estimators = []
estimators.append(('standardize', StandardScaler()))
estimators.append(('mlp', KerasRegressor(build_fn=baseline_model, epochs=100, batch_size=5, verbose=1)))
pipeline = Pipeline(estimators)
kfold = KFold(n_splits=10, random_state=seed)
results = cross_val_score(pipeline, X, Y, cv=kfold)
print("Result: %.2f (%.2f) MSE" % (results.mean(), results.std()))
1个回答

你的损失确实下降了,但并不显着。这是因为您的目标值非常大 ~10e7 并且默认学习率针对较小的值进行了缩放。解决这个问题的最简单方法是标准化 Y。

如果您的意图是代码缩放 Y,那么问题是 Pipeline 不会将 StandardScaler(或任何转换)应用于 Y。您必须使用 sklearn.compose.TransformedTargetRegressor,或将转换应用于 Pipeline 之外的 Y。

选择1:

管道外:
Y = dataframe['revenue'].values
Y = StandardScaler().fit_transform(dataframe['revenue'].values.reshape(-1,1))

管道内部:
estimators.append(('mlp', KerasRegressor(build_fn=baseline_model, epochs=100, batch_size=5, verbose=1)))
from sklearn.compose import TransformedTargetRegressor
estimators.append(('mlp',TransformedTargetRegressor(
regressor=KerasRegressor(build_fn=baseline_model,epochs=100,batch_size=5,verbose=1),
transformer=StandardScaler())))