Cet article est une sortie facile à comprendre du ** Deep Learning from scratch Chapter 7 Learning Techniques **. J'ai pu le comprendre moi-même, j'espère donc que vous pourrez le lire confortablement. De plus, je serais plus qu'heureux si vous pouviez vous y référer lors de l'étude de ce livre.
Jusqu'à présent, la valeur initiale du poids du réseau de neurones utilisait la méthode aléatoire pour générer un nombre aléatoire, mais cela élargirait le succès de l'apprentissage.
La valeur initiale du poids et l'entraînement du réseau neuronal sont très étroitement liés, et si la valeur initiale est appropriée, le résultat d'apprentissage sera bon, et si la valeur initiale est inappropriée, le résultat d'apprentissage sera mauvais.
Par conséquent, cette fois, je voudrais mettre en œuvre une méthode de définition d'une valeur initiale appropriée de poids dans un réseau neuronal en utilisant la fonction sigmoïde.
La valeur initiale du poids qui convient le mieux au réseau de neurones utilisant la fonction sigmoïde est la valeur initiale de Xavier.
scale = np.sqrt(1.0 / all_size_list[idx - 1])
scale * np.random.randn(all_size_list[idx-1], all_size_list[idx])
La valeur initiale de Xavier peut être créée en calculant 1 ÷ le nombre de nœuds dans la couche précédente avec une racine et en le multipliant par un nombre aléatoire aléatoire.
Vous trouverez ci-dessous un exemple de réseau de neurones qui utilise les valeurs initiales de He et Xavier.
#Application de la valeur initiale du poids ・ Réseau neuronal implémentant la décroissance du poids
class MutiLayerNet:
def __init__(self,input_size,hiden_size_list,output_size,
activation='relu',weight_init_std='relu',weight_decay_lambda=0):#weight_decay_Plus le lambda est grand, plus fort
self.input_size = input_size#Nombre de neurones dans la couche d'entrée
self.output_size = output_size#Nombre de neurones dans la couche de sortie
self.hiden_size_list = hiden_size_list#Nombre de neurones dans chaque couche de la couche intermédiaire
self.hiden_layer_num = len(hiden_size_list)#Nombre de couches dans la couche intermédiaire
self.weight_decay_lambda = weight_decay_lambda#Réglage de la force de décroissance du poids
self.params = {}#Entrez les paramètres
#Initialisation du poids
self.__init_weight(weight_init_std)
#Création de couches
activation_layer = {'sigmoid': Sigmoid,'relu': Relu}
self.layers = OrderedDict()#Dictionnaire ordonné pour stocker les couches
for idx in range(1, self.hiden_layer_num+1):#Répétez pour le nombre de couches intermédiaires
self.layers['Affine' + str(idx)] = Affine(self.params['W' + str(idx)],
self.params['b' + str(idx)])
self.layers['Activation_function' + str(idx)] = activation_layer[activation]()#Sélectionnez le calque de fonction Relu
idx = self.hiden_layer_num + 1#Créer une couche affine avant la couche de sortie
self.layers['Affine' + str(idx)] = Affine(self.params['W' + str(idx)],
self.params['b' + str(idx)])
self.last_layer = SoftmaxWithLoss()#Couche de la couche de sortie à la fonction de perte
def __init_weight(self, weight_init_std):#Méthode d'initialisation du poids / biais
all_size_list = [self.input_size] + self.hiden_size_list + [self.output_size]#Contient le nombre de neurones dans toutes les couches
for idx in range(1, len(all_size_list)):
scale = weight_init_std#Contient le nombre à multiplier par le poids aléatoire
if str(weight_init_std).lower() in ('relu', 'he'):#Créer la valeur initiale de he lors de l'utilisation de la fonction relu
scale = np.sqrt(2.0 / all_size_list[idx - 1]) #Valeur initiale recommandée lors de l'utilisation de ReLU
elif str(weight_init_std).lower() in ('sigmoid', 'xavier'):#Lors de l'utilisation de la fonction sigmoïde Créez la valeur initiale de xavier
scale = np.sqrt(1.0 / all_size_list[idx - 1]) #Valeur initiale recommandée lors de l'utilisation de sigmoïde
self.params['W' + str(idx)] = scale * np.random.randn(all_size_list[idx-1], all_size_list[idx])#Initialisation du poids
self.params['b' + str(idx)] = np.zeros(all_size_list[idx])#Initialisation du biais
def predict(self, x):#Traitement de propagation avant du réseau neuronal
for layer in self.layers.values():
x = layer.forward(x)
return x
def loss(self, x, t):#Traitement de propagation avant du réseau neuronal à la fonction de perte + traitement de la décroissance du poids
y = self.predict(x)
weight_decay = 0
for idx in range(1, self.hiden_layer_num + 2):#Dans le processus de décroissance du poids, les carrés des poids de chaque couche sont additionnés et le processus suivant est effectué pour résumer.
W = self.params['W' + str(idx)]
weight_decay += 0.5 * self.weight_decay_lambda * np.sum(W ** 2)
return self.last_layer.forward(y, t) + weight_decay
def accuracy(self, x, t):#Calculez le taux de réponse correct
y = self.predict(x)
y = np.argmax(y, axis=1)
if t.ndim != 1 : t = np.argmax(t, axis=1)
accuracy = np.sum(y == t) / float(x.shape[0])
return accuracy
def numerical_gradient(self, x, t):#Différenciation numérique
loss_W = lambda W: self.loss(x, t)
grads = {}
for idx in range(1, self.hidden_layer_num+2):
grads['W' + str(idx)] = slopeing_grad(loss_W, self.params['W' + str(idx)])
grads['b' + str(idx)] = slopeing_grad(loss_W, self.params['b' + str(idx)])
return grads
def gradient(self, x, t):#Méthode de propagation de retour d'erreur
# forward
self.loss(x, t)
# backward
dout = 1
dout = self.last_layer.backward(dout)
layers = list(self.layers.values())
layers.reverse()
for layer in layers:
dout = layer.backward(dout)
#Récupération de gradient
grads = {}
for idx in range(1, self.hiden_layer_num+2):#Gère également la décroissance du poids
grads['W' + str(idx)] = self.layers['Affine' + str(idx)].dW + self.weight_decay_lambda * self.layers['Affine' + str(idx)].W
grads['b' + str(idx)] = self.layers['Affine' + str(idx)].db
return grads
Recommended Posts