使用神经网络和 ReLU 逼近正弦函数

Posted

技术标签:

【中文标题】使用神经网络和 ReLU 逼近正弦函数【英文标题】:Approximating sine function with Neural Network and ReLU 【发布时间】:2017-11-26 17:42:04 【问题描述】:

我正在尝试使用神经网络 (Keras) 逼近正弦函数。

是的,我阅读了相关的帖子:)

Link 1

Link 2

Link 3

使用四个带有 sigmoid 的隐藏神经元和一个带有线性激活的输出层效果很好。

但也有一些设置提供的结果让我觉得很奇怪。

由于我刚开始与我一起工作,所以我对事情发生的原因和原因很感兴趣,但到目前为止我无法弄清楚。

# -*- coding: utf-8 -*-

import numpy as np
np.random.seed(7)

from keras.models import Sequential
from keras.layers import Dense
import pylab as pl
from sklearn.preprocessing import MinMaxScaler

X = np.linspace(0.0 , 2.0 * np.pi, 10000).reshape(-1, 1)
Y = np.sin(X)

x_scaler = MinMaxScaler()
#y_scaler = MinMaxScaler(feature_range=(-1.0, 1.0))
y_scaler = MinMaxScaler()

X = x_scaler.fit_transform(X)
Y = y_scaler.fit_transform(Y)

model = Sequential()
model.add(Dense(4, input_dim=X.shape[1], kernel_initializer='uniform', activation='relu'))
# model.add(Dense(4, input_dim=X.shape[1], kernel_initializer='uniform', activation='sigmoid'))
# model.add(Dense(4, input_dim=X.shape[1], kernel_initializer='uniform', activation='tanh'))
model.add(Dense(1, kernel_initializer='uniform', activation='linear'))

model.compile(loss='mse', optimizer='adam', metrics=['mae'])

model.fit(X, Y, epochs=500, batch_size=32, verbose=2)

res = model.predict(X, batch_size=32)

res_rscl = y_scaler.inverse_transform(res)

Y_rscl = y_scaler.inverse_transform(Y)

pl.subplot(211)
pl.plot(res_rscl, label='ann')
pl.plot(Y_rscl, label='train')
pl.xlabel('#')
pl.ylabel('value [arb.]')
pl.legend()
pl.subplot(212)
pl.plot(Y_rscl - res_rscl, label='diff')
pl.legend()
pl.show()

这是四个隐藏神经元 (ReLU) 和线性输出激活的结果。

为什么结果会采用 ReLU 的形式?

这与输出规范化有关吗?

【问题讨论】:

【参考方案1】:

这里有两件事:

    您的网络真的很浅而且很小。只有 4 个具有 relu 的神经元使得其中几个神经元完全饱和的情况非常有可能。这可能就是您的网络结果看起来像这样的原因。尝试将 he_normalhe_uniform 作为初始化程序来克服这个问题。 在我看来,您的网络对于这项任务来说太小了。我肯定会通过在你的网络中引入更多的神经元和层来增加你的网络的深度和宽度。如果sigmoid 的形状与sin 函数相似,这可能会正常工作 - 但如果是relu,您确实需要更大的网络。

【讨论】:

是的,只要给上面的代码 40 个 ReLu HU 就更合适了:imgur.com/a/yhTqw【参考方案2】:

尝试添加更多隐藏层,每个隐藏层都有更多隐藏单元。我使用了这段代码:

model = Sequential()
model.add(Dense(50, input_dim=X.shape[1], activation='relu'))
model.add(Dense(50, input_dim=X.shape[1], activation='relu'))
model.add(Dense(1, activation='linear'))

得到了这些结果:

【讨论】:

以上是关于使用神经网络和 ReLU 逼近正弦函数的主要内容,如果未能解决你的问题,请参考以下文章

神经网络中的激活函数具体是什么?为什么Relu要好过与tanh和sigmoid function

BN--批规则化

激活函数

神经网络权重以线性单位爆炸

R中的“神经网络”包,整流线性单元(ReLU)激活函数?

Activation Functions:激活函数