Neural network accuracy optimization
<p>I have constructed an ANN in keras which has 1 input layer(3 inputs), one output layer (1 output) and two hidden layers with with 12 and 3 nodes respectively.</p>

<p><a href="http://i.stack.imgur.com/PkYfu.png" rel="nofollow"><img src="http://i.stack.imgur.com/PkYfu.png" alt="enter image description here"></a></p>

<p>The way i construct and train my network is:</p>

<pre><code>from keras.models import Sequential
from keras.layers import Dense
from sklearn.cross_validation import train_test_split
import numpy
# fix random seed for reproducibility
seed = 7
numpy.random.seed(seed)

dataset = numpy.loadtxt("sorted output.csv", delimiter=",")
# split into input (X) and output (Y) variables
X = dataset[:,0:3]
Y = dataset[:,3]
# split into 67% for train and 33% for test
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.33, random_state=seed)
# create model
model = Sequential()
model.add(Dense(12, input_dim=3, init='uniform', activation='relu'))
model.add(Dense(3, init='uniform', activation='relu'))
model.add(Dense(1, init='uniform', activation='sigmoid'))
# Compile model
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
# Fit the model
model.fit(X_train, y_train, validation_data=(X_test,y_test), nb_epoch=150, batch_size=10)
</code></pre>

<p>Sorted output csv file looks like:</p>

<p><a href="http://i.stack.imgur.com/CIKn3.png" rel="nofollow"><img src="http://i.stack.imgur.com/CIKn3.png" alt="enter image description here"></a></p>

<p>so after 150 epochs i get: <strong>loss: 0.6932 - acc: 0.5000 - val_loss: 0.6970 - val_acc: 0.1429</strong></p>

<p>My question is: how could i modify my NN in order to achieve higher accuracy?</p>

<p>You could try the following things. I have written this roughly in the order of importance - i.e. the order I would try things to fix the accuracy problem you are seeing:</p>

<ol>
<li><p>Normalise your input data. Usually you would take mean and standard deviation of training data, and use them to offset+scale all further inputs. There is a <a href="http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.StandardScaler.html" rel="nofollow">standard normalising function in sklearn</a> for this. Remember to treat your test data in the same way (using the mean and std from the training data, not recalculating it)</p></li>
<li><p>Train for more epochs. For problems with small numbers of features and limited training set sizes, you often have to run for thousands of epochs before the network will converge. You should plot the training and validation loss values to see whether the network is still learning, or has converged as best as it can.</p></li>
<li><p>For your simple data, I would avoid relu activations. You may have heard they are somehow "best", but like most NN options, they have types of problems where they work well, and others where they are not best choice. I think you would be better off with tanh or sigmoid activations in hidden layers for your problem. Save relu for very deep networks and/or convolutional problems on images/audio.</p></li>
<li><p>Use more training data. Not clear how much you are feeding it, but NNs work best with large amounts of training data.</p></li>
<li><p>Provided you already have lots of training data - increase size of hidden layers. More complex relationships require more hidden neurons (and sometimes more layers) for the NN to be able to express the "shape" of the decision surface. <a href="http://cs.stanford.edu/people/karpathy/convnetjs/demo/classify2d.html" rel="nofollow">Here is a handy browser-based network allowing you to play with that idea and get a feel for it</a>. </p></li>
<li><p>Add one or more <a href="https://keras.io/layers/core/#dropout" rel="nofollow">dropout layers</a> after the hidden layers or add some other regularisation. The network could be over-fitting (although with a training accuracy of 0.5 I suspect it isn't). Unlike relu, using dropout is pretty close to a panacea for tougher NN problems - it improves generalisation in many cases. A small amount of dropout (~0.2) might help with your problem, but like most hyper-parameters, you will need to search for the best values.</p></li>
</ol>

<p>Finally, it is always possible that the relationship you want to find that allows you to predict Y from X is not really there. In which case it would be a correct result from the NN to be no better than guessing at Y.</p>

python neural-network theano keras