([Différence de contrôle de nom de variable](http://qiita.com/TomokIshii/items/178938b6db1edc16b94e#%E8%BF%BD%E8%A8%98%E5%A4%89%E6%95%B0%E5% 90% 8D% E3% 82% B3% E3% 83% B3% E3% 83% 88% E3% 83% AD% E3% 83% BC% E3% 83% AB% E3% 81% AE% E9% 81% Ajouté environ 95% E3% 81% 84tfcontribkeras-vs-tflayers).)
Des informations ont été publiées lors du TensorFlow Dev Summit, etc., mais l'intégration de TensorFlow et Keras est en cours. Extrait du blog Keras - Présentation de Keras 2.
Keras is best understood as an API specification, not as a specific codebase. In fact, going fowards there will be two separate implementations of the Keras spec: the internal TensorFlow one, available as tf.keras, written in pure TensorFlow and deeply compatible with all TensorFlow functionality, and the external multi-backend one supporting both Theano and TensorFlow (and likely even more backends in the future).
Keras sera divisé en deux implémentations, l'une pour l'intégration TensorFlow et l'autre pour le multi-backend (Theno, TensorFlow, etc.) en tant que package indépendant. .. J'avais l'habitude de passer à Theano / TensorFlow le cas échéant, mais récemment, le backend TensorFlow a été sélectionné. Donc, parmi les deux packages Keras, je suis plus intéressé par la version intégrée de TensorFlow.
Le calendrier suivant a été annoncé lors du Dev Summit l'autre jour. (Extrait de YouTube)
Comme mentionné ci-dessus, il semble que nous prévoyons de prendre des mesures telles que "tf.contrib.keras" et "tf.keras" pour l'intégration. TensorFlow 1.1 (1.1.0-rc1) a été publié cette fois, je voudrais donc l'installer immédiatement et vérifier le contenu.
(L'environnement de programmation est Python 3.5.2, TensorFlow 1.1.0-rc1, Keras 2.0.2.)
Keras 2 est déjà sorti et Qiita a un article d'introduction. (Je l'ai vu.) J'ai également essayé de l'utiliser dans l'environnement de TensorFlow 1.0 + Keras 2.0. L'API n'a pas beaucoup changé depuis la version finale de Keras 1.0 (1.2.2?), Mais les mots clés (arguments, options, etc.) de certaines fonctions ont changé en détail. L'exemple de code pour la classification MNIST est le suivant.
# Keras 2.0 + TensorFlow 1.0 backend
import numpy as np
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation
from keras.optimizers import Adagrad
from keras.utils import np_utils
(Omis)
model = Sequential()
model.add(Dense(512, input_dim=784))
model.add(Activation('relu'))
model.add(Dropout(0.2))
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.2))
model.add(Dense(10))
model.add(Activation('softmax'))
(Omis)
J'en ai omis beaucoup, mais faites attention au point d'importation du module (de keras.xxx).
Maintenant, essayons ** tf.contrib.keras ** publié cette fois. Je l'ai codé en apportant des modifications au code ci-dessus (TF 1.0 + Keras 2.0).
import numpy as np
from tensorflow.contrib.keras.python.keras.datasets import mnist
from tensorflow.contrib.keras.python.keras.models import Sequential
from tensorflow.contrib.keras.python.keras.layers import Dense
from tensorflow.contrib.keras.python.keras.layers import Dropout, Activation
from tensorflow.contrib.keras.python.keras.optimizers import Adagrad
from tensorflow.contrib.keras.python.keras.utils import np_utils
from tensorflow.contrib.keras.python.keras import backend as K
def load_data(nb_classes=10):
# the data, shuffled and split between tran and test sets
(X_train, y_train), (X_test, y_test) = mnist.load_data()
X_train = X_train.reshape(60000, 784)
X_test = X_test.reshape(10000, 784)
X_train = X_train.astype('float32')
X_test = X_test.astype('float32')
X_train /= 255
X_test /= 255
print(X_train.shape[0], 'train samples')
print(X_test.shape[0], 'test samples')
# convert class vectors to binary class matrices
y_train = np_utils.to_categorical(y_train, nb_classes)
y_test = np_utils.to_categorical(y_test, nb_classes)
return X_train, y_train, X_test, y_test
def mk_model():
model = Sequential()
model.add(Dense(512, input_dim=784))
model.add(Activation('relu'))
model.add(Dropout(0.2))
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.2))
model.add(Dense(10))
model.add(Activation('softmax'))
return model
Dans la première moitié du code, le point d'importation du module change (évidemment). (Le répertoire est profond.) Bien qu'il s'agisse d'une partie de création de modèle, il n'y a pas de changement dans le contenu (bien que je l'ai mis dans la fonction "mk_model"). Semble 100% compatible avec l'API Keras 2.0 (tf.contrib.keras).
De plus, il n'y a pas eu de changements majeurs dans la seconde moitié du code (ci-dessous).
if __name__ == '__main__':
np.random.seed(1337) # for reproducibility
batch_size = 128
nb_epoch = 20
X_train, y_train, X_test, y_test = load_data()
model = mk_model()
model.summary() # check model configuration
model.compile(loss='categorical_crossentropy',
optimizer=Adagrad(),
metrics=['accuracy'])
model.fit(X_train, y_train,
batch_size=batch_size, epochs=nb_epoch,
verbose=1,
validation_data=(X_test, y_test))
score = model.evaluate(X_test, y_test, verbose=0)
print('\nTest score : {:>.4f}'.format(score[0]))
print('Test accuracy: {:>.4f}'.format(score[1]))
K.clear_session()
# This statement is fixed the condition of ...
# Exception ignored in: <bound method BaseSession.__del__ of
# <tensorflow.python.client.session.Session object at 0x7fb79a3fa550>>
# ...
# AttributeError: 'NoneType' object has no attribute 'TF_NewStatus'
#
# TensorFlow issue: Exception ignored in BaseSession.__del__ #3388
Il semble qu'il n'y ait pas de problème fonctionnel, donc à l'avenir (bien que je n'ai pas supprimé le package Keras du disque), il semble que l'API Keras puisse être utilisée simplement en installant TensorFlow sans installer le package Keras. (Dans le passé, quand j'étais dans Keras 1.x.x, je devais faire attention à la synchronisation des versions entre Keras et TensorFlow ...)
Cependant, une erreur s'est produite lorsque le programme a été arrêté, j'ai donc dû enquêter un peu. Il semble que des problèmes puissent survenir dans le traitement lié à la libération des ressources informatiques. (La reproductibilité est inconnue, mais dans mon environnement, une erreur s'est produite la plupart du temps.)
Comme mentionné ci-dessus, la contre-mesure est d'insérer l'instruction «K.clear_session ()». (Je ne comprends pas entièrement la cause de cette erreur et de ce bug. Si vous êtes intéressé, veuillez consulter le site associé.)
Puisqu'il s'agit de Keras lui-même, quittons le cadre de Keras Model
et utilisons-le comme bibliothèque de classes de couches. Cette utilisation est supportée depuis longtemps et n'est pas particulièrement nouvelle, mais je vais l'essayer avec la dernière version de la bibliothèque (tf.contrib.keras).
(La source est Keras Blog- Keras comme interface simplifiée pour TensorFlow: tutoriel Masu.)
import numpy as np
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
from tensorflow.contrib.keras.python import keras
from tensorflow.contrib.keras.python.keras import backend as K
def load_data():
dirn = '../MNIST_data'
mnist = input_data.read_data_sets(dirn, one_hot=True)
print(mnist.train.num_examples, 'train samples')
print(mnist.test.num_examples, 'test samples')
print(mnist.validation.num_examples, 'validation samples (not used)')
return mnist
def mlp_model(input):
# MLP network model
with tf.variable_scope('mlp_model'):
x = keras.layers.Dense(units=512, activation='relu')(input)
x = keras.layers.Dropout(0.2)(x)
x = keras.layers.Dense(units=512, activation='relu')(x)
x = keras.layers.Dropout(0.2)(x)
y_pred = keras.layers.Dense(units=10, activation='softmax')(x)
return y_pred
if __name__ == '__main__':
mnist = load_data()
# tensorflow placeholders
x = tf.placeholder(tf.float32, [None, 784])
y_ = tf.placeholder(tf.float32, [None, 10])
# define TF graph
y_pred = mlp_model(x)
loss = tf.losses.softmax_cross_entropy(y_, y_pred)
train_step = tf.train.AdagradOptimizer(0.05).minimize(loss)
correct_prediction = tf.equal(tf.argmax(y_pred, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
print('Training...')
for i in range(10001):
batch_xs, batch_ys = mnist.train.next_batch(100)
train_fd = {x: batch_xs, y_: batch_ys, K.learning_phase(): 1}
train_step.run(feed_dict=train_fd)
if i % 1000 == 0:
batch_xv, batch_yv = mnist.test.next_batch(200)
val_accuracy = accuracy.eval(
{x: batch_xv, y_: batch_yv, K.learning_phase(): 0})
print(' step, accurary = %6d: %6.3f' % (i, val_accuracy))
test_fd = {x: mnist.test.images, y_: mnist.test.labels,
K.learning_phase(): 0}
test_accuracy = accuracy.eval(feed_dict=test_fd)
print('Test accuracy:', test_accuracy)
J'ai pu écrire le code de classification basé sur le modèle MLP (Multi-layer Perceptron) du MNIST comme "propre". (Comparé au code TensorFlow "simple" qui n'utilise pas l'API HighLevel, cela signifie "propre".)
L'avantage d'utiliser Keras en tant que bibliothèque de classes de couches est qu'il définit la valeur par défaut "de manière appropriée". Ce point a été souligné dans la présentation au TensorFlow Dev Summit comme "une API de haut niveau accessible avec de bonnes valeurs par défaut". Dans le code ci-dessus, l'initialiseur de variable n'est pas défini en détail dans la couche de liaison complète Dense (), mais l'initialiseur de "Glorot_uniform" (Xavier uniform) est appliqué pour Weight et "zeros "pour Bias. L'initialiseur est appliqué. (Il semble que cette méthode d'initialisation de paramètre soit souvent utilisée dans le récent exemple de code de réseau neuronal.) (Le paramètre feed_dict de K.learning_phase () contrôle le comportement de Dropout. Pour plus de détails, reportez-vous au blog Keras "Keras en tant que simplifié ...".)
Pour le moment, je suis curieux de savoir comment utiliser la variable Tensor, alors vérifiez le nom (nom de la variable).
# vars = tf.global_variables()
# print('variables:')
# for v in vars:
# print(v)
variables:
<tf.Variable 'mlp_model/dense_1/kernel:0' shape=(784, 512) dtype=float32_ref>
<tf.Variable 'mlp_model/dense_1/bias:0' shape=(512,) dtype=float32_ref>
<tf.Variable 'mlp_model/dense_2/kernel:0' shape=(512, 512) dtype=float32_ref>
<tf.Variable 'mlp_model/dense_2/bias:0' shape=(512,) dtype=float32_ref>
<tf.Variable 'mlp_model/dense_3/kernel:0' shape=(512, 10) dtype=float32_ref>
<tf.Variable 'mlp_model/dense_3/bias:0' shape=(10,) dtype=float32_ref>
<tf.Variable 'mlp_model/dense_1/kernel/Adagrad:0' shape=(784, 512) dtype=float32_ref>
<tf.Variable 'mlp_model/dense_1/bias/Adagrad:0' shape=(512,) dtype=float32_ref>
<tf.Variable 'mlp_model/dense_2/kernel/Adagrad:0' shape=(512, 512) dtype=float32_ref>
<tf.Variable 'mlp_model/dense_2/bias/Adagrad:0' shape=(512,) dtype=float32_ref>
<tf.Variable 'mlp_model/dense_3/kernel/Adagrad:0' shape=(512, 10) dtype=float32_ref>
<tf.Variable 'mlp_model/dense_3/bias/Adagrad:0' shape=(10,) dtype=float32_ref>
Parmi les 12 variables tf ci-dessus, les 6 premières sont le poids (noyau) et le biais de la couche dense, et les 6 autres sont les variables dérivées de l'optimiseur. Le root'mlp_model'a été nommé par moi-même dans le code, mais'dense_1 / kernel ',' dense_1 / bias ', ... sont automatiquement nommés par "tf.contrib.keras" Il est. J'ai cherché dans la documentation parce que je voulais décider moi-même du nom de cette variable Tensor, mais il semble qu'elle ne prend actuellement pas en charge la dénomination des utilisateurs. (Il peut s'agir d'un usage qui s'écarte du concept de dissimulation de petits détails autant que possible pour le rendre plus facile à utiliser.)
Si vous souhaitez accéder au nom de la variable Tensor ou décider vous-même du nom de la variable à des fins de partage de poids, etc., il semble qu'il vaut mieux s'éloigner de l'API Keras.
import numpy as np
import tensorflow as tf
from tensorflow.python.layers import layers
from tensorflow.examples.tutorials.mnist import input_data
from sklearn.metrics import confusion_matrix
# Create n.n. model
def nn_model(images, drop_rate, vs, reuse=False):
with tf.variable_scope(vs, reuse=reuse):
net = tf.layers.dense(images, 512, activation=tf.nn.relu, name='dense1')
net = tf.layers.dropout(net, rate=drop_rate)
net = tf.layers.dense(net, 512, activation=tf.nn.relu, name='dense2')
net = tf.layers.dropout(net, rate=drop_rate)
net = tf.layers.dense(net, 10, activation=None, name='dense3')
return net
x = tf.placeholder(tf.float32, [None, 784])
y_ = tf.placeholder(tf.float32, [None, 10])
keep_prob = tf.placeholder(tf.float32)
drop_rate = 1 - keep_prob
mlp1_pred = nn_model(x, drop_rate, 'mlp1')
mlp2_pred = nn_model(x, drop_rate, 'mlp1', reuse=True)
loss = tf.losses.softmax_cross_entropy(y_, mlp1_pred)
train_step = tf.train.AdagradOptimizer(0.05).minimize(loss)
correct_prediction = tf.equal(tf.argmax(mlp1_pred, 1), tf.argmax(y_, 1))
accuracy1 = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
Ce qui précède est un codage utilisant "tf.layers" pris en charge par TensorFlow 1.0 ou version ultérieure. Ici, vous pouvez contrôler vous-même le nom de la variable et la portée de la variable, et vous pouvez librement définir des variables partagées avec l'indicateur reuse
.
(Référence, Qiita ci-dessus)
Au fait, remarquez-vous quelque chose lorsque vous regardez le code basé sur "tf.layers" ci-dessus?
Oui, l'API de "tf.layers" et l'API de "tf.contrib.keras" sont très similaires.
Il y en aura probablement d'autres.
Dans mon "API avec augmentation de TensorFlow ..." mentionnée ci-dessus, j'ai écrit négativement à "tf.layers" comme "l'API n'est pas bien organisée et organisée", mais en réalité, l'API Keras L'intégration avec était à l'étude. Le mot clé changé dans Keras 2.0 est également censé être un changement dans la prise en compte de "tf.layers" (je regrette ma légèreté).
Après de nombreuses recherches, nous pouvons nous attendre à une intégration future de TensorFlow et Keras, en particulier la prochaine version, TensorFlow 1.2. (Est-ce vers mai 2017?) Il n'y a pas beaucoup d'informations sur le type d'API qu'il s'agira pour le moment, mais compte tenu de la relation entre la version actuelle du package indépendant de Keras 2 et "tf.contrib.keras", il y a un gros problème en termes de continuité d'API. Je ne m'attends pas à ce que cela arrive. Pour le moment, j'aimerais approfondir ma compréhension de la version actuelle tout en m'attendant à des fonctionnalités plus élevées de TensorFlow et à une plus grande facilité d'utilisation avec "tf.keras".
Dans l'introduction de tf.conrib.keras ci-dessus, j'ai écrit que "Actuellement, il ne semble pas prendre en charge la dénomination des utilisateurs", mais c'était incorrect. Il semble que vous puissiez spécifier l'option "nom" dans la définition de la couche. (Bien que cela ne soit pas expliqué dans le document, il y avait une partie où "nom" était utilisé dans le code de test dans github.) Cependant, il semble que la variable ne soit pas réutilisée en spécifiant "réutiliser". Voir le code ci-dessous.
import numpy as np
import tensorflow as tf
from tensorflow.contrib.keras.python import keras
from tensorflow.contrib.keras.python.keras import backend as K
from tensorflow.python.layers import layers
def mlp_model_keras1(input):
# MLP network model
with tf.variable_scope('mlp_model'):
x = keras.layers.Dense(units=512, activation='relu', name='my_dense1')(input)
x = keras.layers.Dense(units=512, activation='relu', name='my_dense2')(x)
y_pred = keras.layers.Dense(units=10, activation='softmax', name='my_softmax')(x)
return y_pred
def mlp_model_keras2(input):
# MLP network model
with tf.variable_scope('mlp_model', reuse=True):
x = keras.layers.Dense(units=512, activation='relu', name='my_dense1')(input)
x = keras.layers.Dense(units=512, activation='relu', name='my_dense2')(x)
y_pred = keras.layers.Dense(units=10, activation='softmax', name='my_softmax')(x)
return y_pred
# Create the model
def mlp_model_by_layers1(input):
with tf.variable_scope('mlp_by_tflayers'):
net = tf.layers.dense(input, 512, activation=tf.nn.relu, name='his_dense1')
net = tf.layers.dense(net, 512, activation=tf.nn.relu, name='his_dense2')
net = tf.layers.dense(net, 10, activation=None, name='his_dense3')
return net
def mlp_model_by_layers2(input):
with tf.variable_scope('mlp_by_tflayers', reuse=True):
net = tf.layers.dense(input, 512, activation=tf.nn.relu, name='his_dense1')
net = tf.layers.dense(net, 512, activation=tf.nn.relu, name='his_dense2')
net = tf.layers.dense(net, 10, activation=None, name='his_dense3')
return net
if __name__ == '__main__':
fake_data = np.ones([10, 784], dtype=np.float32) * 0.5
x = tf.placeholder(tf.float32, [None, 784])
# define TF graph
y_pred1 = mlp_model_keras1(x)
y_pred2 = mlp_model_keras2(x)
y_pred3 = mlp_model_by_layers1(x)
y_pred4 = mlp_model_by_layers2(x)
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
vars = tf.global_variables()
print('variables:')
for v in vars:
print(v)
'''
variables:
#Première fonction"mlp_model_keras1"Variables définies dans
<tf.Variable 'mlp_model/my_dense1/kernel:0' shape=(784, 512) dtype=float32_ref>
<tf.Variable 'mlp_model/my_dense1/bias:0' shape=(512,) dtype=float32_ref>
<tf.Variable 'mlp_model/my_dense2/kernel:0' shape=(512, 512) dtype=float32_ref>
<tf.Variable 'mlp_model/my_dense2/bias:0' shape=(512,) dtype=float32_ref>
<tf.Variable 'mlp_model/my_softmax/kernel:0' shape=(512, 10) dtype=float32_ref>
<tf.Variable 'mlp_model/my_softmax/bias:0' shape=(10,) dtype=float32_ref>
#Deuxième fonction"mlp_model_keras2"Variables définies dans
<tf.Variable 'mlp_model_1/my_dense1/kernel:0' shape=(784, 512) dtype=float32_ref>
<tf.Variable 'mlp_model_1/my_dense1/bias:0' shape=(512,) dtype=float32_ref>
<tf.Variable 'mlp_model_1/my_dense2/kernel:0' shape=(512, 512) dtype=float32_ref>
<tf.Variable 'mlp_model_1/my_dense2/bias:0' shape=(512,) dtype=float32_ref>
<tf.Variable 'mlp_model_1/my_softmax/kernel:0' shape=(512, 10) dtype=float32_ref>
<tf.Variable 'mlp_model_1/my_softmax/bias:0' shape=(10,) dtype=float32_ref>
#Troisième fonction"mlp_model_by_layers1"Variables définies dans
<tf.Variable 'mlp_by_tflayers/his_dense1/kernel:0' shape=(784, 512) dtype=float32_ref>
<tf.Variable 'mlp_by_tflayers/his_dense1/bias:0' shape=(512,) dtype=float32_ref>
<tf.Variable 'mlp_by_tflayers/his_dense2/kernel:0' shape=(512, 512) dtype=float32_ref>
<tf.Variable 'mlp_by_tflayers/his_dense2/bias:0' shape=(512,) dtype=float32_ref>
<tf.Variable 'mlp_by_tflayers/his_dense3/kernel:0' shape=(512, 10) dtype=float32_ref>
<tf.Variable 'mlp_by_tflayers/his_dense3/bias:0' shape=(10,) dtype=float32_ref>
#Quatrième fonction"mlp_model_by_layers2"Les variables définies dans ne sont pas trouvées (sinon).
'''
Des quatre modèles, les deux premiers utilisent tf.contrib.keras. Lorsque "nom" est spécifié dans "keras.layers.Dense", le nom est reflété dans le nom de la variable. Dans le deuxième modèle, j'ai défini la même portée de variable (même nom de variable) et ajouté reuse = True
à tf.variable_scope, mais cela a été ignoré et le nom de la portée de la variable a été automatiquement changé de" mlp_model "à" mlp_model_1 ". Le nom de la variable a été donné en la convertissant.
D'un autre côté, le résultat de faire de même pour les 3e et 4e modèles tf.layers ne provoque pas le changement automatique du nom de la portée, et le résultat est comme indiqué dans la partie commentaire du code ci-dessus. (Les variables sont réservées uniquement pour celle définie par la 3ème fonction, et aucune nouvelle variable n'est réservée pour la 4ème fonction. Je n'ai pas confirmé correctement le contenu, mais comme prévu, les variables sont réaffectées. Il est probable que l'utilisation et les variables partagées aient été définies.
Je ne pense pas que quiconque utilisera la bibliothèque tf.contrib.keras et tf.layers ensemble, mais le comportement sera différent, donc je pense que c'est un ** "danger de mélange" **. (Je pense que les spécifications vues ci-dessus peuvent changer dans les versions futures.)
BaseSession.__del__
https://github.com/tensorflow/tensorflow/issues/3388
--Keras a été mis à jour vers 2.0. --Qiita
http://qiita.com/cvusk/items/aa6270301ff2d14fb989Recommended Posts