SaveMyLife
SaveMyLife

Reputation: 85

Implemention of Neural Networks

I'm trying to understand how to implement neural networks. So I made my own dataset. Xtrain is numpy.random floats. Ytrain is sign(sin(1/x^3). Try to implement neural networks gave me very poor results. 30%accuracy. Random Forest with 100 trees give 97%. But I heard that NN can approximate any function. What is wrong in my understanding?

import numpy as np
import keras
import math
from sklearn.ensemble import RandomForestClassifier as RF
train = np.random.rand(100000)
test = np.random.rand(100000)
def g(x):
    if math.sin(2*3.14*x) > 0:
        if math.cos(2*3.14*x) > 0:
            return 0
        else:
            return 1 
    else:
        if math.cos(2*3.14*x) > 0:
            return 2
        else:
           return 3
def f(x):
    x = (1/x) ** 3
    res = [0, 0, 0, 0]
    res[g(x)] = 1
    return res

ytrain = np.array([f(x)  for x in train])
ytest = np.array([f(x) for x in test])
train = np.array([[x] for x in train])
test = np.array([[x] for x in test])

from keras.models import Sequential
from keras.layers import Dense, Activation, Embedding, LSTM

model = Sequential()
model.add(Dense(100, input_dim=1))
model.add(Activation('sigmoid'))
model.add(Dense(100))
model.add(Activation('sigmoid'))
model.add(Dense(100))
model.add(Activation('sigmoid'))
model.add(Dense(4))
model.add(Activation('softmax'))
model.compile(optimizer='sgd',
          loss='categorical_crossentropy',
          metrics=['accuracy'])

P.S. I tried out many layers, activation functions, loss functions, optimizers, but never got more than 30% accuracy :(

Upvotes: 1

Views: 182

Answers (2)

Ray
Ray

Reputation: 1993

Zhongyu Kuang's answer is correct in stating that you may need to train it longer or with a different learning rate.

I'll add that the deeper your network, the longer you'll need to train it before it converges. For a relatively simple function like sign(sin(1/x^3)), you may be able to get away with a smaller network than the one you're using.

Additionally, softmax probably isn't the best output layer. You just need to yield -1 or 1. A single tanh unit seems like it would do well. softmax is generally used when you want to learn a probability distribution over a finite set. (You'll probably want to switch your error function from cross entropy to mean square error for similar reasons.)

Try a network with one sigmoidal hidden layer and an output layer with just one tanh unit. Then play around with the layer size and learning rate. Maybe add a second hidden layer if you can't get results with just one, but I wouldn't be surprised if it's unnecessary.

Addendum: In this approach, you'll replace f(x) with a direct calculation of the target function instead of the one-hot vector you're using currently.

Upvotes: 0

Zhongyu Kuang
Zhongyu Kuang

Reputation: 5354

I suspect that the 30% accuracy is a combination of small learning rate setting and a small training-step setting.

I ran your code snippet with model.fit(train, ytrain, nb_epoch=5, batch_size=32), after 5 epoch's training it yields about 28% accuracy. With the same setting but increasing the training steps to nb_epoch=50, the loss drops to ~1.157 ish and the accuracy raises to 40%. Further increase training steps should lead the model to further converging. Other than that, you can also try to configure the model with a larger learning rate setting which could make the converging faster :

model.compile(loss='categorical_crossentropy', optimizer=SGD(lr=0.1, momentum=0.9, nesterov=True), metrics=['accuracy'])

Although be careful don't set the learning rate to be too large otherwise your loss could blow up.

EDIT: NN is known for having the potential for modeling extremely complex function, however, whether or not the model actually produce a good performance is a matter of how the model is designed, trained, and many other matters related to the specific application.

Upvotes: 2

Related Questions