Fitting sine function with neural network and ReLU (Keras)

I am trying to approximate a sinusoidal function with a neural network (Keras).

Yes, I read the related posts :)

Using four hidden sigmoid neurons and a linearly activated output layer works fine.

But there are also settings that provide me with results that seem odd to me.

Since I just started working with what interests me, what and why is happening, but I could not figure out what until now.

# -*- 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()

      

This is the result for four hidden neurons (ReLU) and line-out activation. 4 hidden neurons (ReLU), output activation: linear

Why does the result take the form of ReLU?

Does it have anything to do with normalizing the output?

+3


source to share


1 answer


Two things here:



  • Your network is very small and small. The presence of only 4 neurons relu

    makes the case when a pair of these neurons is fully saturated. This is probably why the result of your network looks like this. Try he_normal

    or he_uniform

    as an initializer to overcome this.
  • In my opinion, your network is too small for this task. I would definitely increase the depth and width of your network by firing more neurons and layers into the network. In a case sigmoid

    that has a similar function form sin

    , this might work fine, but in a case relu

    you really need a larger network.
+5


source







All Articles