I'm attempting to train a classifier on a single input vector of length 3000, and trying to predict which of 30 classes each input vector belongs to.
With 1M labeled input/output examples (split 80% training, 20% validate), I can get about 50% accuracy by simply training weights on a 3000 by 30 matrix. In other words, 50% accuracy with no hidden layer.
When I add a hidden layer with 100 neurons, or 500, or 50, I am consistently seeing worse performance than in my network with no hidden layers. I expect this is somehow a function of my hyperparameters, but I have tried tweaking the learning rate and batch size across a wide range of values. I've also tried sigmoid, tanh, and relu outputs on the hidden layer.
No matter what I try, I'm not seeing better than 20% accuracy when I add a hidden layer.
Happy to provide more detail as needed, but basically I'm looking for advice about how to debug (I'm using this as an excuse to explore Tensorflow.) I'd expect that my network with a hidden layer should at least as well as without.
Example code
Here is how I'm training the model (note that I've also tried sigmoid
and tanh
units, and adding a regularization term to my cost). The next_batch
function creates a batch by randomly choosing a set of input/output pairs from a pool of about a million lableed examples. If I cut the hidden layer out altogether, it learns just fine.
HIDDEN_COUNT = 50
x = tf.placeholder("float", [None, FEATURE_COUNT])
Wh = init_weights((FEATURE_COUNT, HIDDEN_COUNT))
bh = tf.Variable(tf.zeros([HIDDEN_COUNT]))
h = tf.nn.relu(tf.matmul(x, Wh) + bh)
b = tf.Variable(tf.zeros([CATEGORY_COUNT]))
W = init_weights((HIDDEN_COUNT, CATEGORY_COUNT))
y = tf.nn.softmax(tf.matmul(h,W) + b)
y_ = tf.placeholder("float", [None,CATEGORY_COUNT])
cross_entropy = -tf.reduce_sum(y_*tf.log(y))
train_step = tf.train.GradientDescentOptimizer(.0001).minimize( cross_entropy )
# Test trained model
correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
accuracy = tf.reduce_sum(tf.cast(correct_prediction, "float"))
And then, inside a loop...
batch_xs, batch_ys = next_batch('train', batch_size)
train_step.run({x: batch_xs, y_: batch_ys})
Example output
Training on 500k examples, batched into 50-sample batches, with a test evaluation after every 200 batches:
accuracy: 0.031 cost: 71674 after 0 examples
accuracy: 0.187 cost: 70403 after 10000 examples
accuracy: 0.186 cost: 69147 after 20000 examples
accuracy: 0.187 cost: 68044 after 30000 examples
accuracy: 0.189 cost: 66978 after 40000 examples
accuracy: 0.192 cost: 65939 after 50000 examples
accuracy: 0.185 cost: 65112 after 60000 examples
accuracy: 0.187 cost: 64278 after 70000 examples
accuracy: 0.182 cost: 63690 after 80000 examples
accuracy: 0.185 cost: 62865 after 90000 examples
accuracy: 0.191 cost: 62023 after 100000 examples
accuracy: 0.186 cost: 61644 after 110000 examples
accuracy: 0.187 cost: 61155 after 120000 examples
accuracy: 0.189 cost: 60647 after 130000 examples
accuracy: 0.188 cost: 60209 after 140000 examples
accuracy: 0.187 cost: 59964 after 150000 examples
accuracy: 0.184 cost: 59496 after 160000 examples
accuracy: 0.186 cost: 59261 after 170000 examples
accuracy: 0.185 cost: 59127 after 180000 examples
accuracy: 0.186 cost: 58839 after 190000 examples
accuracy: 0.187 cost: 58884 after 200000 examples
accuracy: 0.184 cost: 58723 after 210000 examples
accuracy: 0.184 cost: 58493 after 220000 examples
accuracy: 0.189 cost: 58221 after 230000 examples
accuracy: 0.187 cost: 58176 after 240000 examples
accuracy: 0.189 cost: 58092 after 250000 examples
accuracy: 0.183 cost: 58057 after 260000 examples
accuracy: 0.184 cost: 58040 after 270000 examples
accuracy: 0.181 cost: 58369 after 280000 examples
accuracy: 0.189 cost: 57762 after 290000 examples
accuracy: 0.182 cost: 58186 after 300000 examples
accuracy: 0.189 cost: 57703 after 310000 examples
accuracy: 0.188 cost: 57521 after 320000 examples
accuracy: 0.185 cost: 57804 after 330000 examples
accuracy: 0.184 cost: 57883 after 340000 examples
accuracy: 0.184 cost: 57756 after 350000 examples
accuracy: 0.186 cost: 57505 after 360000 examples
accuracy: 0.185 cost: 57569 after 370000 examples
accuracy: 0.186 cost: 57562 after 380000 examples
accuracy: 0.204 cost: 57406 after 390000 examples
accuracy: 0.211 cost: 57432 after 400000 examples
accuracy: 0.185 cost: 57576 after 410000 examples
accuracy: 0.182 cost: 57774 after 420000 examples
accuracy: 0.183 cost: 57520 after 430000 examples
accuracy: 0.184 cost: 57421 after 440000 examples
accuracy: 0.186 cost: 57374 after 450000 examples
accuracy: 0.183 cost: 57552 after 460000 examples
accuracy: 0.186 cost: 57435 after 470000 examples
accuracy: 0.181 cost: 57210 after 480000 examples
accuracy: 0.182 cost: 57493 after 490000 examples
Note that attempting to lower the learning rate and resume after these 500k training samples produced no improvement in accuracy or cost.
init_weights
? A rule of thumb is thattf.truncated_normal([FEATURE_COUNT, HIDDEN_COUNT], stddev=1./FEATURE_COUNT)
is a good initial value forWh
. $\endgroup$