Le réseau neuronal proposé dans l'article ci-dessous. Performances optimales dans ILSVRC 2012. Après cela, un réseau appelé VGG de l'Université d'Oxford, qui a approfondi AlexNet, est apparu et les performances ont été améliorées. (À partir de 2016, il y a GoogLeNet qui dépasse encore plus les performances. Il semble qu'il soit plus précis que les humains.)
↓ Il existe également un échantillon de Chainer.
Cette fois, j'ai écrit une version dégradée du réseau d'AlexNet et classifié les images. La raison de la détérioration est simplement de réduire le nombre de dimensions du réseau afin de résoudre le manque de mémoire.
Le réseau créé cette fois est le suivant.
class cnn(Chain):
def __init__(self):
super(cnn, self).__init__(
conv1=L.Convolution2D(3, 48, 3, stride=1),
bn1=L.BatchNormalization(48),
conv2=L.Convolution2D(48, 128, 3, pad=1),
bn2=L.BatchNormalization(128),
conv3=L.Convolution2D(128, 192, 3, pad=1),
conv4=L.Convolution2D(192, 192, 3, pad=1),
conv5=L.Convolution2D(192, 128, 3, pad=1),
fc6=L.Linear(2048, 1024),
fc7=L.Linear(1024, 1024),
fc8=L.Linear(1024, 10),
)
self.train = True
def clear(self):
self.loss = None
self.accuracy = None
def forward(self, x_data, t_data):
self.clear()
x, t = chainer.Variable(x_data, volatile=False), chainer.Variable(t_data, volatile=False)
h = self.bn1(self.conv1(x), test=not self.train)
h = F.max_pooling_2d(F.relu(h), 3, stride=2)
h = self.bn2(self.conv2(h), test=not self.train)
h = F.max_pooling_2d(F.relu(h), 3, stride=2)
h = F.relu(self.conv3(h))
h = F.relu(self.conv4(h))
h = F.relu(self.conv5(h))
h = F.max_pooling_2d(F.relu(h), 2, stride=2)
h = F.dropout(F.relu(self.fc6(h)), train=self.train)
h = F.dropout(F.relu(self.fc7(h)), train=self.train)
h = self.fc8(h)
self.loss = F.softmax_cross_entropy(h, t)
self.accuracy = F.accuracy(h, t)
if self.train:
return self.loss, self.accuracy
else:
return h.data, self.accuracy
Comme vous pouvez le voir en le comparant avec l'échantillon Chainer, le nombre de noyaux et la taille du filtre sont réduits.
J'ai utilisé l'ensemble de données CIFAR-10 dans ↓.
Il s'agit d'un ensemble de données avec 6000 images de 10 classes telles que des avions et des animaux par classe. La taille d'une image est de 32 $ \ fois 32 $ et elle dispose de 3 canaux RVB. Gentiment, il existe également un exemple qui lit les données avec python et les stocke dans un tableau. Cependant, la structure des données lues par cette méthode est telle que les premiers éléments $ 1024 (= 32 \ fois 32) $ sont R, le prochain $ 1024 $ est G et le prochain $ 1024 $ est B, donc Chianer Il doit être converti en une forme lisible par la fonction Convolution2D ()
de.
Je l'ai converti comme suit en référence au site suivant.
x_train = x_train.reshape((len(x_train), 3, 32, 32))
En outre, sur le total de 60000 $ feuilles dans la classe $ 6000 $ feuilles $ \ fois 10 $, cette fois-ci, 10000 $ feuilles ont été utilisées comme données d'entraînement et 10000 $ feuilles ont été utilisées comme données de test. L'augmentation du nombre de données d'entraînement améliorera la précision.
Le résultat lorsque la boucle d'apprentissage est tournée de 20 époques. La précision était d'environ 56%.
!/usr/bin/env python
-*- coding: utf-8 -*-
__version__ = '0.0.1'
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
import re
import logging
logger = logging.getLogger(__name__)
handler = logging.StreamHandler()
logger.setLevel(logging.DEBUG)
logger.addHandler(handler)
import pprint
def pp(obj):
pp = pprint.PrettyPrinter(indent=1, width=160)
str = pp.pformat(obj)
print re.sub(r"\\u([0-9a-f]{4})", lambda x: unichr(int("0x"+x.group(1),16)), str)
import os, math, time
import numpy as np
import cPickle as pickle
import copy
import chainer
from chainer import cuda, Function, gradient_check, Variable, optimizers, serializers, utils, Link, Chain, ChainList
import chainer.functions as F
import chainer.links as L
import subprocess
def unpickle(f):
import cPickle
fo = open(f, 'rb')
d = cPickle.load(fo)
fo.close()
return d
def load_cifar10(datadir, n_batch):
train_data = []
train_target = []
if n_batch > 5:
return -1
# load train data
for i in range(1, n_batch+1):
d = unpickle("%s/data_batch_%d" % (datadir, i))
train_data.extend(d["data"])
train_target.extend(d["labels"])
# load test data
d = unpickle("%s/test_batch" % (datadir))
test_data = d["data"]
test_target = d["labels"]
train_data = np.array(train_data, dtype=np.float32)
train_target = np.array(train_target, dtype=np.int32)
test_data = np.array(test_data, dtype=np.float32)
test_target = np.array(test_target, dtype=np.int32)
# normalization
train_data /= 255.0
test_data /= 255.0
return train_data, test_data, train_target, test_target
"""
CNN with Batch-Normalization
"""
class cnn(Chain):
def __init__(self):
super(cnn, self).__init__(
conv1=L.Convolution2D(3, 48, 3, stride=1),
bn1=L.BatchNormalization(48),
conv2=L.Convolution2D(48, 128, 3, pad=1),
bn2=L.BatchNormalization(128),
conv3=L.Convolution2D(128, 192, 3, pad=1),
conv4=L.Convolution2D(192, 192, 3, pad=1),
conv5=L.Convolution2D(192, 128, 3, pad=1),
fc6=L.Linear(2048, 1024),
fc7=L.Linear(1024, 1024),
fc8=L.Linear(1024, 10),
)
self.train = True
def clear(self):
self.loss = None
self.accuracy = None
def forward(self, x_data, t_data):
self.clear()
x, t = chainer.Variable(x_data, volatile=False), chainer.Variable(t_data, volatile=False)
h = self.bn1(self.conv1(x), test=not self.train)
h = F.max_pooling_2d(F.relu(h), 3, stride=2)
h = self.bn2(self.conv2(h), test=not self.train)
h = F.max_pooling_2d(F.relu(h), 3, stride=2)
h = F.relu(self.conv3(h))
h = F.relu(self.conv4(h))
h = F.relu(self.conv5(h))
h = F.max_pooling_2d(F.relu(h), 2, stride=2)
h = F.dropout(F.relu(self.fc6(h)), train=self.train)
h = F.dropout(F.relu(self.fc7(h)), train=self.train)
h = self.fc8(h)
self.loss = F.softmax_cross_entropy(h, t)
self.accuracy = F.accuracy(h, t)
if self.train:
return self.loss, self.accuracy
else:
return h.data, self.accuracy
if __name__ == '__main__':
from argparse import ArgumentParser
parser = ArgumentParser(description='RAE')
parser.add_argument('--data_dir', type=unicode, default='', help='directory path to the cifar10 data')
parser.add_argument('--n_data', type=int, default=1, help='# of data')
parser.add_argument('--n_epoch', type=int, default=20, help='# of epochs')
parser.add_argument('--batchsize', type=int, default=1, help='size of mini-batch')
parser.add_argument('--gpu', type=int, default=-1, help='GPU ID (negative value indicates CPU)')
args = parser.parse_args()
"""
Get params
"""
# the number of training itaration
n_epoch = args.n_epoch
# the size of mini batch
batchsize = args.batchsize
# define cupy
xp = cuda.cupy if args.gpu >= 0 else np
"""
Load data
"""
print 'load CIFAR-10 dataset'
x_train, x_test, y_train, y_test = load_cifar10(args.data_dir, args.n_data)
N_train = y_train.size
N_test = y_test.size
print N_train, N_test
x_train = x_train.reshape((len(x_train), 3, 32, 32))
x_test = x_test.reshape((len(x_test), 3, 32, 32))
"""
Prepare Acnn model
"""
model = cnn()
"""
Setup optimizer
"""
optimizer = optimizers.SGD()
optimizer.setup(model)
"""
Setup GPU
"""
if args.gpu >= 0:
cuda.get_device(args.gpu).use()
model.to_gpu()
"""
Training Loop
"""
for epoch in range(1, n_epoch + 1):
print "epoch: %d" % epoch
perm = np.random.permutation(N_train)
sum_loss = 0
for i in range(0, N_train, batchsize):
x_batch = xp.asarray(x_train[perm[i:i + batchsize]])
y_batch = xp.asarray(y_train[perm[i:i + batchsize]])
optimizer.zero_grads()
loss, acc = model.forward(x_batch, y_batch)
loss.backward()
optimizer.update()
sum_loss += float(loss.data) * len(y_batch)
print "train mean loss: %f" % (sum_loss / N_train)
sum_accuracy = 0
for i in range(0, N_test, batchsize):
x_batch = xp.asarray(x_test[i:i + batchsize])
y_batch = xp.asarray(y_test[i:i + batchsize])
loss, acc = model.forward(x_batch, y_batch)
sum_accuracy += float(acc.data) * len(y_batch)
print "test accuracy: %f" % (sum_accuracy / N_test)
Étudiez en profondeur l'apprentissage en profondeur [DW Day 0]