繁体   English   中英

无法正确训练神经网络

[英]Unable to train neural network properly

我正在尝试训练通过Keras实现的神经网络(NN)来实现以下功能。

y(n)= y(n-1)* 0.9 + x(n)* 0.1

因此,我们的想法是将信号作为train_x数据并通过上述函数来获取train_y数据,从而为我们提供(train_x,train_y)训练数据。

import numpy as np
from keras.models import Sequential
from keras.layers.core import Activation, Dense
from keras.callbacks import EarlyStopping
import matplotlib.pyplot as plt

train_x = np.concatenate((np.ones(100)*120,np.ones(150)*150,np.ones(150)*90,np.ones(100)*110), axis=None)
train_y = np.ones(train_x.size)*train_x[0]

alpha = 0.9

for i in range(train_x.size):
    train_y[i] = train_y[i-1]*alpha + train_x[i]*(1 - alpha)

train_x数据与train_y数据图

问题y(n)下的函数是低通函数,并使x(n)值不会突然改变,如图中所示。

然后我制作一个NN并与它匹配(train_x,train_y)并绘制

model = Sequential()

model.add(Dense(128, kernel_initializer='normal', input_dim=1, activation='relu'))

model.add(Dense(256, kernel_initializer='normal', activation='relu'))
model.add(Dense(256, kernel_initializer='normal', activation='relu'))
model.add(Dense(256, kernel_initializer='normal', activation='relu'))

model.add(Dense(1, kernel_initializer='normal', activation='linear'))

model.compile(loss='mean_absolute_error',
                              optimizer='adam',
                              metrics=['accuracy'])

history = model.fit(train_x, train_y, epochs=200, verbose=0)

print(history.history['loss'][-1])
plt.plot(history.history['loss'])
plt.show()

loss_plot_200_epoch

最终损失值约为2.9,我认为这是非常好的。 但那时的准确性情节是这样的

accuracy_plot_200_epochs

因此,当我检查神经网络对数据的预测时,它就被训练了

plt.plot(model.predict(train_x))
plt.plot(train_x)
plt.show()

train_x_vs_predict_x

这些价值刚刚抵消了一点,这就是全部。 我尝试改变激活函数,神经元和层数,但结果仍然是相同的。 我究竟做错了什么?

----编辑----

使NN接受二维输入,并按预期工作

import numpy as np
from keras.models import Sequential
from keras.layers.core import Activation, Dense
from keras.callbacks import EarlyStopping
import matplotlib.pyplot as plt

train_x = np.concatenate((np.ones(100)*120,np.ones(150)*150,np.ones(150)*90,np.ones(100)*110), axis=None)
train_y = np.ones(train_x.size)*train_x[0]

alpha = 0.9

for i in range(train_x.size):
    train_y[i] = train_y[i-1]*alpha + train_x[i]*(1 - alpha)

train = np.empty((500,2))

for i in range(500):
    train[i][0]=train_x[i]
    train[i][1]=train_y[i]

model = Sequential()

model.add(Dense(128, kernel_initializer='normal', input_dim=2, activation='relu'))

model.add(Dense(256, kernel_initializer='normal', activation='relu'))
model.add(Dense(256, kernel_initializer='normal', activation='relu'))
model.add(Dense(256, kernel_initializer='normal', activation='relu'))

model.add(Dense(1, kernel_initializer='normal', activation='linear'))

model.compile(loss='mean_absolute_error',
                              optimizer='adam',
                              metrics=['accuracy'])

history = model.fit(train, train_y, epochs=100, verbose=0)

print(history.history['loss'][-1])
plt.plot(history.history['loss'])
plt.show()

如果我执行你的代码,我得到XY值的以下图:

X-Y值的图

如果我没有错过任何重要的东西,你真的把它喂给你的神经网络,你可能不会期望更好的结果。 原因是,神经网络只是一个只能为一个输入计算一个输出向量的函数。 在您的情况下,输出向量将只包含一个元素(您的y值),但正如您在上图中所见,对于x = 90,不只有一个单独的输出。 因此,您向神经网络提供的信息无法真正计算为函数,因此网络很可能会尝试计算点〜(90,145)和〜(150,150)之间的直线。 我的意思是,图中的“上面一行”。

您正在构建的神经网络是一个简单的多层感知器,具有一个输入节点和一个输出节点。 这意味着它本质上是一个函数,它接受一个实数并返回一个实数 - 上下文没有被传入,因此不能被考虑。 表达方式

model.predict(train_x)

不评估向量train_x的向量到向量函数,但为train_x每个数字计算数字到数字函数,然后返回结果列表。 这就是你在train_x_vs_predict_x图中获得平坦段的原因:相同的输入数字每次产生相同的输出数。

鉴于这种约束,近似实际上非常好。 例如,网络已经看到x值为150多个y值150和几个较低值但从未超过150.因此,给定x为150,它预测ay值略低于150。

另一方面,您想要的功能是指先前的功能值,并且在其输入中需要有关此功能的信息。 如果你想建立什么是接受实数的序列,并返回实数序列的功能,你可以这样做与许多一对多复发网络(以及你将需要更多训练数据比一个例子序列),但既然你可以直接计算函数,为什么还要用神经网络呢? 没有必要掏出黄油刀会做的电锯。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM