[Deep Learning von Grund auf neu Die Theorie und Implementierung des mit Python erlernten Deep Learning](https://www.amazon.co.jp/%E3%82%BC%E3%83%AD%E3%81%8B%E3%] 82% 89% E4% BD% 9C% E3% 82% 8BDeep-Learning-Python% E3% 81% A7% E5% AD% A6% E3% 81% B6% E3% 83% 87% E3% 82% A3% E3% 83% BC% E3% 83% 97% E3% 83% A9% E3% 83% BC% E3% 83% 8B% E3% 83% B3% E3% 82% B0% E3% 81% AE% E7% 90% 86% E8% AB% 96% E3% 81% A8% E5% AE% 9F% E8% A3% 85-% E6% 96% 8E% E8% 97% A4-% E5% BA% B7% E6% AF% 85 / dp / 4873117585 / ref = sr_1_1? S = digitaler Text & dh = UTF8 & qid = 1483316946 & sr = 8-1 & keywords = tiefes + Lernen +% E3% 82% BC% E3% 83% AD% E3% 81% 8B% E3% 82% 89)
sigmoid function
from sigmoid import *
def sigmoid(x):
return 1 / (1 + np.exp(-x))
sigmoid(7)
0.9990889488055994
x = np.array([4,6,-2,-1, 2])
sigmoid(x)
array([ 0.98201379, 0.99752738, 0.11920292, 0.26894142, 0.88079708])
step function
from step_function import *
def step_function(x):
return np.array(x > 0, dtype=np.int)
step_function(5)
array(1)
step_function(-5)
array(0)
x = np.array([3,-6,4,-1])
step_function(x)
array([1, 0, 1, 0])
x = np.random.randn(2,3)
print(x)
print(step_function(x))
[[ 0.21780529 -0.05316613 1.28802155]
[-0.55119659 -1.23515555 0.6576237 ]]
[[1 0 1]
[0 0 1]]
ReLU function Rectified Linear Unit
Eine Funktion, die den Eingang so ausgibt, wie er ist, wenn der Eingang 0 überschreitet, und 0 ausgibt, wenn er 0 oder weniger ist.
from relu import *
def relu(x):
return np.maximum(0, x)
B = np.array([[1,2], [3,4], [5,6]]); B
array([[1, 2],
[3, 4],
[5, 6]])
np.ndim(B)
2
B.shape
(3, 2)
A = np.array([[3,2,1], [6,5,4]])
A.dot(B)
array([[14, 20],
[41, 56]])
x = np.array([1., .5])
W1 = np.array([[.1, .3, .5], [.2, .4, .6]])
B1 = np.array([.1, .2, .3])
print('Eingangssignal x=', x)
print('Gewicht W1=', W1)
print('Vorspannung B1=', B1)
Eingangssignal x = [1. 0.5] Gewicht W1 = [[0,1 0,3 0,5] [ 0.2 0.4 0.6]] Vorspannung B1 = [0,1 0,2 0,3]
x.shape, W1.shape
((2,), (2, 3))
Passen Sie die Anzahl der Elemente in den Abmessungen von x und W1 an!
A1 = np.dot(x, W1) + B1; A1
array([ 0.3, 0.7, 1.1])
Die gewichtete Summe (Summe aus gewichtetem Signal und Vorspannung) in der verborgenen Schicht wird durch $ a $ dargestellt.
Z1 = sigmoid(A1); Z1
array([ 0.57444252, 0.66818777, 0.75026011])
Das von der Aktivierungsfunktion konvertierte Signal wird durch $ z $ dargestellt.
Die Sigmoid-Funktion entspricht in der Abbildung $ h $ ().
W2 = np.array([[.1, .4], [.2, .5], [.3, .6]])
B2 = np.array([.1, .2])
print('W2=', W2)
print('B2=', B2)
W2= [[ 0.1 0.4]
[ 0.2 0.5]
[ 0.3 0.6]]
B2= [ 0.1 0.2]
A2 = np.dot(Z1, W2) + B2; A2
array([ 0.51615984, 1.21402696])
Z2 = sigmoid(A2); Z2
array([ 0.62624937, 0.7710107 ])
def identity_function(x):
"""Eine Funktion, die als Gleichheitsfunktion bezeichnet wird und die Eingabe so ausgibt, wie sie ist, und nichts tut"""
return x
W3 = np.array([[.1, .3], [.2, .4]])
B3 = np.array([.1, .2])
print('W3=', W3)
print('B3=', B3)
W3= [[ 0.1 0.3]
[ 0.2 0.4]]
B3= [ 0.1 0.2]
A3 = np.dot(Z2, W3) + B3
Y= identity_function(A3); Y
array([ 0.31682708, 0.69627909])
Verwenden Sie eine Funktion namens identity_function () als Aktivierungsfunktion für die Ausgabeschicht.
Die Aktivierungsfunktion der Ausgabeschicht wird durch $ \ sigma $ () dargestellt, was sich von der Aktivierungsfunktion der verborgenen Schicht $ h $ () unterscheidet.
def init_network():
"""Initialisierung von Gewicht und Bias"""
network = {}
network['W1'] = np.array([[.1, .3, .5], [.2, .4, .6]])
network['W2'] = np.array([[.1, .4], [.2, .5], [.3, .6]])
network['W3'] = np.array([[.1, .3], [.2, .4]])
network['b1'] = np.array([.1, .2, .3])
network['b2'] = np.array([.1, .2])
network['b3'] = np.array([.1, .2])
return network
def forward(network, x):
"""Der Prozess der Umwandlung eines Eingangssignals in einen Ausgang"""
W1, W2, W3 = network['W1'], network['W2'], network['W3']
b1, b2, b3 = network['b1'], network['b2'], network['b3']
#Eingabeebene
a1 = np.dot(x, W1) + b1
z1 = sigmoid(a1)
#Versteckte Ebene
a2 = np.dot(z1, W2) + b2
z2 = sigmoid(a2)
#Ausgabeschicht
a3 = np.dot(z2, W3) + b3
return identity_function(a3)
x
array([ 1. , 0.5])
network = init_network()
x = np.array([1., .5])
forward(network, x)
array([ 0.31682708, 0.69627909])
def softmax(a):
"""Gibt den Eingabewert a mit Wahrscheinlichkeit zurück"""
exp_a = np.exp(a - np.max(a)) #
return exp_a/ np.sum(exp_a)
softmax(np.array([.3, 2.9, 4.]))
array([ 0.01821127, 0.24519181, 0.73659691])
import os, sys
sys.path.append(os.pardir) #
from dataset.mnist import load_mnist
Wenn der Wert zu groß ist, wird er zu "inf" = "unendlich" (** Überlauf ** genannt) und trifft die Decke, was eine genaue Berechnung unmöglich macht. Konvertieren Sie daher $ e ^ a $ in einen kleineren Wert und dividieren Sie ihn durch den Gesamtwert, sodass sie wie unten gezeigt mathematisch äquivalent sind. Was ich oben erkläre, ist, dass sich der Wert von $ y_k $ nicht ändert, egal welchen Wert Sie zu $ e ^ {a_k} $ hinzufügen, wenn Sie denselben Nenner hinzufügen. Extrahieren des Datensatzes Wenn das Anhängen des übergeordneten Verzeichnisses ausgeführt wird, wird der mnist-Datensatz als GZ-Datei heruntergeladen, entpackt und dann in der pkl-Datei gespeichert.
Es dauert einige Minuten, bis der Vorgang abgeschlossen ist.
(x_train, t_train), (x_test, t_test) = load_mnist(flatten=True, normalize=False)
ソースはch03.mnist_show.py
Das Bild wird im BMP-Format angezeigt.
# %load mnist_show.py
import sys, os
sys.path.append(os.pardir) #Einstellungen zum Importieren von Dateien in das übergeordnete Verzeichnis
import numpy as np
from dataset.mnist import load_mnist
from PIL import Image
def img_show(img):
pil_img = Image.fromarray(np.uint8(img))
pil_img.show()
(x_train, t_train), (x_test, t_test) = load_mnist(flatten=True, normalize=False)
img = x_train[0]
label = t_train[0]
print(label) # 5
print(img.shape) # (784,)
img = img.reshape(28, 28) #Transformieren Sie die Form in die ursprüngliche Bildgröße
print(img.shape) # (28, 28)
img_show(img)
5
(784,)
(28, 28)
# %load neuralnet_mnist.py
import sys, os
sys.path.append(os.pardir) #Einstellungen zum Importieren von Dateien in das übergeordnete Verzeichnis
import numpy as np
import pickle
from dataset.mnist import load_mnist
from common.functions import sigmoid, softmax
def get_data():
"""Trainingsdaten laden"""
(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, flatten=True, one_hot_label=False)
return x_test, t_test
def init_network():
"""sample_weight.Laden der in pkl gespeicherten gelernten Gewichtsparameter"""
with open("sample_weight.pkl", 'rb') as f:
network = pickle.load(f)
return network
def predict(network, x):
"""Implementierung eines neuronalen Netzwerks
Die Ausgabeschicht ist keine gleiche Funktion
Es ist eine Softmax-Funktion."""
W1, W2, W3 = network['W1'], network['W2'], network['W3']
b1, b2, b3 = network['b1'], network['b2'], network['b3']
a1 = np.dot(x, W1) + b1
z1 = sigmoid(a1)
a2 = np.dot(z1, W2) + b2
z2 = sigmoid(a2)
a3 = np.dot(z2, W3) + b3
y = softmax(a3)
return y
%%timeit
x, t = get_data()
network = init_network()
accuracy_cnt = 0
for i in range(len(x)):
y = predict(network, x[i])
p= np.argmax(y) #Holen Sie sich den Index des wahrscheinlichsten Elements
if p == t[i]:
accuracy_cnt += 1
print("Accuracy:" + str(float(accuracy_cnt) / len(x)))
Accuracy:0.9352
Accuracy:0.9352
Accuracy:0.9352
Accuracy:0.9352
1 loop, best of 3: 1.25 s per loop
Übergang der Arrayform in der Stapelverarbeitung
Die Verarbeitungszeit pro Blatt kann verkürzt werden, indem die Belastung des Busbandes verringert wird, dh durch Stapelverarbeitung, bei der das Verhältnis von Operationen zu Datenlesen erhöht wird.
Das Lesen eines großen Arrays und das gleichzeitige Berechnen eines großen Arrays beendet den Vorgang schneller als das schrittweise Berechnen eines kleinen geteilten Arrays.
%%timeit
# %load neuralnet_mnist_batch.py
x, t = get_data()
network = init_network()
batch_size = 100 #Anzahl der Chargen
accuracy_cnt = 0
for i in range(0, len(x), batch_size):
x_batch = x[i:i+batch_size]
y_batch = predict(network, x_batch)
p = np.argmax(y_batch, axis=1)
accuracy_cnt += np.sum(p == t[i:i+batch_size])
print("Accuracy:" + str(float(accuracy_cnt) / len(x)))
Accuracy:0.9352
Accuracy:0.9352
Accuracy:0.9352
Accuracy:0.9352
1 loop, best of 3: 269 ms per loop
Es konnte durch Stapelverarbeitung etwa fünfmal schneller ausgeführt werden.