我正在尝试使用Keras和TensorFlow构建一个简单的回归模型。在我的问题中,数据形式为(x, y)
,其中x
和y
只是数字。我希望构建一个Keras模型,以便使用x
作为输入来预测y
。
我认为图像能更好地解释事情,这些是我的数据:
我们可以讨论它们是否好,但在我问题中,我真的无法欺骗它们。
我的Keras模型如下(数据被分为30%的测试集(X_test, y_test)
和70%的训练集(X_train, y_train)
):
model = tf.keras.Sequential()model.add(tf.keras.layers.Dense(32, input_shape=() activation="relu", name="first_layer"))model.add(tf.keras.layers.Dense(16, activation="relu", name="second_layer"))model.add(tf.keras.layers.Dense(1, name="output_layer"))model.compile(loss = "mean_squared_error", optimizer = "adam", metrics=["mse"] )history = model.fit(X_train, y_train, epochs=500, batch_size=1, verbose=0, shuffle=False) eval_result = model.evaluate(X_test, y_test)print("\n\nTest loss:", eval_result, "\n")predict_Y = model.predict(X)
注意:X
包含X_test
和X_train
。
绘制预测结果如下(蓝色方块是预测结果predict_Y
)
我一直在尝试调整层、激活函数和其他参数。我的目标是找到训练模型的最佳参数,但这里的实际问题略有不同:事实上,我很难强迫模型过拟合数据(如上图所示)。
有没有人对如何重现过拟合有任何想法?
(红色点在蓝色方块下方!)
编辑:
我在这里提供了上例中使用的数据:你可以直接复制粘贴到Python解释器中:
X_train = [0.704619794270697, 0.6779457393024553, 0.8207082120250023, 0.8588819357831449, 0.8692320257603844, 0.6878750931810429, 0.9556331888763945, 0.77677964510883, 0.7211381534179618, 0.6438319113259414, 0.6478339581502052, 0.9710222750072649, 0.8952188423349681, 0.6303124926673513, 0.9640316662124185, 0.869691568491902, 0.8320164648420931, 0.8236399177660375, 0.8877334038470911, 0.8084042532069621, 0.8045680821762038]y_train = [0.7766424210611557, 0.8210846773655833, 0.9996114311913593, 0.8041331063189883, 0.9980525368790883, 0.8164056182686034, 0.8925487603333683, 0.7758207470960685, 0.37345286573743475, 0.9325789202459493, 0.6060269037514895, 0.9319771743389491, 0.9990691225991941, 0.9320002808310418, 0.9992560731072977, 0.9980241561997089, 0.8882905258641204, 0.4678339275898943, 0.9312152374846061, 0.9542371205095945, 0.8885893668675711]X_test = [0.9749191829308574, 0.8735366740730178, 0.8882783211709133, 0.8022891400991644, 0.8650601322313454, 0.8697902997857514, 1.0, 0.8165876695985228, 0.8923841531760973]y_test = [0.975653685270635, 0.9096752789481569, 0.6653736469114154, 0.46367666660348744, 0.9991817903431941, 1.0, 0.9111205717076893, 0.5264993912088891, 0.9989199241685126]X = [0.704619794270697, 0.77677964510883, 0.7211381534179618, 0.6478339581502052, 0.6779457393024553, 0.8588819357831449, 0.8045680821762038, 0.8320164648420931, 0.8650601322313454, 0.8697902997857514, 0.8236399177660375, 0.6878750931810429, 0.8923841531760973, 0.8692320257603844, 0.8877334038470911, 0.8735366740730178, 0.8207082120250023, 0.8022891400991644, 0.6303124926673513, 0.8084042532069621, 0.869691568491902, 0.9710222750072649, 0.9556331888763945, 0.8882783211709133, 0.8165876695985228, 0.6438319113259414, 0.8952188423349681, 0.9749191829308574, 1.0, 0.9640316662124185]Y = [0.7766424210611557, 0.7758207470960685, 0.37345286573743475, 0.6060269037514895, 0.8210846773655833, 0.8041331063189883, 0.8885893668675711, 0.8882905258641204, 0.9991817903431941, 1.0, 0.4678339275898943, 0.8164056182686034, 0.9989199241685126, 0.9980525368790883, 0.9312152374846061, 0.9096752789481569, 0.9996114311913593, 0.46367666660348744, 0.9320002808310418, 0.9542371205095945, 0.9980241561997089, 0.9319771743389491, 0.8925487603333683, 0.6653736469114154, 0.5264993912088891, 0.9325789202459493, 0.9990691225991941, 0.975653685270635, 0.9111205717076893, 0.9992560731072977]
其中X
包含x值的列表,Y
包含相应的y值。(X_test, y_test)和(X_train, y_train)是(X, Y)的两个(不重叠的)子集。
为了预测和展示模型结果,我只是使用了matplotlib(导入为plt):
predict_Y = model.predict(X)plt.plot(X, Y, "ro", X, predict_Y, "bs")plt.show()
回答:
过拟合模型在现实生活中很少有用。我认为原帖者对此非常清楚,但他想看看神经网络是否确实能够拟合(有界的)任意函数。一方面,示例中的输入输出数据似乎没有任何可辨识的模式。另一方面,输入和输出都是在[0, 1]范围内的标量,训练集只有21个数据点。
根据我的实验和结果,我们确实可以按要求进行过拟合。见下图。
数值结果:
x y_true y_pred error0 0.704620 0.776642 0.773753 -0.0028891 0.677946 0.821085 0.819597 -0.0014882 0.820708 0.999611 0.999813 0.0002023 0.858882 0.804133 0.805160 0.0010264 0.869232 0.998053 0.997862 -0.0001905 0.687875 0.816406 0.814692 -0.0017146 0.955633 0.892549 0.893117 0.0005697 0.776780 0.775821 0.779289 0.0034698 0.721138 0.373453 0.374007 0.0005549 0.643832 0.932579 0.912565 -0.02001410 0.647834 0.606027 0.607253 0.00122611 0.971022 0.931977 0.931549 -0.00042812 0.895219 0.999069 0.999051 -0.00001813 0.630312 0.932000 0.930252 -0.00174814 0.964032 0.999256 0.999204 -0.00005215 0.869692 0.998024 0.997859 -0.00016516 0.832016 0.888291 0.887883 -0.00040717 0.823640 0.467834 0.460728 -0.00710618 0.887733 0.931215 0.932790 0.00157519 0.808404 0.954237 0.960282 0.00604520 0.804568 0.888589 0.906829 0.018240{'me': -0.00015776709314323828, 'mae': 0.00329163070145315, 'mse': 4.0713782563067185e-05, 'rmse': 0.006380735268216915}
我认为原帖者的代码看起来很好。我的改动很小:
- 使用更深的网络。实际上可能不需要使用30层的深度,但由于我们只是想过拟合,我没有过多实验最小的深度需求。
- 每个Dense层有50个单元。这可能有点过头了。
- 每5个Dense层添加一个批量归一化层。
- 将学习率减半。
- 使用所有21个训练样本作为一个批次,运行更长时间的优化。
- 使用MAE作为目标函数。MSE很好,但由于我们想过拟合,我希望以相同的方式惩罚小错误和大错误。
- 随机数在这里更为重要,因为数据看起来是任意的。不过,如果你更改随机数种子并让优化器运行足够长的时间,你应该会得到类似的结果。在某些情况下,优化确实会卡在一个局部最小值,并且不会产生过拟合(如原帖者所要求的)。
代码如下。
...(此处省略代码部分,保持原样)...