[밑바닥부터 시작하는 딥러닝] #2 MNIST, 신경망 구현

Clay Ryu's sound lab·2022년 3월 1일
0

Note for 2022

목록 보기
12/47
post-thumbnail

MNIST

MNIST 분류의 어려움


프로그래밍에는 사람이 직접 규칙을 정해주는 방식과
대용량의 데이터를 통해서 기계에 직접 학습을 시키는 방식 두가지가 있다.

전자의 경우 위 그림과 같은 손글씨를 분류하는게 굉장히 어렵다.

Flatten

28x28의 이미지를 784 크기의 벡터로 바꿔주어야 한다.
NN에 들어가는 이미지 인풋은 일렬로 늘어선 784차원의 벡터이다.

이미지의 차원

흑백의 이미지는 이미지의 개수 x width x height의 3차원 텐서이다.

참고) import 문을 통해 다른 파이썬 파일을 불러올 때, 파이썬은 내부적으로 파일을 찾기 위해 sys.path와 PYTHONPATH에 있는 경로를 탐색합니다.

이미지의 픽셀의 크기

unsigned integer는 수학적으로 modular로서 0~255값을 넘어가는 256의 값은 0으로 되돌리는 역할을 한다.
signed integer는 -128~127 사이의 값을 가진다.

코드 구현

MNIST 데이터의 이미지를 확인해보자.

plt.figure(figsize=(10,10))
for i in range(25):
    plt.subplot(5, 5, i+1)
    plt.xticks([])
    plt.yticks([])
    img = x_train[i].reshape(28,28)
    plt.imshow(img, cmap='gray')
    plt.xlabel(y_train[0])
    #plt.axis('off')
plt.show()

신경망 구현

입력 벡터의 차원은 784 출력 벡터의 차원은 10으로 고정이 된다.
다만 아직 손실함수를 통한 모델의 학습을 배우지 않았으므로
필자가 미리 학습 시켜놓은 가중치 값들을 불러와서
모델의 predict만을 해본다.

def predict(network, x):
    W1, W2, W3 = network['W1'], network['W2'], network['W3']
    b1, b2, b3 = network['b1'], network['b2'], network['b3']
    
    a1 = np.dot(x, W1) + b1
    z1 = sigmoid(a1)
    a2 = np.dot(z1, W2) + b2
    z2 = sigmoid(a2)
    a3 = np.dot(z2, W3) + b3
    y = softmax(a3)
    
    return y

구현된 모델은 hidden layer가 2개인(뉴런이 50, 100개) 모델이며 생김새는 다음과 같다.

배치(묶음) 처리

6만장을 한번에 읽는 것이 아니라 예를들면 100장씩 묶어서 읽는다.
이것이 가능해지는 것은 연산을 행렬로 바꿔서 처리할 수 있기 때문이다. 따라서 6만장을 한번에 처리하는 것보다 배치 처리를 해주는 것이 좀더 유리할 수 있다.

한장씩 처리

x, t = get_data()
net = init_network()

acc = 0
for i in range(len(x)):
    y = predict(net, x[i])
    if t[i] == np.argmax(y)
        acc += 1
acc = float(acc) / len(x)

100장씩 처리

x, t = get_data()
net = init_network()

batch_size = 100
acc = 0

for i in range(len(x)):
    x_batch = x[i:i+batch_size]
    y_batch = predict(net, x_batch)
    p = np.argmax(y_batch, axis=1)
    acc_mini = np.sum(t[i:i+batch_size]==p)
    acc += acc_mini
    
acc = float(acc) / len(x)

예측이 틀린 글씨 찾아보기

plt.figure(figsize=(10,10))
for i in range(25):
    plt.subplot(5,5, i+1)
    plt.xticks([])
    plt.yticks([])
    plt.imshow(x[error[i]].reshape(28,28), cmap='gray')
plt.show()

예측률을 지정하기

예측의 확신을 80프로 이상으로 지정하기

x, t = get_data()
net = init_network()

#batch_size = 100
acc = 0
for i in range(len(x)):
    y = predict(net, x[i])
    p = np.argmax(y)
    if (t[i] == p) & (y[p]>0.8):
        acc += 1
acc = float(acc) / len(x)

batch를 랜덤하게 하기

rand = np.random.choice(60000,25)
rand[0]

혼동행렬 만들기

x = x_test, t = y_test일때

for k in range(len(x)):
    i = int(t[k])
    y = predict(network, x[k])
    j = np.argmax(y)
    confusion[i][j] += 1
print(confusion)
profile
chords & code // harmony with structure

0개의 댓글