이번에는 학습된 모델의 Accuracy만 확인하는 것에서 끝나지 않고,
실제값과 예측값을 저장 → Confusion Matrix 생성 → Heatmap으로 시각화
하는 과정까지 이어서 진행했다.
그리고 이 과정에서도 계속 중요하게 등장한 것이 Tensor의 Shape과 데이터 타입이었다.
⠀
1. Accuracy만으로는 어떤 데이터를 틀렸는지 알기 어렵다
앞에서는 모델의 전체 Accuracy를 계산했다.
accuracy = accuracy_fn(
y_true=targets,
y_pred=te_round.squeeze()
)
Accuracy를 보면 전체 데이터 중 몇 %를 맞혔는지는 알 수 있다.
하지만 예를 들어 Accuracy가 95%라고 해도
- 실제 5를 5가 아니라고 얼마나 틀렸는지
- 실제 5가 아닌 숫자를 5라고 얼마나 틀렸는지
까지는 알 수 없다.
그래서 이번에는 Confusion Matrix를 이용해 실제값과 예측값의 관계를 더 자세히 확인했다.
⠀
2. 다시 확인한 Shape의 중요성
강의에서 다시 강조된 부분은 squeeze()였다.
이진분류 모델의 출력은 마지막 target_size=1이기 때문에 일반적으로
(batch, 1)
형태다.
반면 Target은
(batch,)
형태다.
즉 예를 들어
예측값 : (100, 1)
정답 : (100,)
이 된다.
두 Tensor가 가지고 있는 값의 개수는 같아 보여도 Shape은 다르다.
따라서 예측값을 실제 Target과 비교하려면
te_round.squeeze()
를 사용해
(100, 1)
↓
(100,)
으로 맞춰줘야 한다.
📌 이번 강의에서 다시 강조된 점
함수를 사용한다고 해서 항상 Tensor의 차원이 바뀌는 것은 아니다.
Sigmoid → 값만 변경, Shape 유지
round → 값만 변경, Shape 유지
squeeze → Shape 변경
따라서 딥러닝에서는 현재 Tensor가 몇 차원인지 계속 확인하는 습관이 중요하다.
⠀
3. Confusion Matrix를 만들려면 실제값과 예측값을 저장해야 한다
Confusion Matrix에는 두 가지 값이 필요하다.
실제값 y_true
예측값 y_pred
하지만 Test DataLoader에서는 Batch 단위로 데이터가 들어오기 때문에, 각 Batch의 결과를 계속 모아야 한다.
그래서 빈 리스트를 먼저 만든다.

그리고 Test Loop를 반복하면서 실제값과 예측값을 저장한다.

⠀
4. append가 아니라 extend를 사용한 이유
여기서 append()와 extend()의 차이도 다시 확인했다.
예를 들어
a = [1, 2, 3]
을 리스트에 넣을 때
result.append(a)
를 사용하면
[[1, 2, 3]]
처럼 리스트 자체가 하나의 원소로 들어간다.
반면
result.extend(a)
를 사용하면
[1, 2, 3]
처럼 각각의 값이 기존 리스트에 이어서 들어간다.
이번에는 Batch별 예측값을 하나의 전체 예측 리스트로 이어붙여야 하기 때문에 extend()를 사용했다.
⠀
5. Tensor를 NumPy로 변환하는 이유
모델 학습과 추론은 PyTorch Tensor를 사용했다.
하지만 이번 Confusion Matrix는 sklearn의 함수를 이용한다.
from sklearn.metrics import confusion_matrix
즉 지금까지 사용하던 PyTorch 영역에서 sklearn 영역으로 넘어가는 것이다.
그래서 Tensor 형태의 값을 NumPy 형태로 변환한다.
te_round.numpy()
targets.numpy()
최종적으로 리스트에 저장한 뒤 다시 NumPy Array로 변환할 수 있다.
np.array(lst_te_y)
np.array(lst_te_pred)
📌 내가 기억할 부분
PyTorch 모델
→ Tensor
sklearn 평가 함수
→ NumPy 사용
처럼 서로 다른 라이브러리를 연결할 때 데이터 타입을 맞춰주는 과정이 필요할 수 있다.
⠀
6. Confusion Matrix 만들기
실제값과 예측값을 모두 모았다면 Confusion Matrix를 계산할 수 있다.

여기서
normalize='true'
를 사용하면 단순한 개수가 아니라 실제 클래스별 비율로 확인할 수 있다.
예를 들어 데이터 개수가 클래스마다 다르면 단순 Count만 비교하는 것보다 비율로 보는 것이 결과를 해석하기 더 편하다.
⠀
7. Heatmap으로 시각화하기
Confusion Matrix를 숫자 배열로만 봐도 되지만, Heatmap으로 표현하면 어느 부분에서 모델이 잘 맞추고 틀리는지 훨씬 쉽게 볼 수 있다.

축을 볼 때는
x축 → Predicted
y축 → Actual
이라는 점을 확인해야 한다.

📌 Heatmap에서 보는 것
대각선 방향의 값은 실제값과 예측값이 일치한 경우다.
반대로 대각선 밖의 값은 모델이 다른 클래스로 잘못 예측한 경우다.
즉 Accuracy 하나만 볼 때보다 어떤 방향의 오분류가 발생했는지까지 확인할 수 있다.
⠀
8. 왜 비율로 보는가
강의에서는 Heatmap을 확인할 때 normalize를 적용해 비율로 표현하는 것을 강조했다.
예를 들어 한 클래스가 1,000개이고 다른 클래스가 100개라면 단순 개수만 비교할 경우 데이터가 많은 클래스의 숫자가 당연히 더 크게 나타난다.
반면 클래스별 비율을 사용하면
실제 Class 0 중 몇 %를 제대로 맞췄는가
실제 Class 1 중 몇 %를 제대로 맞췄는가
처럼 해석할 수 있다.
따라서 클래스별 모델 성능을 비교하기 편해진다.
⠀
9. 이번 실습의 전체 흐름
Test DataLoader
↓
Model
↓
Logit
↓
Sigmoid
↓
round
↓
squeeze
↓
Batch별 예측값 저장
↓
Tensor → NumPy
↓
실제값 / 예측값 전체 수집
↓
Confusion Matrix
↓
normalize
↓
Heatmap
앞에서는 모델을 학습시키는 것이 중심이었다면, 이번에는 학습된 모델의 결과를 어떻게 해석할 것인지까지 연결했다.
⠀
10. 핵심 정리
개념기억할 내용
| squeeze | (batch, 1)을 (batch,)로 변경 |
| Sigmoid | 값은 변경하지만 Shape은 그대로 |
| round | 확률을 0/1로 변경하지만 Shape은 그대로 |
| extend | Batch별 결과를 하나의 리스트로 이어붙임 |
| .numpy() | Tensor를 NumPy 형태로 변환 |
| Confusion Matrix | 실제값과 예측값의 관계를 확인 |
| normalize | 클래스별 결과를 비율로 확인 |
| Heatmap | Confusion Matrix를 시각적으로 확인 |
이번 실습에서 가장 기억할 부분은,
모델 평가도 결국 Shape과 데이터 타입을 정확하게 이해해야 제대로 연결할 수 있다는 점이다.
단순히 Accuracy가 높다고 끝내는 것이 아니라,
실제값
vs
예측값
을 직접 비교하면서 어떤 데이터를 잘 맞히고 어떤 데이터를 틀리는지 확인하는 과정까지 이어져야 모델을 제대로 평가할 수 있다.