딥러닝 아키텍처


교재(머신러닝을 위한 파이썬 한 조각)의 257 페이지 내용을 텐서플로우 2.0 버전으로 구현할 것임.

deep learning architecture

Relu 함수 (은닉층)


Relu 함수는 x가 0보다 큰 경우에만 출력을 활성화한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import numpy as np
import matplotlib.pyplot as plt

def relu(x):
return np.maximum(0, x)

x = np.arange(-5.0, 5.1, 0.1)
y = relu(x)

plt.title('relu', fontsize=25)
plt.xlabel('x', fontsize=15)
plt.ylabel('y', fontsize=15, rotation=0)
plt.plot(x, y)
plt.axvline(0.0, color='grey', linestyle='--', alpha=0.8)
plt.show()

relu function

Softmax 함수 (출력층)


$\textrm{softmax}(Z_{i}) = \frac{e^{Z_{i}}}{\sum_{k=1}^{n}{e^{Z_{k}}}}$

softmax 함수는 모든 결과의 합이 1이되는 함수이다. 즉, 활성화 값이 확률을 나타낸다고 해석할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import numpy as np
import matplotlib.pyplot as plt

def softmax(z):
exp_z = np.exp(z)
return exp_z / np.sum(exp_z)

x = np.random.randn(5)
y = softmax(x)

plt.title('softmax', fontsize=25)
plt.ylabel('y', fontsize=15, rotation=0)
plt.pie(y, labels=y)
plt.show()

softmax

MNIST 손글씨 데이터 불러오기


1
2
3
4
5
6
7
8
9
10
11
12
13
from tensorflow.keras.datasets import mnist
import matplotlib.pyplot as plt

(x_train, t_train), (x_test, t_test) = mnist.load_data()
print(f'x_train.shape={x_train.shape}')
print(f'y_train.shape={t_train.shape}')
print(f'x_test.shape={x_test.shape}')
print(f'y_test.shape={t_test.shape}')

plt.figure()
plt.imshow(x_train[0], cmap=plt.cm.binary)
plt.colorbar()
plt.show()
1
2
3
4
x_train.shape=(60000, 28, 28)
y_train.shape=(60000,)
x_test.shape=(10000, 28, 28)
y_test.shape=(10000,)

mnist1

mnist의 손글씨 데이터는 0에서 255의 밝기를 갖고 있는 28x28 이미지이다.

학습용 데이터 6만개와 테스트용 데이터 1만개의 세트가 있다.

MNIST 정규화


$x_{new} = \frac{x-x_{min}}{x_{max}-x_{min}}$

예를 들어 0부터 255사이의 값을 정규화 한다면

$x_{max} = 255,\ x_{min} = 0$

$x_{new} = \frac{x}{255}$

1
2
3
4
5
6
7
8
9
10
11
12
from tensorflow.keras.datasets import mnist
import matplotlib.pyplot as plt

(x_train, t_train), (x_test, t_test) = mnist.load_data()

x_train = x_train / 255.
x_test = x_test / 255.

plt.figure()
plt.imshow(x_train[0], cmap=plt.cm.binary)
plt.colorbar()
plt.show()

mnist2

밝기의 값이 0에서 1사이로 정규화 되었다.

0에서 1사이로 정규화를 해야 cross-entropy 식에서 오버플로우가 발생하지 않는다.

손실 함수 선택


Classfication 문제의 손실 함수 종류

  • Binary Cross-Entropy Error

    • 정답 데이터가 0또는 1의 이진 값인 경우
  • Categorical Cross-Entropy Error

    • 정답 데이터가 one-hot encoding인 경우
  • Sparse Categorical Cross-Entropy Error

    • 정답 데이터가 정수인 경우

본 프로젝트에선 one-hot encoding으로 정답으로 치환하겠다.

one-hot encoding

0부터 9까지 총 10개의 분류 항목이 존재한다면

ex) 5 → [0, 0, 0, 0, 0, 1, 0, 0, 0, 0]

1
2
3
4
from tensorflow.keras.utils import to_categorical

t_train_categorical = to_categorical(t_train, 10)
t_test_categorical = to_categorical(t_test, 10)

Model 생성


1
2
3
4
5
6
7
8
9
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Flatten
from tensorflow.keras.layers import Dense

model = Sequential([
Flatten(input_shape=(28, 28)),
Dense(units=100, activation='relu'),
Dense(units=10, activation='softmax'),
])

모델 생성 단계는 신경망 계층을 구성하는 단계이다.

설계된 아키텍처에 맞춰 신경망 계층을 구성한다.

Model 컴파일


1
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

모델 컴파일 단계는 Hyper-Parameter나 손실 함수를 설정하고 신경망 계층이 구체화 되는 단계이다.

Tensorflow에 따르면, optimizer는 모델이 인식하는 데이터와 해당 손실 함수를 기반으로 모델이 업데이트되는 방식이다.

Adam Algorithm에 대한 정보는 공식 문서를 참고하라.

loss는 말그대로 손실 함수를 설정한다.

metrics은 학습 단계에서 학습에 대한 결과의 의미가 무엇인지 설정한다.

손글씨 분류의 ‘정확도’를 알고 싶은 것이므로 accuracy로 설정한다.

Model 학습


모델 학습 단계는 컴파일된 모델을 바탕으로 입력 데이터와 정답데이터를 이용해 손실율을 낮추는 것이다.

epochs는 전체 데이터셋을 몇 번 학습 시킬건지 설정한다.

batch_size는 한번 feed forward를 진행할때 몇 개의 데이터셋을 입력으로 넣을건지 설정한다.

1 epoch당 학습 횟수는 (전체 데이터셋 크기 / batch_size)가 된다.

1
model.fit(x_train, t_train_categorical, epochs=10, batch_size=100)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Epoch 1/10
600/600 [==============================] - 2s 3ms/step - loss: 0.3473 - accuracy: 0.9053
Epoch 2/10
600/600 [==============================] - 2s 3ms/step - loss: 0.1675 - accuracy: 0.9524
Epoch 3/10
600/600 [==============================] - 2s 3ms/step - loss: 0.1219 - accuracy: 0.9649
Epoch 4/10
600/600 [==============================] - 2s 3ms/step - loss: 0.0958 - accuracy: 0.9728
Epoch 5/10
600/600 [==============================] - 2s 3ms/step - loss: 0.0772 - accuracy: 0.9777
Epoch 6/10
600/600 [==============================] - 2s 3ms/step - loss: 0.0639 - accuracy: 0.9813
Epoch 7/10
600/600 [==============================] - 2s 3ms/step - loss: 0.0532 - accuracy: 0.9843
Epoch 8/10
600/600 [==============================] - 2s 3ms/step - loss: 0.0449 - accuracy: 0.9872
Epoch 9/10
600/600 [==============================] - 2s 3ms/step - loss: 0.0384 - accuracy: 0.9890
Epoch 10/10
600/600 [==============================] - 2s 3ms/step - loss: 0.0324 - accuracy: 0.9904
<keras.callbacks.History at 0x7f6f42307d10>

정확도 검증

1
2
3
test_loss, test_acc = model.evaluate(x_test,  t_test_categorical, verbose=2)

print('\nTest accuracy:', test_acc)
1
2
3
313/313 - 0s - loss: 0.0725 - accuracy: 0.9773 - 474ms/epoch - 2ms/step

Test accuracy: 0.9772999882698059

테스트 데이터를 이용해 정확도를 측정한다.

이 모델의 경우 테스트 데이터에서 약 98%의 정확도를 보인다.

예측하기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import numpy as np
import matplotlib.pyplot as plt

predictions = model.predict(x_test)

plt.figure(figsize=(6,3))

'''
image
'''
plt.subplot(1,2,1)
plt.imshow(x_test[0], cmap=plt.cm.binary)

'''
histogram
'''
plt.subplot(1,2,2)
plt.xticks(range(10))
plt.yticks(np.arange(0, 1.1, 0.1))
thisplot = plt.bar(range(10), predictions[0], color="#777777")
plt.ylim([0, 1])
predicted_label = np.argmax(predictions[0])
thisplot[predicted_label].set_color('red')

plt.show()

predictions

softmax 함수의 값 중 index=7의 값이 가장 높은 것을 알수 있다.

학습 코드 전문


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Flatten
from tensorflow.keras.layers import Dense
from tensorflow.keras.datasets import mnist
from tensorflow.keras.utils import to_categorical
import matplotlib.pyplot as plt

(x_train, t_train), (x_test, t_test) = mnist.load_data()

x_train = x_train / 255.
x_test = x_test / 255.

t_train_categorical = to_categorical(t_train, 10)
t_test_categorical = to_categorical(t_test, 10)

model = Sequential([
Flatten(input_shape=(28, 28)),
Dense(units=100, activation='relu'),
Dense(units=10, activation='softmax'),
])

model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

model.fit(x_train, t_train_categorical, epochs=10, batch_size=100)

test_loss, test_acc = model.evaluate(x_test, t_test_categorical, verbose=2)

print('\nTest accuracy:', test_acc)