リンク
今回は、ゼロから作るDeep Learningのサンプルプログラムを用いて
cifar10(データファイル)をcnn(畳み込みニューラルネット)で学習していきたいです!!
僕の環境
python 3.6.5
chainer v4.2.0
windows 7(研究室のよさげなパソコンを借りてる)
1.まずはサンプルプログラムの入手
GitHub - oreilly-japan/deep-learning-from-scratch: 『ゼロから作る Deep Learning』のリポジトリ
このサイトから入手できます。
緑色でClone or downloadって書いてあるボタンを押すと
全部ダウンロードできるはずです
欲しいのは
・ch07
・ch08(なくていい)
・common
の三つです。
2.cifar10のデータセットを
入手
CIFAR-10 and CIFAR-100 datasets
このサイトのCIFAR-10 python versionをダウンロードしてください。
解凍すると
cifar-10-batches-pyというフォルダがあるので
deep-learning-from-scratch-masterの中のch7のフォルダに新規にDataというフォルダを作ってそこにぶち込んでください。
3.プログラムを書き換える
書き換える必要のあるファイルは
フォルダch7にあるtrain_convnet.py
上から11行目の
(x_train, t_train), (x_test, t_test) = load_mnist(flatten=False)
を
from datetime import datetime
import time
import _pickle as cPickle
import numpy as np
import os
def unpickle(file):
fo = open(file, 'rb')
dict = cPickle.load(fo,encoding='bytes')
fo.close()
return dict
def conv_data2image(data):
return np.rollaxis(data.reshape((3,32,32)),0,3)
def get_cifar10(folder):
tr_data = np.empty((0,32*32*3))
tr_labels = np.empty(1)
'''
32x32x3
'''
for i in range(1,6):
fname = os.path.join(folder, "%s%d" % ("data_batch_", i))
data_dict = unpickle(fname)
if i == 1:
tr_data = data_dict[b'data']
tr_labels = data_dict[b'labels']
else:
tr_data = np.vstack((tr_data, data_dict[b'data']))
tr_labels = np.hstack((tr_labels, data_dict[b'labels']))
data_dict = unpickle(os.path.join(folder, 'test_batch'))
te_data = data_dict[b'data']
te_labels = np.array(data_dict[b'labels'])
bm = unpickle(os.path.join(folder, 'batches.meta'))
label_names = bm[b'label_names']
tr_data = tr_data.reshape(tr_data.shape[0], 3, 32, 32)
te_data = te_data.reshape(te_data.shape[0], 3, 32, 32)
return tr_data, tr_labels, te_data, te_labels, label_names
if __name__ == '__main__':
datapath = "./data/cifar-10-batches-py"
tr_data10, tr_labels10, te_data10, te_labels10, label_names10 = get_cifar10(datapath)
x_train = tr_data10/255.0
t_train = tr_labels10.astype(np.int32)
x_test = te_data10/255.0
t_test = te_labels10.astype(np.int32)
x_train = x_train.astype(np.float32)
x_test =x_test.astype(np.float32)
に書き換える。(最後に全部書き換えたやつをのせます)
あとはministのデータは(1.28.28)の大きさで
cifar10は(3.32.32)なので
1.28.28を3.32.32と書き直して終了。
commonフォルダのtrainer.pyの
49行目の if self.verbose: print("train loss:" + str(loss))
の前に#をつけてコメント文に変えることをおすすめします。
これで6割りぐらい正答します。
ch8のほうが計算量が多いのでそちらでも同じように実装すると
7割ぐらいは正答するようになります。
train_convnet.py
import sys, os
sys.path.append(os.pardir)
import numpy as np
import matplotlib.pyplot as plt
from simple_convnet import SimpleConvNet
from common.trainer import Trainer
import _pickle as cPickle
import numpy as np
import os
def unpickle(file):
fo = open(file, 'rb')
dict = cPickle.load(fo,encoding='bytes')
fo.close()
return dict
def conv_data2image(data):
return np.rollaxis(data.reshape((3,32,32)),0,3)
def get_cifar10(folder):
tr_data = np.empty((0,32*32*3))
tr_labels = np.empty(1)
'''
32x32x3
'''
for i in range(1,6):
fname = os.path.join(folder, "%s%d" % ("data_batch_", i))
data_dict = unpickle(fname)
if i == 1:
tr_data = data_dict[b'data']
tr_labels = data_dict[b'labels']
else:
tr_data = np.vstack((tr_data, data_dict[b'data']))
tr_labels = np.hstack((tr_labels, data_dict[b'labels']))
data_dict = unpickle(os.path.join(folder, 'test_batch'))
te_data = data_dict[b'data']
te_labels = np.array(data_dict[b'labels'])
bm = unpickle(os.path.join(folder, 'batches.meta'))
label_names = bm[b'label_names']
tr_data = tr_data.reshape(tr_data.shape[0], 3, 32, 32)
te_data = te_data.reshape(te_data.shape[0], 3, 32, 32)
return tr_data, tr_labels, te_data, te_labels, label_names
if __name__ == '__main__':
datapath = "./data/cifar-10-batches-py"
tr_data10, tr_labels10, te_data10, te_labels10, label_names10 = get_cifar10(datapath)
x_train = tr_data10/255.0
t_train = tr_labels10.astype(np.int32)
x_test = te_data10/255.0
t_test = te_labels10.astype(np.int32)
x_train = x_train.astype(np.float32)
x_test =x_test.astype(np.float32)
max_epochs = 20
network = SimpleConvNet(input_dim=(3,32,32),
conv_param = {'filter_num': 30, 'filter_size': 5, 'pad': 0, 'stride': 1},
hidden_size=100, output_size=10, weight_init_std=0.01)
trainer = Trainer(network, x_train, t_train, x_test, t_test,
epochs=max_epochs, mini_batch_size=100,
optimizer='Adam', optimizer_param={'lr': 0.001},
evaluate_sample_num_per_epoch=1000)
trainer.train()
network.save_params("params.pkl")
print("Saved Network Parameters!")
markers = {'train': 'o', 'test': 's'}
x = np.arange(max_epochs)
plt.plot(x, trainer.train_acc_list, marker='o', label='train', markevery=2)
plt.plot(x, trainer.test_acc_list, marker='s', label='test', markevery=2)
plt.xlabel("epochs")
plt.ylabel("accuracy")
plt.ylim(0, 1.0)
plt.legend(loc='lower right')
plt.show()
commonの
trainer.py
import sys, os
sys.path.append(os.pardir)
import numpy as np
from common.optimizer import *
class Trainer:
"""ニューラルネットの訓練を行うクラス
"""
def __init__(self, network, x_train, t_train, x_test, t_test,
epochs=20, mini_batch_size=100,
optimizer='SGD', optimizer_param={'lr':0.01},
evaluate_sample_num_per_epoch=None, verbose=True):
self.network = network
self.verbose = verbose
self.x_train = x_train
self.t_train = t_train
self.x_test = x_test
self.t_test = t_test
self.epochs = epochs
self.batch_size = mini_batch_size
self.evaluate_sample_num_per_epoch = evaluate_sample_num_per_epoch
optimizer_class_dict = {'sgd':SGD, 'momentum':Momentum, 'nesterov':Nesterov,
'adagrad':AdaGrad, 'rmsprpo':RMSprop, 'adam':Adam}
self.optimizer = optimizer_class_dict[optimizer.lower()](**optimizer_param)
self.train_size = x_train.shape[0]
self.iter_per_epoch = max(self.train_size / mini_batch_size, 1)
self.max_iter = int(epochs * self.iter_per_epoch)
self.current_iter = 0
self.current_epoch = 0
self.train_loss_list = []
self.train_acc_list = []
self.test_acc_list = []
def train_step(self):
batch_mask = np.random.choice(self.train_size, self.batch_size)
x_batch = self.x_train[batch_mask]
t_batch = self.t_train[batch_mask]
grads = self.network.gradient(x_batch, t_batch)
self.optimizer.update(self.network.params, grads)
loss = self.network.loss(x_batch, t_batch)
self.train_loss_list.append(loss)
if self.current_iter % self.iter_per_epoch == 0:
self.current_epoch += 1
x_train_sample, t_train_sample = self.x_train, self.t_train
x_test_sample, t_test_sample = self.x_test, self.t_test
if not self.evaluate_sample_num_per_epoch is None:
t = self.evaluate_sample_num_per_epoch
x_train_sample, t_train_sample = self.x_train[:t], self.t_train[:t]
x_test_sample, t_test_sample = self.x_test[:t], self.t_test[:t]
train_acc = self.network.accuracy(x_train_sample, t_train_sample)
test_acc = self.network.accuracy(x_test_sample, t_test_sample)
self.train_acc_list.append(train_acc)
self.test_acc_list.append(test_acc)
if self.verbose: print("=== epoch:" + str(self.current_epoch) + ", train acc:" + str(train_acc) + ", test acc:" + str(test_acc) + " ===")
self.current_iter += 1
def train(self):
for i in range(self.max_iter):
self.train_step()
test_acc = self.network.accuracy(self.x_test, self.t_test)
if self.verbose:
print("=============== Final Test Accuracy ===============")
print("test acc:" + str(test_acc)
ここのぶろぐも参考にしました
http://msyksphinz.hatenablog.com/entry/2018/03/11/092428
http://sssiii.seesaa.net/article/452359119.html