Ich bin ein bisschen stecken, versucht, ein ziemlich Standard-MLP-Modell mit Theano zu trainieren. Mein Modell-Code sieht wie folgt ausTraining MLP in Theano
class Layer(object): def __init__(self, inputs, n_in, n_out, activation=T.nnet.softmax): def weights(shape): return np.array(np.random.uniform(size=shape), dtype='float64') def biases(size): return np.zeros((size), dtype='float64') self.W = theano.shared(value=weights((n_in, n_out)), name='weights', borrow=True) self.b = theano.shared(value=biases(n_out), name='biases', borrow=True) self.output = activation(T.dot(inputs, self.W) + self.b) self.pred = T.argmax(self.output, axis=1) self.params = [self.W, self.b] class MLP(object): def __init__(self, inputs, n_in, n_hidden, n_out): """ for now lets go with one hidden layer""" self._hidden = Layer(inputs, n_in, n_hidden, activation=T.tanh) self._output = Layer(self._hidden.output, n_hidden, n_out) # softmax by default def loss(self, one_hot): return T.mean(T.sqr(one_hot - self._output.output) def accuracy(self, y): return T.mean(T.eq(self._output.pred, y)) def updates(self, loss, rate=0.01): updates = [] updates.append((self._hidden.W, self._hidden.W - rate * T.grad(cost=loss, wrt=self._hidden.W))) updates.append((self._hidden.b, self._hidden.b - rate * T.grad(cost=loss, wrt=self._hidden.b))) updates.append((self._output.W, self._output.W - rate * T.grad(cost=loss, wrt=self._output.W))) updates.append((self._output.b, self._output.b - rate * T.grad(cost=loss, wrt=self._output.b))) return updates
Dann versuche ich es wie diese
x = T.matrix('x', dtype='float64') y = T.vector('y', dtype='int32') # basic logistic model # model = Layer(x, 784, 10, activation=T.nnet.softmax) # basic multi-layer perceptron model = MLP(x, 784, 128, 10) labels = T.extra_ops.to_one_hot(y, 10) # loss function #loss = T.mean(T.sqr(labels - model.output)) loss = model.loss(labels) # average number of correct predictions over a batch #accuracy = T.mean(T.eq(model.pred, y)) accuracy = model.accuracy(y) # updates #rate = 0.05 #g_W = T.grad(cost=loss, wrt=model.W) #g_b = T.grad(cost=loss, wrt=model.b) #updates = [(model.W, model.W - rate * g_W), # (model.b, model.b - rate * g_b)] updates = model.updates(loss, rate=0.3) # batch index index = T.scalar('batch index', dtype='int32') size = T.scalar('batch size', dtype='int32') train = theano.function([index, size], [loss, accuracy], updates=updates, givens={x: train_set[0][index * size: (index + 1) * size], y: train_set[1][index * size: (index + 1) * size]}) valid = theano.function([index, size], [loss, accuracy], givens={x: valid_set[0][index * size: (index + 1) * size], y: valid_set[1][index * size: (index + 1) * size]}) test = theano.function([index, size], [accuracy], givens={x: test_set[0][index * size: (index + 1) * size], y: test_set[1][index * size: (index + 1) * size]}) n_epochs = 10 batch_size = 500 # number of items in training dataset/batch size batches_in_epoch = datasets[0][0].shape[0] // batch_size losses = np.empty(0) errors = np.empty(0) for epoch in range(1, n_epochs + 1): epoch_losses = np.empty(0) epoch_errors = np.empty(0) for batch_n in range(batches_in_epoch): l, e = train(batch_n, batch_size) epoch_losses = np.append(epoch_losses, l) epoch_errors = np.append(epoch_errors, e) print('[%s]' % time.ctime(), 'epoch: ', epoch, 'batch: ', batch_n, 'loss: ', np.round(l, 4), 'accuracy: ', np.round(e, 4)) # shuffle train set every epoch shuffle = np.arange(datasets[0][1].shape[0]) np.random.shuffle(shuffle) train_set[0] = train_set[0][shuffle] train_set[1] = train_set[1][shuffle] losses = np.concatenate([losses, epoch_losses]) errors = np.concatenate([errors, epoch_errors]) valid_l, valid_e = valid(0, datasets[1][0].shape[0]) print('[%s]' % time.ctime(), 'epoch: ', epoch, 'validation loss: ', valid_l, 'validation accuracy: ', valid_e) acc = test(0, datasets[2][0].shape[0]) print() print('Final accuracy: ', np.round(acc, 4)[0])
Nun zu trainieren, wenn man sich die Kommentare sieht, versuchte ich es mit einem grundlegenden logistischen Regressionsmodell und es funktionierte, Ich habe eine Genauigkeit von 80%. Aber es funktioniert nicht, wenn ich es durch mein MLP-Modell ersetze. Es konvergiert zu nichts und ich bekomme zufällige Vermutungen mit 10% Genauigkeit. Was mache ich falsch? Die Daten, die ich benutze, sind das MNIST-Dataset, das wie bei Theano-Tutorials in Shared-Variablen geladen wird.
Der Aufbau des Netzwerks hängt von den Daten ab, aber die Verwendung von 128 Einheiten in der versteckten Ebene für einen Datensatz mit der Eingabegröße 784 ist möglicherweise etwas niedrig (das ist eine große Dimensionsreduktion und kann zu Informationsverlust führen) Konvergenz. Vielleicht möchten Sie [hier] (http://stackoverflow.com/questions/10565868/multi-layer-perceptron-mlp-architecture-criteria-for-choosing-number-of-hidde) und [hier] (ftp : //ftp.sas.com/pub/neural/FAQ3.html#A_hu). Ich würde vorschlagen, dass Sie mit einer hohen Dimension von versteckten Einheiten beginnen, sagen wir, 1024 oder 512, dann tunen Sie es später, indem Sie kleine Werte ausprobieren – MGoksu
I habe viele verschiedene Konfigurationen ausprobiert und ich bekomme das gleiche Ergebnis mit 128, 256, 512, 1024 und 2048. Und all diese konvergieren gut für mich, wenn ich es mit Tensorflow mache. Ich erhalte unterschiedliche Genauigkeiten, aber selbst mit 128 Einheiten versteckter Ebene erreiche ich eine Genauigkeit von 97%. MNIST ist kein schwieriger zu klassifizierender Datensatz. Ich vermute also, dass dies ein Fehler in meinem Theano-Code ist und kein Problem mit dem Modell. –