Dies ist ein Lernrekord, als ich die Rabbit Challenge mit dem Ziel absolvierte, die Qualifikation der Japan Deep Learning Association (JDLA) E zu bestehen, die am 19. und 20. Januar 2021 stattfinden wird.
Rabbit Challenge ist ein Kurs, der die Unterrichtsmaterialien verwendet, die aus dem aufgezeichneten Video des Schulbesuchskurses "Deep Learning-Kurs, der vor Ort zerstört werden kann" bearbeitet wurden. Es gibt keine Unterstützung für Fragen, aber es ist ein billiger Kurs (der niedrigste Preis ab Juni 2020) für die E-Qualifikationsprüfung.
Bitte überprüfen Sie die Details über den unten stehenden Link.
Angewandte Mathematik Maschinelles Lernen Deep Learning (Tag 1) Deep Learning (Tag 2) Deep Learning (Tag 3) Deep Learning (Tag 4)
Wenn das Fehler-Backpropagation-Verfahren zu den unteren Schichten fortschreitet, wird der Gradient immer sanfter. Daher ändert die Aktualisierung durch das Gradientenabstiegsverfahren kaum die Parameter der unteren Schicht, und das Training konvergiert nicht zum optimalen Wert.
--ReLU-Funktion
Was passiert, wenn ich das Anfangsgewicht auf 0 setze? → Weil alle Werte mit demselben Wert übertragen werden. Parameter werden nicht mehr eingestellt.
Der Durchschnitt und die Varianz der Mini-Charge
Beitrag zum Verschwinden des Gradienten beim Ändern der Aktivierungsfunktion, des anfänglichen Gewichtswerts und des Vorhandenseins / Nichtvorhandenseins einer Chargennormalisierung
import sys, os
sys.path.append(os.pardir) #Einstellungen zum Importieren von Dateien in das übergeordnete Verzeichnis
import numpy as np
from common import layers
from collections import OrderedDict
from common import functions
from data.mnist import load_mnist
import matplotlib.pyplot as plt
from common import optimizer
class MultiLayerNet:
'''
input_size:Anzahl der Knoten in der Eingabeebene
hidden_size_list:Liste der Knoten versteckter Ebenen
output_size:Anzahl der Knoten in der Ausgabeschicht
activation:Aktivierungsfunktion
weight_init_std:So initialisieren Sie Gewichte
weight_decay_lambda:Stärke der L2-Regularisierung
use_dropout:Mit oder ohne Ausfall
dropout_ratio:Abbruchquote
use_batchnorm:Mit oder ohne Chargennormalisierung
'''
def __init__(self, input_size, hidden_size_list, output_size, activation='relu', weight_init_std='relu', weight_decay_lambda=0,
use_dropout = False, dropout_ratio = 0.5, use_batchnorm=False):
self.input_size = input_size
self.output_size = output_size
self.hidden_size_list = hidden_size_list
self.hidden_layer_num = len(hidden_size_list)
self.use_dropout = use_dropout
self.weight_decay_lambda = weight_decay_lambda
self.use_batchnorm = use_batchnorm
self.params = {}
#Gewichtsinitialisierung
self.__init_weight(weight_init_std)
#Schichterzeugung
activation_layer = {'sigmoid': layers.Sigmoid, 'relu': layers.Relu}
self.layers = OrderedDict()
for idx in range(1, self.hidden_layer_num+1):
self.layers['Affine' + str(idx)] = layers.Affine(self.params['W' + str(idx)], self.params['b' + str(idx)])
if self.use_batchnorm:
self.params['gamma' + str(idx)] = np.ones(hidden_size_list[idx-1])
self.params['beta' + str(idx)] = np.zeros(hidden_size_list[idx-1])
self.layers['BatchNorm' + str(idx)] = layers.BatchNormalization(self.params['gamma' + str(idx)], self.params['beta' + str(idx)])
self.layers['Activation_function' + str(idx)] = activation_layer[activation]()
if self.use_dropout:
self.layers['Dropout' + str(idx)] = layers.Dropout(dropout_ratio)
idx = self.hidden_layer_num + 1
self.layers['Affine' + str(idx)] = layers.Affine(self.params['W' + str(idx)], self.params['b' + str(idx)])
self.last_layer = layers.SoftmaxWithLoss()
def __init_weight(self, weight_init_std):
all_size_list = [self.input_size] + self.hidden_size_list + [self.output_size]
for idx in range(1, len(all_size_list)):
scale = weight_init_std
if str(weight_init_std).lower() in ('relu', 'he'):
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'):
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])
self.params['b' + str(idx)] = np.zeros(all_size_list[idx])
def predict(self, x, train_flg=False):
for key, layer in self.layers.items():
if "Dropout" in key or "BatchNorm" in key:
x = layer.forward(x, train_flg)
else:
x = layer.forward(x)
return x
def loss(self, x, d, train_flg=False):
y = self.predict(x, train_flg)
weight_decay = 0
for idx in range(1, self.hidden_layer_num + 2):
W = self.params['W' + str(idx)]
weight_decay += 0.5 * self.weight_decay_lambda * np.sum(W**2)
return self.last_layer.forward(y, d) + weight_decay
def accuracy(self, X, D):
Y = self.predict(X, train_flg=False)
Y = np.argmax(Y, axis=1)
if D.ndim != 1 : D = np.argmax(D, axis=1)
accuracy = np.sum(Y == D) / float(X.shape[0])
return accuracy
def gradient(self, x, d):
# forward
self.loss(x, d, train_flg=True)
# backward
dout = 1
dout = self.last_layer.backward(dout)
layers = list(self.layers.values())
layers.reverse()
for layer in layers:
dout = layer.backward(dout)
#Aufbau
grads = {}
for idx in range(1, self.hidden_layer_num+2):
grads['W' + str(idx)] = self.layers['Affine' + str(idx)].dW + self.weight_decay_lambda * self.params['W' + str(idx)]
grads['b' + str(idx)] = self.layers['Affine' + str(idx)].db
if self.use_batchnorm and idx != self.hidden_layer_num+1:
grads['gamma' + str(idx)] = self.layers['BatchNorm' + str(idx)].dgamma
grads['beta' + str(idx)] = self.layers['BatchNorm' + str(idx)].dbeta
return grads
#Batch-Regularisierungsschicht
class BatchNormalization:
'''
gamma:Skalenkoeffizient
beta:Versatz
momentum:Trägheit
running_mean:Durchschnittlich während des Tests zu verwenden
running_var:Verteilung während des Testens verwendet
'''
def __init__(self, gamma, beta, momentum=0.9, running_mean=None, running_var=None):
self.gamma = gamma
self.beta = beta
self.momentum = momentum
self.input_shape = None
self.running_mean = running_mean
self.running_var = running_var
#Zwischendaten, die rückwärts verwendet werden sollen
self.batch_size = None
self.xc = None
self.std = None
self.dgamma = None
self.dbeta = None
def forward(self, x, train_flg=True):
if self.running_mean is None:
N, D = x.shape
self.running_mean = np.zeros(D)
self.running_var = np.zeros(D)
if train_flg:
mu = x.mean(axis=0) #durchschnittlich
xc = x - mu #Mitte x
var = np.mean(xc**2, axis=0) #Verteilt
std = np.sqrt(var + 10e-7) #Skalierung
xn = xc / std
self.batch_size = x.shape[0]
self.xc = xc
self.xn = xn
self.std = std
self.running_mean = self.momentum * self.running_mean + (1-self.momentum) * mu #Gewichteter Durchschnitt der Durchschnittswerte
self.running_var = self.momentum * self.running_var + (1-self.momentum) * var #Gewichteter Durchschnitt der Varianzwerte
else:
xc = x - self.running_mean
xn = xc / ((np.sqrt(self.running_var + 10e-7)))
out = self.gamma * xn + self.beta
return out
def backward(self, dout):
dbeta = dout.sum(axis=0)
dgamma = np.sum(self.xn * dout, axis=0)
dxn = self.gamma * dout
dxc = dxn / self.std
dstd = -np.sum((dxn * self.xc) / (self.std * self.std), axis=0)
dvar = 0.5 * dstd / self.std
dxc += (2.0 / self.batch_size) * self.xc * dvar
dmu = np.sum(dxc, axis=0)
dx = dxc - dmu / self.batch_size
self.dgamma = dgamma
self.dbeta = dbeta
return dx
#Daten lesen
# (x_train, d_train), (x_test, d_test) = load_mnist(normalize=True, one_hot_label=True)
(x_train, d_train), (x_test, d_test) = load_mnist(normalize=True)
print('Datenlesung abgeschlossen')
activations = ['sigmoid', 'relu']
weight_init_stds = [0.01, 'Xavier', 'He']
use_batchnorms = [False, True]
iters_num = 2000
train_size = x_train.shape[0]
batch_size = 100
learning_rate = 0.1
plot_interval = 100
plot_idx = 0
for k in range(len(activations)):
for l in range(len(weight_init_stds)):
for m in range(len(use_batchnorms)):
network = MultiLayerNet(input_size=784, hidden_size_list=[40, 20], output_size=10, activation=activations[k], weight_init_std=weight_init_stds[l], use_batchnorm=use_batchnorms[m])
train_loss_list = []
accuracies_train = []
accuracies_test = []
lists = []
plot_idx = plot_idx + 1
for i in range(iters_num):
batch_mask = np.random.choice(train_size, batch_size)
x_batch = x_train[batch_mask]
d_batch = d_train[batch_mask]
#Steigung
grad = network.gradient(x_batch, d_batch)
for key in ('W1', 'W2', 'W3', 'b1', 'b2', 'b3'):
network.params[key] -= learning_rate * grad[key]
loss = network.loss(x_batch, d_batch)
train_loss_list.append(loss)
if (i + 1) % plot_interval == 0:
accr_test = network.accuracy(x_test, d_test)
accuracies_test.append(accr_test)
accr_train = network.accuracy(x_batch, d_batch)
accuracies_train.append(accr_train)
print('Generation: ' + str(i+1) + '.Richtige Antwortrate(Ausbildung) = ' + str(accr_train))
print(' : ' + str(i+1) + '.Richtige Antwortrate(Prüfung) = ' + str(accr_test))
lists = range(0, iters_num, plot_interval)
plt.rcParams['figure.figsize'] = (12.0, 10.0)
plt.subplot(4,3,plot_idx)
plt.plot(lists, accuracies_train, label='training set')
plt.plot(lists, accuracies_test, label='test set')
plt.legend(loc='lower right')
plt.title(activations[k] + ', ' + str(weight_init_stds[l]) + ',Chargennormalisierung' + str(use_batchnorms[m]) + ' (' + str(np.round(accuracies_test[-1],2)) + ')')
plt.xlabel('count')
plt.ylabel('accuracy')
plt.ylim(0, 1.0)
#Grafik anzeigen
plt.tight_layout()
# plt.suptitle('Vorhersagegenauigkeit, wenn die Anfangswerte der Aktivierungsfunktion und des Gewichts geändert werden', fontsize = 16)
plt.show()
Wenn der Wert der Lernrate groß ist, wird der optimale Wert nicht für immer erreicht und divergiert. Wenn der Wert der Lernrate klein ist, wird er nicht divergieren, aber wenn er zu klein ist, wird es einige Zeit dauern, bis er konvergiert, oder es wird schwierig sein, zum globalen lokalen optimalen Wert zu konvergieren.
--Schwung
[Vorteile der Dynamik]
Impulsgradient
#Steigung
grad = network.gradient(x_batch, d_batch)
if i == 0:
v = {}
for key in ('W1', 'W2', 'W3', 'b1', 'b2', 'b3'):
if i == 0:
v[key] = np.zeros_like(network.params[key])
v[key] = momentum * v[key] - learning_rate * grad[key]
network.params[key] += v[key]
loss = network.loss(x_batch, d_batch)
train_loss_list.append(loss)
[Vorteile von AdaGrad] ――Für Hänge mit leichten Hängen nähern Sie sich dem optimalen Wert.
AdaGrad-Gradient
#Steigung
grad = network.gradient(x_batch, d_batch)
if i == 0:
h = {}
for key in ('W1', 'W2', 'W3', 'b1', 'b2', 'b3'):
if i == 0:
h[key] = np.full_like(network.params[key], 1e-4)
else:
h[key] += np.square(grad[key])
network.params[key] -= learning_rate * grad[key] / (np.sqrt(h[key]))
loss = network.loss(x_batch, d_batch)
train_loss_list.append(loss)
[Vorteile von RMS Drop]
RMS Drop Gradient
#Steigung
grad = network.gradient(x_batch, d_batch)
if i == 0:
h = {}
for key in ('W1', 'W2', 'W3', 'b1', 'b2', 'b3'):
if i == 0:
h[key] = np.zeros_like(network.params[key])
h[key] *= decay_rate
h[key] += (1 - decay_rate) * np.square(grad[key])
network.params[key] -= learning_rate * grad[key] / (np.sqrt(h[key]) + 1e-7)
loss = network.loss(x_batch, d_batch)
train_loss_list.appen
[Vorteile von Adam]
Adams Gefälle
#Steigung
grad = network.gradient(x_batch, d_batch)
if i == 0:
m = {}
v = {}
learning_rate_t = learning_rate * np.sqrt(1.0 - beta2 ** (i + 1)) / (1.0 - beta1 ** (i + 1))
for key in ('W1', 'W2', 'W3', 'b1', 'b2', 'b3'):
if i == 0:
m[key] = np.zeros_like(network.params[key])
v[key] = np.zeros_like(network.params[key])
m[key] += (1 - beta1) * (grad[key] - m[key])
v[key] += (1 - beta2) * (grad[key] ** 2 - v[key])
network.params[key] -= learning_rate_t * m[key] / (np.sqrt(v[key]) + 1e-7)
loss = network.loss(x_batch, d_batch)
train_loss_list.append(loss)
Die Lernkurve weicht zwischen dem Testfehler und dem Trainingsfehler ab, und das Training ist auf eine bestimmte Trainingsprobe spezialisiert. Es gibt die folgenden Methoden, um Überlernen zu verhindern.
Verwenden Sie die L2-Norm: Ridge-Schätzung (Reduktionsschätzung ... Schätzen Sie den Parameter näher an 0)
Bestimmen Sie einen geeigneten Wert durch Gegenprüfung usw.
Verwenden Sie die L1-Norm: Lasso-Schätzung (der Operator für die geringste absolute Schrumpfung und Auswahl) (spärliche Schätzung ... einige Parameter werden auf genau 0 geschätzt)
Strafe proportional zur L1-Norm des Parameters
Viele Parameter werden zu 0, wenn $ \ lambda $ erhöht wird $ \ rightarrow $ Generiert ein spärliches Modell durch Variablenauswahl
Aussteigen Durch zufälliges Löschen und Trainieren von Knoten kann interpretiert werden, dass verschiedene Modelle trainiert werden, ohne die Datenmenge zu ändern.
Keine Regularisierung (Reproduktion von Überlernen)
(optimizer.SGD(learning_rate=0.01))
L2-Regularisierung
(learning_rate=0.01)
L1-Regularisierung
(learning_rate=0.1)
Aussteiger
(optimizer.SGD(learning_rate=0.01), weight_decay_lambda = 0.01)
(optimizer.Momentum(learning_rate=0.01, momentum=0.9), weight_decay_lambda = 0.01)
(optimizer.AdaGrad(learning_rate=0.01), weight_decay_lambda = 0.01)
(optimizer.Adam(learning_rate=0.01), weight_decay_lambda = 0.01)
Dropout + L1-Regularisierung
(dropout_ratio = 0.1, weight_decay_lambda=0.005)
--Vorspannen
--Schreiten
Wenn die Eingangsgröße W × H ist, ist die Filtergröße Fw × Fh, die Polsterung ist p, der Schritt ist s und die Ausgangsgröße der Faltungsschicht ist OW × OH, OW und OH werden durch die folgenden Gleichungen berechnet.
Nachteile einer vollständig verbundenen Schicht: Bei einem Bild handelt es sich um 3D-Daten von vertikal, horizontal und kanalförmig, die jedoch als 1D-Daten verarbeitet werden. Das heißt, die Beziehung zwischen jedem RGB-Kanal spiegelt sich nicht im Lernen wider.
AlexNet
Es heißt Alex Net nach dem Namen des Hauptautors der Zeitung, Alex Krizhevsky. Es besteht aus drei vollständig verbundenen Schichten, einschließlich einer fünfschichtigen Faltschicht und einer Poolschicht. Im Vergleich zu LeNet, einem CNN, das erstmals 1998 von Yann LeCun et al. Entwickelt wurde, weist es eine erheblich tiefere Struktur auf. Um ein Überlernen zu vermeiden, verwenden wir Aussetzer für die Ausgabe der vollständig verbundenen Schicht der Größe 4096.
Chainers AlexNet enthält den folgenden Code.
alex.py
import chainer
import chainer.functions as F
import chainer.links as L
class Alex(chainer.Chain):
"""Single-GPU AlexNet without partition toward the channel axis."""
insize = 227
def __init__(self):
super(Alex, self).__init__()
with self.init_scope():
self.conv1 = L.Convolution2D(None, 96, 11, stride=4)
self.conv2 = L.Convolution2D(None, 256, 5, pad=2)
self.conv3 = L.Convolution2D(None, 384, 3, pad=1)
self.conv4 = L.Convolution2D(None, 384, 3, pad=1)
self.conv5 = L.Convolution2D(None, 256, 3, pad=1)
self.fc6 = L.Linear(None, 4096)
self.fc7 = L.Linear(None, 4096)
self.fc8 = L.Linear(None, 1000)
def __call__(self, x, t):
h = F.max_pooling_2d(F.local_response_normalization(
F.relu(self.conv1(x))), 3, stride=2)
h = F.max_pooling_2d(F.local_response_normalization(
F.relu(self.conv2(h))), 3, stride=2)
h = F.relu(self.conv3(h))
h = F.relu(self.conv4(h))
h = F.max_pooling_2d(F.relu(self.conv5(h)), 3, stride=2)
h = F.dropout(F.relu(self.fc6(h)))
h = F.dropout(F.relu(self.fc7(h)))
h = self.fc8(h)
loss = F.softmax_cross_entropy(h, t)
chainer.report({'loss': loss, 'accuracy': F.accuracy(h, t)}, self)
return loss
Recommended Posts