2016-04-21 7 views
1

Ich experimentierte mit einfachen grundlegenden (Intro Tutorial-Level) neuronalen Netzwerken in verschiedenen Frameworks, bin aber verwirrt über die Leistung, die ich in TensorFlow sehe. Das einfache Netzwerk von Michael Nielsen's tutorial (MNIST-Ziffernerkennung mit stochastischem L2-Gradientenabstieg in einem Netzwerk mit 30 versteckten Knoten) schneidet viel schlechter ab (dauert etwa 8x so lang pro Epoche, mit den gleichen Parametern) als ein kleines angepasst (mit Vektorisierung durch Minibatch wie in one of the tutorial exercises vorgeschlagen) Version von Nielsen's basic NumPy code.Ist TensorFlow schlecht für einfache Netzwerke?

Führt TensorFlow, der auf einer einzigen CPU läuft, immer so schlecht? Gibt es Einstellungen, die ich optimieren sollte, um die Leistung zu verbessern? Oder glänzt TensorFlow wirklich nur mit viel komplexeren Netzwerken oder Lernregimes, so dass es für solche einfachen Spielzeugfälle nicht gut ist?


from __future__ import (absolute_import, print_function, division, unicode_literals) 

import tensorflow as tf 
from tensorflow.examples.tutorials.mnist import input_data 
import time 


def weight_variable(shape): 
    return tf.Variable(tf.truncated_normal(shape, stddev=0.1)) 


def bias_variable(shape): 
    return tf.Variable(tf.constant(0.1, shape=shape)) 


mnist = input_data.read_data_sets("./data/", one_hot=True) 

sess = tf.Session() 

# Inputs and outputs 
x = tf.placeholder(tf.float32, shape=[None, 784]) 
y_ = tf.placeholder(tf.float32, shape=[None, 10]) 

# Model parameters 
W1 = weight_variable([784, 30]) 
b1 = bias_variable([30]) 
o1 = tf.nn.sigmoid(tf.matmul(x, W1) + b1, name='o1') 
W2 = weight_variable([30, 10]) 
b2 = bias_variable([10]) 
y = tf.nn.softmax(tf.matmul(o1, W2) + b2, name='y') 

sess.run(tf.initialize_all_variables()) 

loss = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y), reduction_indices=[1])) 
loss += 0.1/1000 * (tf.nn.l2_loss(W1) + tf.nn.l2_loss(W2)) 

train_step = tf.train.GradientDescentOptimizer(0.15).minimize(loss) 

accuracy = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1)), tf.float32)) 


for ep in range(30): 
    for mb in range(int(len(mnist.train.images)/40)): 
     batch_xs, batch_ys = mnist.train.next_batch(40) 
     sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys}) 
+0

Wie lange dauert 'next_batch'? Diese Funktion macht viel mehr Zeug als Michael Nielsens Version, die einfaches Numpy Slicing verwendet. –

+0

@YaroslavBulatov: Gibt es eine Möglichkeit, das "viel mehr Zeug" zu deaktivieren, so dass es genau das tut, was Michael Nielsens Version tut, so habe ich einen direkteren Vergleich ? – orome

+0

vielleicht können Sie TensorFlow in Michael Nielsens Version einstecken? –

Antwort

1

Ja, ich möchte, dass die Hand codiert spezialisierte einfache Netzwerke auf CPU läuft erwarten würde schneller laufen als tensorflow diejenigen. Der Grund ist normalerweise mit dem Graphenauswertungssystem verbunden, das Tensorflow verwendet. Der Vorteil der Verwendung von Tensorflow besteht darin, dass Sie viel komplexere Algorithmen verwenden und zuerst die Korrektheit testen und dann problemlos portieren können, um mehr Maschinen und mehr Verarbeitungseinheiten zu verwenden.

Zum Beispiel eine Sache, die Sie versuchen können, ist, Ihren Code auf einem Computer mit einer GPU laufen zu lassen und zu sehen, ohne etwas in Ihrem Code zu ändern, würden Sie schneller, vielleicht schneller als das handcodierte Beispiel erreichen. Sie können sehen, dass der handschriftliche Code erheblichen Aufwand für die Portierung auf GPU erfordern würde.

+0

Und vermutlich dann, wenn ich ein komplexeres Netzwerk (Faltung, mehr Schichten, viel mehr Knoten usw.) oder mehr Phantasie (zB Aussetzer) hatte, würde TensorFlow selbst mit einer einzigen CPU anfangen, das zu übertreffen, was ich mit basic machen konnte NumPy, oder? – orome

+0

definitiv, plus der Code wird von vielen anderen Entwicklern ausgeübt, so ist auch zuverlässiger. – fabrizioM

+0

Fall, ich versuchte gestern numpy OpenBLAS auf Z840 gestern, und es war 430 G Ops/Sekunde für große Matrix-Multiplikation, während TensorFlow gab mir 1,1 T ops/Sekunde –