Connaissez-vous le problème Fizzbuzz? Il s'agit d'un problème de programmation débutant et vous écrivez le code suivant.
Un exemple de réponse écrite en Python est le suivant.
import numpy as np
num = np.arange(1,101,1)
for i in num:
if i % 15 == 0: print ("fizzbuzz")
elif i % 5 == 0: print ("buzz")
elif i % 3 == 0: print ("fizz")
else: print (i)
Il existe d'innombrables façons d'écrire du code, mais fondamentalement, il est facile d'écrire en divisant la casse en pour et si.
Pourtant! C'est la nature humaine qui nous donne envie de résoudre ces problèmes avec un apprentissage en profondeur. De plus, certains ancêtres l'ont résolu même avec Tensorflow (bien qu'il n'ait pas été résolu (.ŏ﹏ŏ)). http://joelgrus.com/2016/05/23/fizz-buzz-in-tensorflow/
Alors, réécrivons le fizzbuzz Tensorflow ci-dessus avec Keras. Principalement, seule la partie modèle a été migrée vers Keras, et la plupart des autres codes sont basés sur la version de Tensorflow telle quelle.
Un modèle de réseau neuronal est créé par apprentissage supervisé et le taux de réponse correct du modèle est évalué en utilisant un entier de 1 à 100 comme données de test.
Écrivons-le maintenant.
Tout d'abord, importez les bibliothèques requises.
import numpy as np
from keras.models import Sequential
from keras.layers import Dense
from keras.utils import np_utils
from keras.layers import Dense
from keras.models import Model
Les données de l'enseignant sont requises. Cette fois, les données de l'enseignant sont un nombre entier de 101 à 1024, mais les données de l'enseignant sont au format binaire. Autrement dit, la matrice en (923, 10) est les données de l'enseignant.
def binary_encode(i, num_digits):
return np.array([i >> d & 1 for d in range(num_digits)])
NUM_DIGITS = 10
trX = np.array([binary_encode(i, NUM_DIGITS) for i in range(101, 2 ** NUM_DIGITS)])
Maintenant, nous avons également besoin de la valeur fizzbuzz des données de l'enseignant. Ceci est également réalisé au format binaire.
def fizz_buzz_encode(i):
if i % 15 == 0: return np.array([0, 0, 0, 1])
elif i % 5 == 0: return np.array([0, 0, 1, 0])
elif i % 3 == 0: return np.array([0, 1, 0, 0])
else: return np.array([1, 0, 0, 0])
trY = np.array([fizz_buzz_encode(i) for i in range(101, 2 ** NUM_DIGITS)])
Ceci complète les données de l'enseignant 101-1024 entiers (format binaire) et leur fizzbuzz (format binaire). Les préparatifs sont terminés. Maintenant écrivons un modèle.
Générez des modèles de manière séquentielle.
model = Sequential()
Ajoutez un calque. Cette fois, nous utiliserons un réseau à 3 couches (entièrement combiné).
model.add(Dense(1000, input_dim=10, activation="relu"))
model.add(Dense(1000, activation="relu"))
model.add(Dense(4, activation="softmax"))
La sortie finale est un entier, un fizz, un buzz ou un fizzbuzz, donc la couche finale aura une sortie de 4.
L'algorithme d'optimisation doit être adagrad. La version Tensorflow était SGD, mais elle n'a pas beaucoup convergé lorsque je l'ai fait avec Keras. Compilons le modèle et formons-le.
model.compile(loss='categorical_crossentropy', optimizer='adagrad', metrics=["accuracy"])
model.fit(trX, trY, nb_epoch=100, batch_size=128)
C'est un taux de convergence équitable. (Légèrement overfit?)
Évaluons ce modèle. Appliquons le modèle aux entiers de 1 à 100.
def fizz_buzz(i, prediction):
return [str(i), "fizz", "buzz", "fizzbuzz"][prediction]
numbers = np.arange(1, 101)
teX = np.transpose(binary_encode(numbers, NUM_DIGITS))
teY = model.predict_classes(teX)
output = np.vectorize(fizz_buzz)(numbers, teY)
print (output)
sortit de.
À propos, la bonne réponse est la suivante.
answer = np.array([])
for i in numbers:
if i % 15 == 0: answer = np.append(answer, "fizzbuzz")
elif i % 5 == 0: answer = np.append(answer, "buzz")
elif i % 3 == 0: answer = np.append(answer, "fizz")
else: answer = np.append(answer, str(i))
print (answer)
Voyons le taux de précision du modèle.
evaluate = np.array(answer == output)
print (np.count_nonzero(evaluate == True) / 100)
97%!! Est-ce si bon?
Vous pouvez obtenir un meilleur taux de précision en augmentant le nombre de couches et d'unités, mais ce n'est pas grave.
Le code entier est ci-dessous.
import numpy as np
from keras.models import Sequential
from keras.layers import Dense
from keras.utils import np_utils
from keras.layers import Dense
from keras.models import Model
#Génération des données des enseignants
def binary_encode(i, num_digits):
return np.array([i >> d & 1 for d in range(num_digits)])
NUM_DIGITS = 10
trX = np.array([binary_encode(i, NUM_DIGITS) for i in range(101, 2 ** NUM_DIGITS)])
#Fizzbuzz des données des enseignants
def fizz_buzz_encode(i):
if i % 15 == 0: return np.array([0, 0, 0, 1])
elif i % 5 == 0: return np.array([0, 0, 1, 0])
elif i % 3 == 0: return np.array([0, 1, 0, 0])
else: return np.array([1, 0, 0, 0])
trY = np.array([fizz_buzz_encode(i) for i in range(101, 2 ** NUM_DIGITS)])
#modèle
model = Sequential()
model.add(Dense(1000, input_dim=10, activation="relu"))
model.add(Dense(1000, activation="relu"))
model.add(Dense(4, activation="softmax"))
model.compile(loss='categorical_crossentropy', optimizer='adagrad', metrics=["accuracy"])
model.fit(trX, trY, nb_epoch=100, batch_size=128)
#Conversion fizzbuzz binaire
def fizz_buzz(i, prediction):
return [str(i), "fizz", "buzz", "fizzbuzz"][prediction]
#Essayez d'appliquer le modèle à des entiers de 1 à 100
numbers = np.arange(1, 101)
teX = np.transpose(binary_encode(numbers, NUM_DIGITS))
teY = model.predict_classes(teX)
output = np.vectorize(fizz_buzz)(numbers, teY)
print (output)
#Bonne réponse
answer = np.array([])
for i in numbers:
if i % 15 == 0: answer = np.append(answer, "fizzbuzz")
elif i % 5 == 0: answer = np.append(answer, "buzz")
elif i % 3 == 0: answer = np.append(answer, "fizz")
else: answer = np.append(answer, str(i))
print (answer)
#Taux de réponse correct
evaluate = np.array(answer == output)
print (np.count_nonzero(evaluate == True) / 100)