Suite de l'article précédent Notes sur les réseaux de neurones J'ai créé un réseau neuronal à deux couches et j'ai appris MNIST. Reportez-vous au chapitre 4 du Deep Learning à partir de zéro
TwoLayerNet.py
import numpy as np
class TwoLayerNet:
def __init__(self,input_size,hidden_size,output_size,weight_init_std=0.01):
#Initialisation du poids
self.params = {}
#784 *Matrice de 50 poids
self.params['W1'] = weight_init_std * np.random.randn(input_size,hidden_size)
#50 *10 matrice de poids
self.params['W2'] = weight_init_std * np.random.randn(hidden_size,output_size)
#Biais, autant de couches cachées
self.params['b1'] = np.zeros(hidden_size)
#Biais, autant que le nombre de couches de sortie
self.params['b2'] = np.zeros(output_size)
def sigmoid(self,x):
return 1 / (1 + np.exp(-x))
def softmax(self,a):
c = np.max(a)
exp_a = np.exp(a - c)#Mesures de débordement
sum_exp_a = np.sum(exp_a)
y = exp_a / sum_exp_a
return y
def _numerical_gradient_1d(self,f, x):
h = 1e-4 # 0.0001
grad = np.zeros_like(x)
for idx in range(x.size):
tmp_val = x[idx]
x[idx] = float(tmp_val) + h
fxh1 = f(x) # f(x+h)
x[idx] = tmp_val - h
fxh2 = f(x) # f(x-h)
grad[idx] = (fxh1 - fxh2) / (2*h)
x[idx] = tmp_val #Restaurer la valeur
return grad
def numerical_gradient(self,f, X):
if X.ndim == 1:
return self._numerical_gradient_1d(f, X)
else:
grad = np.zeros_like(X)
for idx, x in enumerate(X):
grad[idx] = self._numerical_gradient_1d(f, x)
return grad
def cross_entropy_error(self,y,t):
if y.ndim == 1:
t = t.reshape(1,t.size)
y = y.reshape(1,y.size)
batch_size = y.shape[0]
return -np.sum(t * np.log(y)) / batch_size
def predict(self,x):
W1,W2 = self.params['W1'],self.params['W2']
b1,b2 = self.params['b1'],self.params['b2']
a1 = np.dot(x,W1) + b1 #a = Wx + b
z1 = self.sigmoid(a1)
a2 = np.dot(z1,W2) + b2
z2 = self.softmax(a2)
return z2
def loss(self, x, t):
y = self.predict(x)
return self.cross_entropy_error(y,t)
def gradient(self,x,t):
loss_W = lambda W: self.loss(x,t)
grads = {}
grads['W1'] = self.numerical_gradient(loss_W,self.params['W1'])
grads['W2'] = self.numerical_gradient(loss_W,self.params['W2'])
grads['b1'] = self.numerical_gradient(loss_W,self.params['b1'])
grads['b2'] = self.numerical_gradient(loss_W,self.params['b2'])
return grads
D'autre part, l'apprentissage par mini-lots (taille 50) a été effectué 500 fois à partir des données MNIST.
LearningMNIST.py
import numpy as np
from sklearn.datasets import fetch_mldata
from sklearn.preprocessing import OneHotEncoder
mnist = fetch_mldata('MNIST original', data_home=".")
x_train = mnist['data'][:60000]
t_train = mnist['target'][:60000]
train_loss_list = []
#Normalisation des données(0<=x<=1)je fais
x_train = x_train.astype(np.float64)
x_train /= x_train.max()
#one-Convertir en vecteur chaud
t_train = t_train.reshape(1, -1).transpose()
encoder = OneHotEncoder(n_values=max(t_train)+1)
t_train = encoder.fit_transform(t_train).toarray()
#hyper parameter
iters_num = 500
train_size = x_train.shape[0]
batch_size = 100
learning_rate = 0.1
#Puisque les données d'image sont 28x28, la couche d'entrée est 784, la couche cachée est 50, et la couche de sortie est 10 selon le nombre d'étiquettes.
network = TwoLayerNet(input_size=784,hidden_size=50,output_size=10)
for i in range(iters_num):
batch_mask = np.random.choice(train_size,batch_size)
x_batch = x_train[batch_mask]
t_batch = t_train[batch_mask]
grad = network.gradient(x_batch,t_batch)
for key in ('W1','W2','b1','b2'):
network.params[key] -= learning_rate * grad[key]
loss = network.loss(x_batch,t_batch)
train_loss_list.append(loss)
Ce résultat est le graphique ci-dessous, l'axe vertical est l'erreur d'entropie d'intersection et l'axe horizontal est le nombre d'itérations d'apprentissage.
L'erreur d'entropie croisée est réduite. La prochaine fois, nous vérifierons la précision de prédiction de ce réseau de neurones.
Recommended Posts