3.4 다층 퍼셉트론으로 MNIST 분류하기

유명곤·2026년 9월 27일

다층 퍼셉트론으로 손글씨를 분류할 때는 픽셀 값에서 중간 특성을 만들고, 그 특성으로 숫자별 점수를 계산한다. 은닉층의 가중치도 정답과 비교한 손실을 통해 함께 학습된다.

2.5 소프트맥스 회귀의 MNIST 분류기에 은닉층을 추가하면 무엇이 달라지는지 살펴본다. 학습에 필요한 기울기는 3.3 역전파에서 설명한 방법으로 구한다.

픽셀에서 중간 특성 만들기

MNIST는 0~9의 손글씨 숫자를 담은 데이터셋이다. 한 장은 28×28픽셀의 흑백 이미지이므로, 픽셀을 순서대로 나열하면 784개의 입력값이 된다. 이 절에서는 OpenML에서 이미 펼쳐진 데이터를 읽고, 밝기 값을 255로 나누어 0~1 범위로 바꾼다.

다층 퍼셉트론(Multilayer perceptron, MLP)은 입력과 출력 사이에 은닉층을 둔 신경망이다. 각 은닉 뉴런은 이전 층의 값들에 가중치를 곱해 더하고 편향을 더한 뒤, 비선형 활성화 함수를 적용한다. 이렇게 만든 값들이 다음 층의 입력이 된다.

교재의 실제 모델은 784 → 100 → 100 → 10이다. 한 배치에 들어 있는 이미지 수를 BB라 하면 각 단계의 텐서 모양은 다음과 같다.

단계구성출력 모양
입력이미지마다 픽셀 784개(B, 784)
첫 번째 은닉층Linear(784, 100) + ReLU(B, 100)
두 번째 은닉층Linear(100, 100) + ReLU(B, 100)
출력층Linear(100, 10)(B, 10)

정류 선형 함수(Rectified Linear Unit, ReLU)는 음수를 0으로 바꾸고 양수는 그대로 통과시키는 함수이다. 입력값을 zz라 하면 다음과 같다.

ReLU⁡(z)=max⁡(0,z)\operatorname{ReLU}(z)=\max(0,z)

ReLU는 값마다 적용되며 텐서의 모양을 바꾸지 않는다. 선형 계층만 여러 번 이어 붙이면 하나의 선형 계층으로 합칠 수 있지만, 사이에 ReLU를 넣으면 입력에 따라 다른 뉴런이 활성화되어 비선형 관계를 표현할 수 있다.

은닉층의 100개 값에 사람이 미리 의미를 붙이는 것은 아니다. 숫자를 구분하는 데 도움이 되도록 가중치가 조정되면서 중간 표현이 만들어진다.

출력 점수와 정답 연결하기

출력층의 열 개 값은 숫자 0~9에 대응하는 로짓(Logit), 즉 확률로 변환하기 전의 점수이다. 음수도 가능하고 합이 1일 필요도 없다. 출력층 뒤에는 ReLU나 Softmax를 붙이지 않고 이 점수를 nn.CrossEntropyLoss()에 바로 전달한다.

교차 엔트로피(Cross entropy) 손실은 정답 클래스에 부여한 확률이 낮을수록 커진다. PyTorch의 CrossEntropyLoss는 로짓으로부터 로그 소프트맥스와 정답 클래스의 음의 로그 확률에 해당하는 계산을 처리하므로, 확률을 미리 만들어 넣지 않는다.

이 예제에서는 (B, 10)의 로짓과 (B,)의 정수 정답을 짝지어 전달한다. 정답 텐서는 torch.long이며, 각 값은 0~9 중 하나이다. 원-핫 벡터로 바꿀 필요는 없다.

예측할 때는 이미지마다 가장 큰 로짓의 위치를 고른다. outputs.argmax(dim=1)을 적용하면 배치의 각 행에서 숫자 하나를 선택한다. 소프트맥스는 같은 행 안에서 점수의 순서를 유지하므로, 가장 높은 클래스만 고를 때는 별도의 확률 변환이 필요하지 않다.

학습과 평가에서 확인할 것

교재는 배치 크기 64로 데이터를 나누고, Adam 최적화 방법과 학습률 0.01로 3에포크를 학습한다. 에포크(Epoch)는 훈련 데이터를 한 번 모두 사용하는 단위이다. 각 배치에서 기울기를 초기화하고, 순전파와 손실 계산, 역전파, 가중치 갱신을 반복한다.

이때 교재가 에포크 끝에 출력하는 loss.item()은 마지막 배치의 손실이다. 전체 훈련 데이터의 평균 손실로 읽으면 안 된다. 에포크 평균을 구하려면 각 배치의 평균 손실에 실제 배치 크기를 곱해 누적한 뒤, 전체 표본 수로 나누어야 한다.

평가에서는 model.eval()로 평가 모드를 설정하고, torch.no_grad() 안에서 예측한다. 전자는 일부 계층의 동작 모드를 바꾸고, 후자는 역전파를 위한 계산 기록을 끈다. 이번 모델의 Linear와 ReLU는 모드에 따라 계산이 달라지지 않지만, 두 설정의 역할은 구분해야 한다. 정확도는 테스트 전체에서 맞힌 개수를 전체 테스트 표본 수로 나눈다.

또한 이 절은 OpenML의 70,000개 데이터를 무작위로 60,000개와 10,000개로 나눈다. 앞선 2.5 글에서 사용한 MNIST 기본 분할과 표본 구성이 다르므로, 두 결과를 그대로 비교해 은닉층의 효과라고 단정할 수 없다. 모델 구조에 따른 차이를 비교하려면 같은 데이터 분할과 전처리 등 비교 조건을 맞춰야 한다.

참고자료

profile
Werde, der du bist!

0개의 댓글