Während ich "Deep Learning von Grund auf neu" lese (geschrieben von Yasuki Saito, veröffentlicht von O'Reilly Japan), werde ich die Websites notieren, auf die ich verwiesen habe. Teil 11 ←
In P243 wird erklärt, dass die Netzwerkdefinition deep_convnet.py im Ordner ch08 lautet, der Trainingscode train_deepnet.py lautet und der gelernte Gewichtungsparameter deep_conv_net_params.pkl lautet, der Gewichtungsparameter jedoch gelesen und die Testdaten gelesen werden. Das zu verarbeitende Programm ist misclassified_mnist.py.
Dieses Programm kann ausgeführt werden, indem JupyterNote im Ordner ch08 erstellt wird.
Wenn Sie versuchen, es im Basisverzeichnis auszuführen, müssen Sie den Speicherort und den Aufruf von deep_convert.py und deep_conv_net_params.pkl ändern.
Ausführungsergebnis von misclassified_mnist.py
Der Inhalt der DeepConvNet-Klasse wurde bisher nur erklärt, daher denke ich, dass es notwendig ist, den Inhalt erneut zu überprüfen.
damit,
Verwenden wir diese Klasse dieses Mal, um Kaggles Hunde- und Katzendatensatz zu verarbeiten.
Download von der folgenden Seite https://www.microsoft.com/en-us/download/details.aspx?id=54765
Bilder sind in den Ordnern Cat and Dog unter dem Ordner PetImages enthalten. Die Dateinamen sind Seriennummern von 0.jpg bis 12499.jpg. Dies bedeutet, dass für jeden Hund und jede Katze 12500 Bilder vorhanden sind. Die Bilder sind farbig und unterschiedlich groß. Wenn Sie 0.jpg dieses Bildes in einem NumPy-Array speichern und den Inhalt anzeigen
(375, 500, 3)
Es wird als dreidimensionales Array von (Höhe, Breite, Farbe) gespeichert. Die Farbe ist 0 für Rot, 1 für Grün und 2 für Blau. In Memo 6-2 wurde es in Graustufen konvertiert, diesmal jedoch in 3 Farben und 3 Datenkanäle.
Bilddaten sind in Kanal 3, Höhe 80 und Breite 80 angeordnet.
import os
import glob
from PIL import Image
import numpy as np
dataset_dir = os.path.dirname(os.path.abspath('__file__'))+'/dataset'
catfiles = glob.glob(dataset_dir + '/Cat/*.jpg')
dogfiles = glob.glob(dataset_dir + '/Dog/*.jpg')
fsize = 80
for f in catfiles:
try:
lblA = 0
pad_u, pad_d, pad_l, pad_r = 0,0,0,0
img = Image.open(f)
w,h=img.size
if w>h:
imgr = img.resize((fsize, int(h*fsize/w)))
wr,hr = imgr.size
pad_u = int((fsize - hr)/2)
pad_d = fsize - hr - pad_u
else:
imgr = img.resize((int(w*fsize/h),fsize))
wr,hr = imgr.size
pad_l = int((fsize - wr)/2)
pad_r = fsize - wr - pad_l
imgtr = np.array(imgr).transpose(2,0,1)
imgA = np.pad(imgtr, [(0, 0),(pad_u,pad_d),(pad_l,pad_r)], 'constant')
imgA = imgA.tolist()
except Exception as e:
print(f+" : " + str(e))
Informationen der von PIL gelesenen Bilddatei
img = Image.open(f)
print(img.format, img.size, img.mode)
JPEG (500, 375) RGB
Die Größe der Datei ist (Breite, Höhe). Das Konvertieren in ein Numpy-Array ergibt:
imgA = np.array(img)
print(imgA.size, imgA.shape)
562500 (375, 500, 3)
(Höhe, Breite, Farbe). Ändern Sie auf dieser Grundlage die Größe des Bilds auf 80 x 80 und tauschen Sie die Bemaßungsachsen aus, um ein Array mit Kanal 3, Höhe 80 und Breite 80 zu erstellen.
Wenn das obige Programm jedoch die Dateien im Ordner kontinuierlich verarbeitet, tritt dieser Fehler auf.
C:\Users\021133/dataset/Cat\10125.jpg : axes don't match array C:\Users\021133/dataset/Cat\10501.jpg : axes don't match array C:\Users\021133/dataset/Cat\1074.jpg : Python int too large to convert to C ssize_t C:\Users\021133/dataset/Cat\666.jpg : cannot identify image file
Anscheinend gibt es keine Dimensionsachse um die Transponierte (2,0,1). 1074.jpg ist auch ein Fehler, wenn es mit Memo 6-2 verarbeitet wird. Beim Lesen der Datei scheint ein Fehler aufgetreten zu sein. 666.jpg ist eine leere 0-Byte-Datei.
Wenn Sie sich 10125.jpg ansehen
img=Image.open(dataset_dir + '/10125.jpg')
print(img.format, img.size, img.mode)
imgA = np.array(img)
print(imgA.size, imgA.shape,imgA.ndim)
GIF (259, 346) P 89614 (346, 259) 2
Soweit ich im Viewer sehen kann, wird es problemlos als Farbbild angezeigt. Das Problem scheint im P-Paletten-Modus zu liegen. Also habe ich die Lesemethode geändert.
img=Image.open(dataset_dir + '/10501.jpg').convert('RGB')
print(img.format, img.size, img.mode)
imgA = np.array(img)
print(imgA.size, imgA.shape,imgA.ndim)
None (400, 299) RGB 358800 (299, 400, 3) 3
Anscheinend ist das in Ordnung.
Die Problemdatei CAt 1074.jpg 5127.jpg 666.jpg Dog 11702.jpg 829.jpg 8366.jpg wurde in einen anderen Ordner verschoben und die Testdaten auf 100 und die Trainingsdaten auf 4000 erhöht, um Speicherfehler zu vermeiden. Ich beschloss, es zu quetschen.
import os
import glob
import numpy as np
from PIL import Image
dataset_dir = os.path.dirname(os.path.abspath('__file__'))+'/dataset'
catfiles = glob.glob(dataset_dir + '/Cat/*.jpg')
dogfiles = glob.glob(dataset_dir + '/Dog/*.jpg')
fsize = 80
tsl = []
tsi = []
trl = []
tri = []
tst_count = 0
trn_count = 0
count = 0
for f in catfiles:
try:
lblA = 0
img = Image.open(f).convert('RGB')
w,h=img.size
pad_u, pad_d, pad_l, pad_r = 0,0,0,0
if w>h:
imgr = img.resize((fsize, int(h*fsize/w)))
wr,hr = imgr.size
pad_u = int((fsize - hr)/2)
pad_d = fsize - hr - pad_u
else:
imgr = img.resize((int(w*fsize/h),fsize))
wr,hr = imgr.size
pad_l = int((fsize - wr)/2)
pad_r = fsize - wr - pad_l
imgtr = np.array(imgr).transpose(2,0,1)
imgA = np.pad(imgtr, [(0, 0),(pad_u,pad_d),(pad_l,pad_r)], 'constant')
imgA = imgA.tolist()
except Exception as e:
print(f+" : " + str(e))
if count < 50:
tsl.append(lblA)
tsi.append(imgA)
tst_count += 1
elif count < 2050:
trl.append(lblA)
tri.append(imgA)
trn_count += 1
else:
break
count += 1
count = 0
for f in dogfiles:
try:
lblA = 1
img = Image.open(f).convert('RGB')
w,h=img.size
pad_u, pad_d, pad_l, pad_r = 0,0,0,0
if w>h:
imgr = img.resize((fsize, int(h*fsize/w)))
wr,hr = imgr.size
pad_u = int((fsize - hr)/2)
pad_d = fsize - hr - pad_u
else:
imgr = img.resize((int(w*fsize/h),fsize))
wr,hr = imgr.size
pad_l = int((fsize - wr)/2)
pad_r = fsize - wr - pad_l
imgtr = np.array(imgr).transpose(2,0,1)
imgA = np.pad(imgtr, [(0, 0),(pad_u,pad_d),(pad_l,pad_r)], 'constant')
imgA = imgA.tolist()
except Exception as e:
print(f+" : " + str(e))
if count < 50:
tsl.append(lblA)
tsi.append(imgA)
tst_count += 1
elif count < 2050:
trl.append(lblA)
tri.append(imgA)
trn_count += 1
else:
break
count += 1
dataset = {}
dataset['test_label'] = np.array(tsl, dtype=np.uint8)
dataset['test_img'] = np.array(tsi, dtype=np.uint8)
dataset['train_label'] = np.array(trl, dtype=np.uint8)
dataset['train_img'] = np.array(tri, dtype=np.uint8)
import pickle
save_file = dataset_dir + '/catdog.pkl'
with open(save_file, 'wb') as f:
pickle.dump(dataset, f, -1)
dataset['test_img'].shape
(100, 3, 80, 80)
dataset['train_img'].shape
(4000, 3, 80, 80)
Der Code für die DeepConvNet-Klasse befindet sich in deep_convnet.py im Ordner ch08, aber es scheint, dass es einen Teil gibt, der der Eingabe von (1,28,28) entspricht.
def __init__(self, input_dim=(1, 28, 28),
conv_param_1 = {'filter_num':16, 'filter_size':3, 'pad':1, 'stride':1},
conv_param_2 = {'filter_num':16, 'filter_size':3, 'pad':1, 'stride':1},
conv_param_3 = {'filter_num':32, 'filter_size':3, 'pad':1, 'stride':1},
conv_param_4 = {'filter_num':32, 'filter_size':3, 'pad':2, 'stride':1},
conv_param_5 = {'filter_num':64, 'filter_size':3, 'pad':1, 'stride':1},
conv_param_6 = {'filter_num':64, 'filter_size':3, 'pad':1, 'stride':1},
hidden_size=50, output_size=10):
input_dim = (1, 28, 28) ist natürlich, aber dies ist kein Problem, da Sie ihm einen anderen Wert als Parameter geben können. Das Problem ist die Größe des Gewichts W7.
#Gewichtsinitialisierung===========
#Wie viele Verbindungen hat jedes der Neuronen in jeder Schicht mit den Neuronen in der vorherigen Schicht (TODO)?:Automatisch berechnen)
pre_node_nums = np.array([1*3*3, 16*3*3, 16*3*3, 32*3*3, 32*3*3, 64*3*3, 64*4*4, hidden_size])
weight_init_scales = np.sqrt(2.0 / pre_node_nums) #Empfohlener Anfangswert bei Verwendung von ReLU
Hier können Sie den Kanal x Höhe x Breite des in jeder Ebene verwendeten Filters angeben. Dies geschieht jedoch, wenn die Eingabedaten (3,80,80) werden.
pre_node_nums = np.array([3*3*3, 16*3*3, 16*3*3, 32*3*3, 32*3*3, 64*3*3, 64*10*10, hidden_size])
Die Größe des Gewichts W7 war auch so,
self.params['W7'] = weight_init_scales[6] * np.random.randn(64*4*4, hidden_size)
Wenn Sie dies nicht ändern, funktioniert das Programm nicht.
self.params['W7'] = weight_init_scales[6] * np.random.randn(64*10*10, hidden_size)
Der Grund, warum es 10x10 ist, ist, dass es auf der Höhe x Breite der Eingabedaten basiert. Die Eingabedaten sind diesmal 80 x 80, aber wenn sie einmal in der Mitte durch die Poolebene laufen, sind sie halb so groß. In dieser Klassendefinition wird es dreimal übergeben, also 80 → 40 → 20 → 10. Der 4x4 des ursprünglichen Programms ist 28 → 14 → 7 → 4.
import sys, os
import pickle
import numpy as np
from common.functions import *
from common.optimizer import *
from deep_convnet import DeepConvNet
def to_one_hot(label):
t = np.zeros((label.size, 2))
for i in range(label.size):
t[i][label[i]] = 1
return t
dataset_dir = os.path.dirname(os.path.abspath('__file__'))+'/dataset'
mnist_file = dataset_dir + '/catdog.pkl'
with open(mnist_file, 'rb') as f:
dataset = pickle.load(f)
x_train = dataset['train_img']
t_train = to_one_hot(dataset['train_label'])
#Hyperparameter
iters_num = 30
train_size = x_train.shape[0]
batch_size = 12
learning_rate = 0.1
train_loss_list = []
network = DeepConvNet( input_dim=(3, 80, 80),
conv_param_1 = {'filter_num':16, 'filter_size':3, 'pad':1, 'stride':1},
conv_param_2 = {'filter_num':16, 'filter_size':3, 'pad':1, 'stride':1},
conv_param_3 = {'filter_num':32, 'filter_size':3, 'pad':1, 'stride':1},
conv_param_4 = {'filter_num':32, 'filter_size':3, 'pad':2, 'stride':1},
conv_param_5 = {'filter_num':64, 'filter_size':3, 'pad':1, 'stride':1},
conv_param_6 = {'filter_num':64, 'filter_size':3, 'pad':1, 'stride':1},
hidden_size=50, output_size=2)
optimizer = Adam(lr=learning_rate)
for i in range(iters_num):
#Holen Sie sich eine Mini-Charge
batch_mask = np.random.choice(train_size, batch_size)
x_batch = x_train[batch_mask]
t_batch = t_train[batch_mask]
#Gradientenberechnung
grads = network.gradient(x_batch, t_batch)
optimizer.update(network.params, grads)
#Aufzeichnung des Lernfortschritts
loss = network.loss(x_batch, t_batch)
train_loss_list.append(loss)
#Speichern Sie das Netzwerkobjekt mit pickle. Gespeicherte Objekte werden in der Inferenzverarbeitung verwendet
import pickle
save_file = dataset_dir + '/catdogA.pkl'
with open(save_file, 'wb') as f:
pickle.dump(network, f, -1)
Das Programm hat funktioniert, aber ich konnte es nicht wirklich lernen. Selbst wenn ich versuche zu schließen, erreicht die richtige Antwortrate nicht 50%. Ist es nicht falsch, dass die Anzahl der Daten, die in einem Stapel trainiert werden sollen, nur 12 beträgt? Wenn Sie es jedoch weiter verarbeiten, tritt ein Speicherfehler auf.
network.layers
[common.layers.Convolution at 0x3610030, common.layers.Relu at 0xbad8170, common.layers.Convolution at 0xbabf990, common.layers.Relu at 0xbabf870, common.layers.Pooling at 0xbabf950, common.layers.Convolution at 0xbabf430, common.layers.Relu at 0xbabf0f0, common.layers.Convolution at 0xbabf230, common.layers.Relu at 0xbabf570, common.layers.Pooling at 0xbabf130, common.layers.Convolution at 0xbabf4d0, common.layers.Relu at 0xbabf1f0, common.layers.Convolution at 0xbabf210, common.layers.Relu at 0xbabf190, common.layers.Pooling at 0xbabf9f0, common.layers.Affine at 0xbabf970, common.layers.Relu at 0xbabf270, common.layers.Dropout at 0xbabf9b0, common.layers.Affine at 0xbabf470, common.layers.Dropout at 0xbabf370]
print(x_batch.shape)
print(network.params['W1'].shape)
print(network.params['W2'].shape)
print(network.params['W3'].shape)
print(network.params['W4'].shape)
print(network.params['W5'].shape)
print(network.params['W6'].shape)
print(network.params['W7'].shape)
print(network.params['W8'].shape)
(12, 3, 80, 80) (16, 3, 3, 3) (16, 16, 3, 3) (32, 16, 3, 3) (32, 32, 3, 3) (64, 32, 3, 3) (64, 64, 3, 3) (6400, 50) (50, 2)
#Mit Testdaten auswerten
import numpy as np
import sys, os
import pickle
from deep_convnet import DeepConvNet
dataset_dir = os.path.dirname(os.path.abspath('__file__'))+'/dataset'
mnist_file = dataset_dir + '/catdog.pkl'
with open(mnist_file, 'rb') as f:
dataset = pickle.load(f)
x_test = dataset['test_img']
t_test = dataset['test_label']
test_size = 10
test_mask = np.random.choice(100, test_size)
x = x_test[test_mask]
t = t_test[test_mask]
#network = DeepConvNet()
weight_file = dataset_dir + '/catdogA.pkl'
with open(weight_file, 'rb') as f:
network = pickle.load(f)
y = network.predict(x)
accuracy_cnt = 0
for i in range(len(y)):
p= np.argmax(y[i])
if p == t[i]:
accuracy_cnt += 1
print("Accuracy:" + str(float(accuracy_cnt) / len(x)))
Accuracy:0.5
import matplotlib.pyplot as plt
class_names = ['cat', 'dog']
def showImg(x):
example = x.transpose(1,2,0)
plt.figure()
plt.xticks([])
plt.yticks([])
plt.grid(False)
plt.imshow(example, cmap=plt.cm.binary)
plt.show()
return
for i in range(test_size):
c = t[i]
print("Richtige Antwort" + str(c) + " " + class_names[c])
p = np.argmax(y[i])
v = y[p]
print("Beurteilung" + str(p) + " " + class_names[p] + " " + str(v) )
showImg(x[i])
Die Wahrscheinlichkeit des Beurteilungsergebnisses ist ein sehr kleiner Wert. Schließlich wurde es möglicherweise nicht normal verarbeitet. Es ist jedoch schwierig, den Test in einer Umgebung zu wiederholen, in der sofort ein Speicherfehler auftritt ...
Ich schaute auf den Inhalt des Gewichts
import numpy as np
import matplotlib.pyplot as plt
dataset_dir = os.path.dirname(os.path.abspath('__file__'))+'/dataset'
def filter_show(filters, nx=8, margin=3, scale=10):
"""
c.f. https://gist.github.com/aidiary/07d530d5e08011832b12#file-draw_weight-py
"""
FN, C, FH, FW = filters.shape
ny = int(np.ceil(FN / nx))
fig = plt.figure()
fig.subplots_adjust(left=0, right=1, bottom=0, top=1, hspace=0.05, wspace=0.05)
for i in range(FN):
ax = fig.add_subplot(ny, nx, i+1, xticks=[], yticks=[])
ax.imshow(filters[i][0], cmap=plt.cm.binary, interpolation='nearest')
plt.show()
#network = DeepConvNet()
weight_file = dataset_dir + '/catdogA.pkl'
with open(weight_file, 'rb') as f:
network = pickle.load(f)
filter_show(network.params['W1'])
W1
W2
Es sieht nicht so aus, als gäbe es ein Muster.
Teil 11 ←
Unterschied zwischen PIL- und L-Modus-Bildern von PIL
Recommended Posts