Dieser Artikel ist eine leicht verständliche Ausgabe von ** Deep Learning von Grund auf neu. Kapitel 7 Lerntechniken **. Ich konnte es selbst verstehen, also hoffe ich, dass Sie es bequem lesen können. Ich würde mich auch sehr freuen, wenn Sie sich beim Studium dieses Buches darauf beziehen könnten.
Bisher verwendete der Anfangswert des Gewichts des neuronalen Netzwerks die Zufallsmethode, um eine Zufallszahl zu erzeugen, aber dies würde den Erfolg des Lernens erweitern.
Der Anfangswert des Gewichts und das Training des neuronalen Netzwerks sind sehr eng miteinander verbunden, und wenn der Anfangswert angemessen ist, ist das Lernergebnis gut, und wenn der Anfangswert unangemessen ist, ist das Lernergebnis schlecht.
Daher möchte ich dieses Mal eine Methode zum Einstellen eines geeigneten Anfangsgewichtswerts in einem neuronalen Netzwerk unter Verwendung der Sigmoid-Funktion implementieren.
Der Anfangswert des Gewichts, das für das neuronale Netzwerk unter Verwendung der Sigmoidfunktion am besten geeignet ist, ist der Anfangswert von Xavier.
scale = np.sqrt(1.0 / all_size_list[idx - 1])
scale * np.random.randn(all_size_list[idx-1], all_size_list[idx])
Der Anfangswert von Xavier kann erstellt werden, indem 1 ÷ die Anzahl der Knoten in der vorherigen Ebene mit einer Wurzel berechnet und mit einer zufälligen Zufallszahl multipliziert wird.
Unten sehen Sie ein Beispiel eines neuronalen Netzwerks, das die Anfangswerte von He und Xavier verwendet.
#Anfangswertanwendung von Gewicht ・ Neuronales Netzwerk, das den Gewichtsabfall implementiert
class MutiLayerNet:
def __init__(self,input_size,hiden_size_list,output_size,
activation='relu',weight_init_std='relu',weight_decay_lambda=0):#weight_decay_Je größer das Lambda, desto stärker
self.input_size = input_size#Anzahl der Neuronen in der Eingabeschicht
self.output_size = output_size#Anzahl der Neuronen in der Ausgabeschicht
self.hiden_size_list = hiden_size_list#Anzahl der Neuronen in jeder Schicht der mittleren Schicht
self.hiden_layer_num = len(hiden_size_list)#Anzahl der Schichten in der mittleren Schicht
self.weight_decay_lambda = weight_decay_lambda#Gewichtsabnahme Festigkeitseinstellung
self.params = {}#Parameter eingeben
#Gewichtsinitialisierung
self.__init_weight(weight_init_std)
#Ebenenerstellung
activation_layer = {'sigmoid': Sigmoid,'relu': Relu}
self.layers = OrderedDict()#Bestelltes Wörterbuch zum Speichern von Ebenen
for idx in range(1, self.hiden_layer_num+1):#Wiederholen Sie dies für die Anzahl der Zwischenschichten
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]()#Wählen Sie die Funktionsebene Relu
idx = self.hiden_layer_num + 1#Erstellen Sie eine affine Ebene vor der Ausgabeebene
self.layers['Affine' + str(idx)] = Affine(self.params['W' + str(idx)],
self.params['b' + str(idx)])
self.last_layer = SoftmaxWithLoss()#Schicht von der Ausgangsschicht zur Verlustfunktion
def __init_weight(self, weight_init_std):#Methode zum Initialisieren von Gewicht / Bias
all_size_list = [self.input_size] + self.hiden_size_list + [self.output_size]#Enthält die Anzahl der Neuronen in allen Schichten
for idx in range(1, len(all_size_list)):
scale = weight_init_std#Enthält die Zahl, die mit dem Zufallsgewicht multipliziert werden soll
if str(weight_init_std).lower() in ('relu', 'he'):#Erstellen Sie den Anfangswert von he, wenn Sie die Relu-Funktion verwenden
scale = np.sqrt(2.0 / all_size_list[idx - 1]) #Empfohlener Anfangswert bei Verwendung von ReLU
elif str(weight_init_std).lower() in ('sigmoid', 'xavier'):#Bei Verwendung der Sigmoid-Funktion Erstellen Sie den Anfangswert von xavier
scale = np.sqrt(1.0 / all_size_list[idx - 1]) #Empfohlener Anfangswert bei Verwendung von Sigmoid
self.params['W' + str(idx)] = scale * np.random.randn(all_size_list[idx-1], all_size_list[idx])#Gewichtsinitialisierung
self.params['b' + str(idx)] = np.zeros(all_size_list[idx])#Bias-Initialisierung
def predict(self, x):#Vorwärtsausbreitungsverarbeitung des neuronalen Netzwerks
for layer in self.layers.values():
x = layer.forward(x)
return x
def loss(self, x, t):#Vorwärtsausbreitungsverarbeitung vom neuronalen Netzwerk zur Verlustfunktion + Gewichtsabnahmeverarbeitung
y = self.predict(x)
weight_decay = 0
for idx in range(1, self.hiden_layer_num + 2):#Beim Gewichtsabnahmeprozess werden die Quadrate der Gewichte jeder Schicht summiert, und der folgende Prozess wird ausgeführt, um zu summieren.
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):#Berechnen Sie die richtige Antwortrate
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):#Numerische Differenzierung
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):#Methode zur Fehlerrückübertragung
# 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)
#Gradientenwiederherstellung
grads = {}
for idx in range(1, self.hiden_layer_num+2):#Behandelt auch Gewichtsabnahme
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