SimpleConvNet을 주피터에서 돌리기 - LOPES-HUFS/DeepLearningFromForR GitHub Wiki
아래 코드에서 필요한 클래스를 쥬피터에 미리 채워 넣고, simple_convnet_7.h5
을 폴더에 넣은 다음 돌리면 아래와 같이 돌아간다.
import numpy as np
import tensorflow as tf
from tensorflow import keras
import h5py
from keras.utils import np_utils
mnist = keras.datasets.mnist
(x_train, t_train), (x_test, t_test) = mnist.load_data()
x_train = x_train.reshape(x_train.shape[0], 1, 28, 28).astype('float64')
x_test = x_test.reshape(x_test.shape[0], 1, 28, 28).astype('float64')
x_train, x_test = x_train / 255.0, x_test / 255.0
x_train_100 = x_train[0:100,:,:,:]
#import numpy as np
nb_classes = 6
data = [2, 3, 4, 0](/LOPES-HUFS/DeepLearningFromForR/wiki/2,-3,-4,-0)
def indices_to_one_hot(data, nb_classes):
"""Convert an iterable of indices to one-hot encoded labels."""
targets = np.array(data).reshape(-1)
return np.eye(nb_classes)[targets]
t_train_100 = indices_to_one_hot(t_train[0:100], 10)
class SimpleConvNet:
"""単純なConvNet
conv - relu - pool - affine - relu - affine - softmax
Parameters
----------
input_size : 入力サイズ(MNISTの場合は784)
hidden_size_list : 隠れ層のニューロンの数のリスト(e.g. [100, 100, 100])
output_size : 出力サイズ(MNISTの場合は10)
activation : 'relu' or 'sigmoid'
weight_init_std : 重みの標準偏差を指定(e.g. 0.01)
'relu'または'he'を指定した場合は「Heの初期値」を設定
'sigmoid'または'xavier'を指定した場合は「Xavierの初期値」を設定
"""
def __init__(self, input_dim=(1, 28, 28),
conv_param={'filter_num':30, 'filter_size':5, 'pad':0, 'stride':1},
hidden_size=100, output_size=10, weight_init_std=0.01):
filter_num = conv_param['filter_num']
filter_size = conv_param['filter_size']
filter_pad = conv_param['pad']
filter_stride = conv_param['stride']
input_size = input_dim[1]
conv_output_size = (input_size - filter_size + 2*filter_pad) / filter_stride + 1
pool_output_size = int(filter_num * (conv_output_size/2) * (conv_output_size/2))
# 重みの初期化
hf = h5py.File('simple_convnet_7.h5', 'r')
hf.keys()
params['W1'] = hf.get('W1')
params['W1'] = np.array(params['W1'])
params['W2'] = hf.get('W2')
params['W2'] = np.array(params['W2'])
params['W3'] = hf.get('W3')
params['W3'] = np.array(params['W3'])
hf.close()
self.params = {}
self.params['W1'] = params['W1']
#self.params['W1'] = weight_init_std * \
# np.random.randn(filter_num, input_dim[0], filter_size, filter_size)
self.params['b1'] = np.zeros(filter_num)
#self.params['W2'] = weight_init_std * \
# np.random.randn(pool_output_size, hidden_size)
self.params['W2'] = params['W2']
self.params['b2'] = np.zeros(hidden_size)
#self.params['W3'] = weight_init_std * \
# np.random.randn(hidden_size, output_size)
self.params['W3'] = params['W3']
self.params['b3'] = np.zeros(output_size)
# レイヤの生成
self.layers = OrderedDict()
self.layers['Conv1'] = Convolution(self.params['W1'], self.params['b1'],
conv_param['stride'], conv_param['pad'])
self.layers['Relu1'] = Relu()
self.layers['Pool1'] = Pooling(pool_h=2, pool_w=2, stride=2)
self.layers['Affine1'] = Affine(self.params['W2'], self.params['b2'])
self.layers['Relu2'] = Relu()
self.layers['Affine2'] = Affine(self.params['W3'], self.params['b3'])
self.last_layer = SoftmaxWithLoss()
def predict(self, x):
for layer in self.layers.values():
x = layer.forward(x)
return x
def loss(self, x, t):
"""損失関数を求める
引数のxは入力データ、tは教師ラベル
"""
y = self.predict(x)
return self.last_layer.forward(y, t)
def accuracy(self, x, t, batch_size=100):
if t.ndim != 1 : t = np.argmax(t, axis=1)
acc = 0.0
for i in range(int(x.shape[0] / batch_size)):
tx = x[i*batch_size:(i+1)*batch_size]
tt = t[i*batch_size:(i+1)*batch_size]
y = self.predict(tx)
y = np.argmax(y, axis=1)
acc += np.sum(y == tt)
return acc / x.shape[0]
def numerical_gradient(self, x, t):
"""勾配を求める(数値微分)
Parameters
----------
x : 入力データ
t : 教師ラベル
Returns
-------
各層の勾配を持ったディクショナリ変数
grads['W1']、grads['W2']、...は各層の重み
grads['b1']、grads['b2']、...は各層のバイアス
"""
loss_w = lambda w: self.loss(x, t)
grads = {}
for idx in (1, 2, 3):
grads['W' + str(idx)] = numerical_gradient(loss_w, self.params['W' + str(idx)])
grads['b' + str(idx)] = numerical_gradient(loss_w, self.params['b' + str(idx)])
return grads
def gradient(self, x, t):
"""勾配を求める(誤差逆伝搬法)
Parameters
----------
x : 入力データ
t : 教師ラベル
Returns
-------
各層の勾配を持ったディクショナリ変数
grads['W1']、grads['W2']、...は各層の重み
grads['b1']、grads['b2']、...は各層のバイアス
"""
# forward
self.loss(x, t)
# backward
dout = 1
dout = self.last_layer.backward(dout)
layers = list(self.layers.values())
layers.reverse()
for layer in layers:
dout = layer.backward(dout)
# 設定
grads = {}
grads['W1'], grads['b1'] = self.layers['Conv1'].dW, self.layers['Conv1'].db
grads['W2'], grads['b2'] = self.layers['Affine1'].dW, self.layers['Affine1'].db
grads['W3'], grads['b3'] = self.layers['Affine2'].dW, self.layers['Affine2'].db
return grads
network = SimpleConvNet(input_dim=(1,28,28),
conv_param = {'filter_num': 30, 'filter_size': 5, 'pad': 0, 'stride': 1},
hidden_size=100, output_size=10, weight_init_std=0.01)
temp_network = network.gradient(x_train_100, t_train_100)
temp_network['b2']
array([ 1.13699712e-04, -4.29507837e-04, 4.71714423e-04, -7.16677820e-05,
-1.17173921e-05, 1.41251011e-04, 1.30049931e-03, -8.63587884e-05,
5.17859257e-04, 8.84411753e-04, 7.65561502e-04, 8.94050291e-05,
9.32573578e-05, 1.37477149e-03, 5.00705892e-04, 1.46325479e-04,
3.02025904e-04, -9.62641534e-04, -1.76420979e-03, -7.87698304e-04,
4.85357144e-05, -9.11073628e-04, 2.52054550e-04, -1.29024335e-03,
1.39014763e-04, 7.19705325e-04, -2.86479329e-05, -3.36708993e-05,
-1.40866207e-04, -8.35243862e-04, -5.86974021e-04, 7.69837622e-06,
6.47731337e-04, -3.21919105e-05, -1.62805397e-04, -1.24341778e-03,
5.65282352e-04, -6.14486575e-04, -6.67954021e-04, -4.99853321e-04,
9.78107945e-04, 1.96397320e-04, 1.72905028e-05, 1.06492456e-03,
3.81550800e-05, -2.29788199e-04, -3.39012663e-04, 1.62358373e-04,
2.28840405e-04, 9.14060899e-04, -7.77821848e-04, -7.74494830e-04,
-2.06424376e-04, -1.40858049e-04, 4.61756875e-04, -1.56278450e-03,
-1.84003721e-03, 4.64306361e-04, -2.18224066e-04, 9.65499452e-04,
8.92501212e-04, -6.29480291e-04, -2.22677129e-04, 1.17979308e-03,
1.61359668e-04, 1.04861107e-04, -8.77427823e-04, -4.16142822e-04,
-1.35221922e-03, 6.12461262e-04, 1.15719992e-04, 1.47491435e-04,
3.83007761e-04, -2.64106906e-04, -1.33239547e-05, 3.77785677e-05,
-2.39847186e-04, 0.00000000e+00, 5.92925946e-04, 6.40392804e-04,
8.56004223e-04, 5.39916724e-04, -2.73564848e-04, 0.00000000e+00,
9.71619074e-04, 3.09403995e-04, 3.90876323e-04, -1.58906367e-03,
2.13654319e-03, -1.08551966e-03, -5.27603802e-04, -1.44884157e-03,
-2.03661078e-03, 9.47791735e-04, 2.50277621e-04, 6.11453738e-05,
1.06337897e-04, -2.01938759e-03, -2.14810419e-04, -4.68517236e-04])