首页 > 解决方案 > 什么是最小的 Keras 回归神经网络模型,可以完美拟合汽车数据?

问题描述

我正在寻找 这个汽车数据集。我使用这段代码构建和训练回归模型,改编自这篇文章这篇文章。我正在使用所有的训练数据(没有训练/测试拆分):

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import KFold
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import MinMaxScaler
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.wrappers.scikit_learn import KerasRegressor
dataset=np.loadtxt("cars.csv", delimiter=",", skiprows=1)
x=dataset[:,0:5]
y=dataset[:,5]
y=np.reshape(y, (-1,1))
scaler_x = MinMaxScaler()
scaler_y = MinMaxScaler()
print(scaler_x.fit(x))
xscale=scaler_x.transform(x)
print(scaler_y.fit(y))
yscale=scaler_y.transform(y)
model = Sequential([
    Dense(2048, activation='relu', input_dim=5),
    Dense(1024, activation='relu'),
    Dense(512, activation='relu'),
    Dense(1)
  ])
model.compile(loss='mse', optimizer='adam', metrics=['mse','mae'])
history = model.fit(xscale, yscale, epochs=1000, batch_size=577,  verbose=1, validation_split=0)
Xnew= scaler_x.transform(Xnew)
ynew= model.predict(Xnew)
ynew = scaler_y.inverse_transform(ynew) 
Znew = scaler_y.inverse_transform(y_train)
plt.figure(figsize=(15,8))
plt.scatter(Znew,ynew);

在 1000 个 epoch 之后,此模型将紧密但不完全适合输入训练数据:

在此处输入图像描述

该模型有 2,635,777 个可训练参数(数据本身只有 5,778 个数字)。

什么是最小的 Keras 回归模型(就可训练参数的总数而言),它可以训练到几乎完美地拟合该数据(具有 5 个输入参数、1 个输出参数和 963 个样本)?

标签: tensorflowkerasregression

解决方案


Michael Grogan 在这里 - 我是这个数据和示例的原始作者,所以希望我能帮助你。

您提到您尚未在数据中调用验证拆分。请问这有什么原因吗?分为训练和验证的目的是让模型从验证参数中获取反馈,然后相应地更新预测。

自从我查看此示例以来已经有一段时间了,但这里是训练/验证拆分的示例,训练和验证损失似乎在 20 个 epoch 后触底 - 所以 1000 并不是严格要求的。我写的原始教程在示例中使用了 150 个 epoch。

x 和 y 拆分如下:

x_train, x_val, y_train, y_val = train_test_split(xscale, yscale, random_state=0)

然后我使用您的配置运行模型:

model = Sequential([
    Dense(2048, activation='relu', input_dim=5),
    Dense(1024, activation='relu'),
    Dense(512, activation='relu'),
    Dense(1)
  ])
model.compile(loss='mse', optimizer='adam', metrics=['mse','mae'])
history = model.fit(x_train, y_train, epochs=20, batch_size=577,  verbose=1, validation_data=(x_val, y_val))

这是训练和验证损失图:

图形

什么是最小的 Keras 回归模型(就可训练参数的总数而言),它可以训练到几乎完美地拟合该数据(具有 5 个输入参数、1 个输出参数和 963 个样本)?

当您说“最小的 Keras 回归模型”时,您似乎指的是使用最少数量的特征来实现相同(或更好的准确性)的模型。可以确定的一种方法是使用诸如ExtraTreesClassifier之类的特征选择工具,其中每个特征都根据其重要性进行排名(数字越高,越重要)。

鉴于年龄、性别、里程、债务和收入等特征,结果如下:

In:

from sklearn.ensemble import ExtraTreesClassifier
model = ExtraTreesClassifier()
model.fit(x, y)
print(model.feature_importances_)

Out: [0.23371284 0.01554055 0.23787049 0.25267784 0.26019827]

除性别外,其他特征在重要性方面排名相似。

在这方面,让我们再次运行模型,但这次没有性别变量。

这是模型(唯一的变化是 input_dim = 4),这是新的训练和验证损失:

model = Sequential([
    Dense(2048, activation='relu', input_dim=4),
    Dense(1024, activation='relu'),
    Dense(512, activation='relu'),
    Dense(1)
  ])
model.compile(loss='mse', optimizer='adam', metrics=['mse','mae'])
history = model.fit(x_train, y_train, epochs=20, batch_size=577,  verbose=1, validation_data=(x_val, y_val))

图2

您的示例中的隐藏层看起来非常大,因此让我们尝试将其简化一下:

model = Sequential([
    Dense(12, activation='relu', input_dim=4),
    Dense(8, activation='relu'),
    Dense(1, activation='linear')
  ])
model.compile(loss='mse', optimizer='adam', metrics=['mse','mae'])
history = model.fit(x_train, y_train, epochs=20, batch_size=577,  verbose=1, validation_data=(x_val, y_val))

现在当模型再次训练时,这里是新的训练和验证损失:

图3

我们现在看到,获得类似的训练和验证损失大约需要 50 个 epoch 而不是 20 个。在这方面,隐藏层的大小和用于训练模型的 epoch 数之间似乎存在权衡。

一般来说,该模型需要 4 个输入参数和不到 1000 个 epoch 才能生成良好的拟合。

一个警告 - 关于数据是否“完美”拟合的真正测试是针对看不见的数据测试预测。例如,我们使用训练和验证数据来构建模型。这些数据的一部分应该完全分开,然后与模型预测进行比较以确保准确性——这是关于模型是否真正工作的试金石——我建议将其作为下一步以确保您的模型是健壮的。

希望以上有所帮助。


推荐阅读