【问题标题】:non-linear neural network regression - quadratic function is not being estimated correctly非线性神经网络回归 - 二次函数没有被正确估计
【发布时间】:2018-12-29 22:07:56
【问题描述】:

我主要使用 ANN 进行分类,最近才开始尝试使用它们来建模连续变量。作为练习,我生成了一组简单的 (x, y) 对,其中 y = x^2 并尝试训练 ANN 来学习这个二次函数。

人工神经网络模型:

这个 ANN 有 1 个输入节点(即 x)、2 个隐藏层,每层有 2 个节点,以及 1 个输出节点。所有四个隐藏节点都使用非线性tanh激活函数,输出节点没有激活函数(因为它是回归)。

数据:

对于训练集,我为 x 随机生成了 100 个介于 (-20, 20) 之间的数字,并计算出 y=x^2。对于测试集,我为 x 随机生成了 100 个介于 (-30, 30) 之间的数字,并且还计算了 y=x^2。然后我对所有 x 进行了转换,使它们以 0 为中心,它们的最小值和最大值大约在 -1.5 和 1.5 左右。我也对所有 y 进行了类似的变换,但使它们的最小值和最大值约为 -0.9 和 0.9。这样一来,所有数据都在 tanh 激活函数的中间范围内,而不是在极端情况下。

问题:

在 Keras 中训练 ANN 后,我看到只学习了多项式函数的右半部分,而左半部分完全平坦。有谁知道为什么会发生这种情况?我尝试使用不同的缩放选项以及隐藏层规范,但左侧没有运气。

谢谢!

附件是我用于所有内容的代码,图像显示了缩放训练 x 与预测 y 的图。如您所见,只恢复了一半的抛物线。

import numpy as np, pandas as pd
from keras.models import Sequential
from keras.layers import Dense
from keras.wrappers.scikit_learn import KerasRegressor
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
import matplotlib.pyplot as plt

seed = 10
n = 100
X_train = np.random.uniform(-20, 20, n)
Y_train = X_train ** 2
X_test = np.random.uniform(-30, 30, n)
Y_test = X_test ** 2

#### Scale the data

x_cap = max(abs(np.array(list(X_train) + list(X_test))))
y_cap = max(abs(np.array(list(Y_train) + list(Y_test))))
x_mean = np.mean(np.array(list(X_train) + list(X_test)))
y_mean = np.mean(np.array(list(Y_train) + list(Y_test)))

X_train2 = (X_train-x_mean) / x_cap
X_test2 = (X_test-x_mean) / x_cap
Y_train2 = (Y_train-y_mean) / y_cap
Y_test2 = (Y_test-y_mean) / y_cap

X_train2 = X_train2 * (1.5 / max(X_train2))
Y_train2 = Y_train2 * (0.9 / max(Y_train2))

# define base model
def baseline_model1():
# create model
model1 = Sequential()
model1.add(Dense(2, input_dim=1, kernel_initializer='normal', activation='tanh'))
model1.add(Dense(2, input_dim=1, kernel_initializer='normal', activation='tanh'))
model1.add(Dense(1, kernel_initializer='normal'))
# Compile model
model1.compile(loss='mean_squared_error', optimizer='adam')
return model1

np.random.seed(seed)
estimator1 = KerasRegressor(build_fn=baseline_model1, epochs=100, batch_size=5, verbose=0)

estimator1.fit(X_train2, Y_train2)
prediction = estimator1.predict(X_train2)
plt.scatter(X_train2, prediction)

enter image description here

【问题讨论】:

    标签: neural-network keras non-linear-regression nonlinear-functions


    【解决方案1】:

    您的网络对初始参数非常敏感。以下将有所帮助:

    • 将您的 kernel_initializer 更改为 glorot_uniform。您的网络非常小,glorot_uniform 将与 tanh 激活配合得更好。 Glorot uniform 会鼓励你的权重最初在一个更合理的范围内(因为它考虑到了每一层的扇入和扇出)。

    • 训练您的模型以获得更多时期(即 1000 个)。

    【讨论】:

      【解决方案2】:

      您还应该考虑为隐藏层添加更多宽度。我从 2 变成了 5 并且非常合身。我还按照 rvinas 的建议使用了更多的时代

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-30
        • 1970-01-01
        • 2017-04-01
        • 2020-05-18
        • 2019-01-27
        • 2010-10-24
        相关资源
        最近更新 更多