Ces dernières années, le deep learning (deep neural network: DNN) a attiré l'attention dans le domaine de l'apprentissage automatique. Parallèlement à cela, diverses bibliothèques DNN ont été publiées, mais quelles sont les différences entre elles (laquelle devrait être utilisée)? Dans cet article, je voudrais comparer comment la structure du réseau de DNN est décrite dans chaque bibliothèque. Cet article est destiné à ceux qui connaissent DNN dans une certaine mesure mais ne connaissent pas les bibliothèques. Si vous avez lu les didacticiels de chaque bibliothèque et que vous avez réellement écrit le code, il n'y a rien de plus.
De nombreuses bibliothèques sont ouvertes au public, mais cet article traite du chainer et de TensorFlow. J'espère ajouter d'autres bibliothèques à l'avenir. Ci-dessous, je vais d'abord résumer uniquement les informations de base simples de chaque bibliothèque. Pour comparer la vitesse, etc. [J'ai comparé la bibliothèque Deep Learning qui peut être écrite en Python] [] était facile à comprendre, merci. Je me demande si ce site suffit, mais dans cet article, je voudrais organiser spécifiquement le code source et comparer les descriptions de la même structure de réseau.
Il s'agit d'une bibliothèque ouverte que Google utilise en fait en interne. Je suis simplement attiré par google (?
PEN est une startup japonaise et semble être financée par NTT. Vous pouvez vous attendre à des documents japonais (?
Je viens de le résumer en référence au tutoriel ... Puisque je suis un débutant DNN, il peut y avoir des erreurs dans les termes.
Dans cet article, nous utilisons une structure de réseau MLP à 3 couches. Je voulais vraiment faire CNN, mais c'était la prochaine fois. Le nombre d'unités de calque masquées est de 100. `` Couche d'entrée - Couche cachée - Couche de sortie ''
Les nombres manuscrits MNIST sont utilisés comme ensemble de données. Il semble que ce soit déjà un problème simple pour DNN, mais cette fois je veux surtout comparer la méthode de description. La couche d'entrée est de 784 dimensions (28 x 28) et la sortie est de 10 dimensions.
J'ai utilisé data.py '' utilisé dans l'exemple de chainer pour obtenir les données. Dans TensorFlow, un exemple appelé `ʻinput_data.py
est souvent utilisé, mais j'ai utilisé les données lues à partir de
data.pyà des fins d'étude. (Dans
data.py, l'étiquette est représentée par un nombre et représentée par un vecteur tel que
{1,4,9,2 ...} . Par contre, dans `ʻinput_data.py
, elle est représentée parIl est exprimé par un ensemble de vecteurs One-Hot tels que
{0,0, ..., 1,0}
. Au début, je n'ai pas remarqué cette différence et j'ai eu une erreur indiquant que la dimension était fausse. L'opération de conversion est représentée par une méthode appelée x).
trainingData
import data
import numpy as np
mnist = data.load_mnist_data()
x_all = mnist['data'].astype(np.float32) / 255
y_all = mnist['target'].astype(np.int32)
#only tensorFlow
y_all = dense_to_one_hot(y_all)
x_train, x_test = np.split(x_all, [60000])
y_train, y_test = np.split(y_all, [60000])
x_train.shape => (60000, 784)
y_train.shape => (60000, 1) or (60000, 10)
Il est.
Cette fois, ubuntu14.04 (CPU uniquement) a été utilisé. Par conséquent, les deux bibliothèques pourraient être facilement installées avec `` pip ''. Sous Windows ... Je ne toucherai pas cette fois.
chainer
chainer(classDefine)
import chainer
import chainer.functions as F
import chainer.links as L
class MLP(chainer.Chain):
def __init__(self):
super(MLP, self).__init__(
l1=L.Linear(784, 100),
l2=L.Linear(100, 100),
l3=L.Linear(100, 10),
)
def __call__(self, x):
h1 = F.relu(self.l1(x))
h2 = F.relu(self.l2(h1))
y = self.l3(h2)
return y
class Classifier(Chain):
def __init__(self, predictor):
super(Classifier, self).__init__(predictor=predictor)
def __call__(self, x, t):
y = self.predictor(x)
self.loss = F.softmax_cross_entropy(y, t)
self.accuracy = F.accuracy(y, t)
return self.loss
Tout d'abord, créez une classe qui définit la structure de la couche et une classe qui définit l'erreur de sortie.
Dans la classe MLP '',
Linear '' (liaison complète représentée par le poids $ W $ et le biais $ b $) est utilisé pour chaque couche, et ReLU (...) '' est utilisé comme fonction d'activation. Vous pouvez voir qu'il y en a. En changeant cette partie, il semble possible d'ajouter du
dropout (...) '' ou d'ajouter une couche de convolution.
De plus, `` softmax_cross_entropy (...) '', c'est-à-dire l'entropie croisée calculée pour la sortie de la fonction softmax, est utilisée pour calculer l'erreur. À propos, dans la classe Classifier définie, une classe similaire est implémentée en tant que chainer.links.Classifier. Si vous pouvez l'implémenter tel quel, vous pouvez l'utiliser.
chainer(model)
model = Classifier(MLP()) # same as ``L.Classifier(MLP())``
optimizer = optimizers.SGD()
optimizer.setup(model)
Ensuite, créez une instance de la classe définie. La méthode d'optimisation est spécifiée ici, et `` SGD () '' (méthode probabiliste de descente la plus raide) est spécifié.
tensorFlow
tensorFlow
import tensorFlow as tf
# input
x = tf.placeholder(tf.float32, [None, 784])
# label
y_ = tf.placeholder(tf.float32, [None, 10])
# FC1
W1 = tf.Variable(tf.random_normal([784, 100], mean=0.0, stddev=0.05))
b1 = tf.Variable(tf.zeros([100]))
# layer output
h1 = tf.nn.relu(tf.matmul(x, W1) + b1)
# FC2
W2 = tf.Variable(tf.random_normal([100, 100], mean=0.0, stddev=0.05))
b2 = tf.Variable(tf.zeros([100]))
# layer output
h2 = tf.nn.relu(tf.matmul(h1, W2) + b2)
# FC3
W3 = tf.Variable(tf.random_normal([100, 10], mean=0.0, stddev=0.05))
b3 = tf.Variable(tf.zeros([10]))
# output
y = tf.nn.softmax(tf.matmul(h2, W3) + b3)
# training
cross_entropy = -tf.reduce_sum(y_ * tf.log(y))
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)
Dans tensorFlow, chaque couche est représentée par la formule de calcul matricielle $ y = Wx + b $ en utilisant le poids $ W $ et le biais $ b $ ($ x $: entrée, $ y $: sortie).
L'entrée $ x $ sera une matrice appelée (nombre de données, 784) '' cette fois. Le nombre de données est variable en spécifiant
Aucun '' dans le code.
Le poids W1 '' de la première couche est défini comme
(784,100) '', le biais b1 '' est défini comme
(100,) '' et la sortie de la première couche est h1 ''. Définissez la formule pour `. Ici,
relu (...) '' est utilisé comme fonction d'activation. Vous pouvez également voir que la couche de sortie calcule softmax (...) ''.
y_est une variable qui stocke l'étiquette de réponse correcte et est utilisée pour définir l'erreur
cross_entropy ''. L'entropie croisée est utilisée comme erreur et Minimize '' est spécifié à l'aide de
GradientDescentOptimizer ''.
Je pense que la description de chaque couche est plus gênante que le chainer, mais quand j'ai pensé à modifier la structure du réseau, j'ai pensé que ce serait plus facile à faire car la description est la même que la formule. (Le code est compliqué car je ne définis pas correctement la classe
Soit batch_x, batch_y
un mini-lot de x_train, y_train
, respectivement. Voici le traitement d'un mini-lot.
chainer
chainerTraining
optimizer.update(model, batch_x, batch_y)
Passez-le à l'argument de optimizer.update.
tensorFlow
tensorFlowTraining
#sess = tf.Session()
sess.run(train_step, feed_dict={x:batch_x, y_:batch_y})
Dans tensorFlow, les données sont transmises sous forme de dictionnaire sous la forme d'un ensemble avec le `` placeholder '' défini ci-dessus.
Cette fois, nous allons l'exécuter sur un PC de bureau faible avec seulement un processeur, nous avons donc confirmé que le code fonctionne à l'époque environ plusieurs dizaines de fois. Puisqu'il s'agit d'une bibliothèque largement utilisée, je pense qu'elle est comparable en termes de précision et de rapidité. Je vais le vérifier s'il y a une opportunité dans le futur.
En tant que problèmes futurs, je voudrais aborder les points suivants.
Il semble qu'il y aura des différences dans les bibliothèques autour des deux premiers. Je voudrais essayer la prise en charge de plusieurs GPU (la machine pour cela est ... De plus, je pense que le café etc. est souvent utilisé uniquement dans le but de classer à l'aide d'un modèle entraîné (n'y en a-t-il pas beaucoup?), Mais je me demande aussi s'il peut être utilisé à cette fin.
Recommended Posts