【问题标题】:Keras - Neural Network learns correctly trend of the data, but not amplitudeKeras - 神经网络正确地学习数据的趋势,但不是幅度
【发布时间】:2019-11-27 00:59:32
【问题描述】:

我在 Keras 中构建了一个神经网络来学习 4 个坐标 x,y,z,d(带有 d=sqrt(x**2+y**2+z**2))和一个标量值之间的映射。我的训练集由 x,y,z,d 的 1500 个值组成,与标量函数的 1500 个值相关联。我的测试集有 500 个样本。

我的神经网络产生正确的数据“趋势”,但幅度不正确。下面的图表应该清楚地说明什么意思。它们显示了训练和测试集的标量函数的值;在每个图中,显示了原始样本和 NN 预测。我想询问有关如何让 NN 也正确学习幅度的指示,避免图中清晰可见的“插值”效应。

from __future__ import division
from tensorflow.keras.layers import Input, Dense
from tensorflow.keras.models import Model
from tensorflow.keras import optimizers


input_sig = Input(batch_shape=(None,4))
output = Dense(1)(input_sig)

NN = Model(input_sig, output)
nadam = optimizers.Nadam()
NN.compile(optimizer=nadam, loss='logcosh', metrics=['accuracy'])
history = NN.fit(x = x_train, y = y_train,
                    epochs=1000,
                    batch_size=100,
                    validation_split=0.2)

prediction_training = np.squeeze(NN.predict(x_train))
prediction_testing = np.squeeze(NN.predict(x_test))
plt.plot(y_train, color='blue', label='Original training')
plt.plot(prediction_training, color='red', label='Prediction training')
plt.legend(fontsize='x-large')
plt.show()
plt.close()

plt.plot(y_test, color='blue', label='Original testing')
plt.plot(prediction_testing, color='red', label='Prediction testing')
plt.legend(fontsize='x-large')
plt.show()
plt.close()

训练集图

测试集图

【问题讨论】:

  • 我不清楚您是如何生成 x_trainy_train 的。如果样本之间没有依赖关系,我认为您的数据中没有“趋势”。
  • 你凭什么说它学会了“趋势”?我不清楚它是否至少来自图像。比如,你怎么知道模型是不是在区间之间随机波动?
  • @thushv89 我说它已经正确地了解了趋势,因为如果你放大图,你可以看到红线“跟随”蓝线的运动。但是,NN 无法在信号中产生尖峰,更一般地说,无法产生与原始信号一样高的信号
  • @HanWang 我明白你的意思。但是,我不觉得它已经学会了(这是我的观点)。我觉得数据太不稳定,无法从中学习。您可以使用一些数据规范化来使线条更平滑吗?那么你可能有更好的学习机会。

标签: python tensorflow machine-learning keras neural-network


【解决方案1】:

我想你想建立一个前馈神经网络来学习函数

d=sqrt(x**2+y**2+z**2)

因此,正如函数所述,输入应该是一个 3D 向量 [x, y, z],输出应该是一个标量值 d。这些是你的 x_trainy_train

Keras 中的非线性Dense 层应该能够学习它(注意:您需要指定非线性激活函数,如Dense(..., activation='sigmoid'))。否则Dense层将是线性的,只进行线性变换,可能无法很好地学习非线性函数。

需要注意的另一件事是大多数激活函数的取值范围有限。例如sigmoid 的范围在(0,1) 中,这意味着即使乘以权重w,它仍然无法将d 与任意[x, y, z] 匹配。或者,学习具有特定范围值的[x, y, z] 是个好主意。

【讨论】:

  • 函数d=sqrt(x**2+y**2+z**2)不用学。我的x_train 由一组坐标x,y,z 组成,我可以在其中添加d=sqrt(x**2+y**2+z**2),这样我就有了四个坐标。我的y_train 是一个标量值(不是d),它表示与坐标相关的一些物理量
  • @johnhenry 然后d 似乎是一个冗余输入,因为它显然依赖于x,y,z。所以基本上你的任务是用给定x,y,z的神经网络生成一些物理量?
  • 是的,这是正确的。 d 似乎是多余的,我同意,但由于距离d 要学习的物理量有一些依赖性,我认为将其显式输入网络可能会有所帮助
猜你喜欢
  • 2018-10-05
  • 1970-01-01
  • 2015-10-17
  • 2017-02-28
  • 2016-07-11
  • 1970-01-01
  • 2020-05-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多