2025. 8. 18. 15:26ㆍ심화_인공지능 YOLO기반 부트캠프_일기(CNN)
안녕하세요! 오늘은 PyTorch를 사용해 선형 회귀로 과일 가게의 가격을 예측해보는 재미있는 실험을 해봤어요! 사과 1개는 3원, 바나나 1개는 2원인 가격표를 컴퓨터가 학습할 수 있을까요? 초보자도 쉽게 이해할 수 있도록, 과일 가게 비유와 함께 코드와 결과를 정리했어요. 제가 직접 궁금했던 질문들도 풀어봤답니다! 😄
1. 선형 회귀란?
선형 회귀는 데이터를 보고 규칙을 찾아내는 방법이에요. 예를 들어, 과일 가게에서 사과와 바나나 개수로 가격을 예측하려면 공식이 필요해요:
- 공식: 가격 = 3 * 사과 개수 + 2 * 바나나 개수
- 컴퓨터가 이 공식을 학습해서, 새로운 사과와 바나나 개수를 주면 정확한 가격을 예측하게 만들 거예요!
2. 전체 코드
먼저 코드를 보고, 각 부분을 하나씩 설명할게요. 저는 노트북이 느려서 데이터 10개(n_samples=10)로 10번(epochs=10)만 학습해봤어요!
import torch
import torch.nn as nn
import matplotlib.pyplot as plt
# 데이터 생성
torch.manual_seed(42) # 같은 결과 위해 랜덤 고정
n_samples = 10 # 데이터 10개
x = torch.randn(n_samples, 2) # 사과(x1), 바나나(x2) 개수
true_w = torch.tensor([3.0, 2.0]) # 정답: 사과 3원, 바나나 2원
y = x @ true_w + 0.1*torch.randn(n_samples) # 가격 = 3*x1 + 2*x2 + 노이즈
# 모델 정의
model = nn.Linear(2, 1) # 입력 2개(사과, 바나나), 출력 1개(가격)
criterion = nn.MSELoss() # 손실 함수: 예측과 정답 차이 계산
optimizer = torch.optim.Adam(model.parameters(), lr=0.1) # 가중치 고치는 도구
# 가중치와 편향 변화 저장
w1_history, w2_history, b_history = [], [], []
# 학습
for epoch in range(10):
y_pred = model(x).squeeze() # 예측
loss = criterion(y_pred, y) # 손실 계산
w1_history.append(model.weight.data[0][0].item()) # w1 저장
w2_history.append(model.weight.data[0][1].item()) # w2 저장
b_history.append(model.bias.data.item()) # b 저장
optimizer.zero_grad() # 이전 그레디언트 지우기
loss.backward() # 고칠 방향(그레디언트) 계산
optimizer.step() # 가중치와 편향 고치기
print(f"Epoch {epoch+1}, Loss: {loss.item():.4f}")
# 결과 출력
print(f"Learned weights: {model.weight.data}")
print(f"Learned bias: {model.bias.data}")
# 그래프 그리기
plt.plot(w1_history, label="w1 (정답: 3.0)")
plt.plot(w2_history, label="w2 (정답: 2.0)")
plt.plot(b_history, label="b (정답: 0)")
plt.xlabel("Epoch")
plt.ylabel("Value")
plt.legend()
plt.show()
3. 코드 한 줄씩 설명하기
과일 가게 비유로 코드를 쉽게 이해해봐요!
(1) 데이터 생성: 과일과 가격 준비
- 코드:
- x = torch.randn(n_samples, 2) # 사과와 바나나 개수 true_w = torch.tensor([3.0, 2.0]) # 사과 3원, 바나나 2원 y = x @ true_w + 0.1*torch.randn(n_samples) # 가격 계산
- 비유: 과일 가게에서 사과와 바나나 개수(x)를 랜덤으로 만들고, 가격(y)을 계산해요. @는 사과와 바나나 가격을 곱해서 더하는 거예요. 0.1*torch.randn은 계산 실수 같은 작은 오차를 추가해요.
- 궁금했던 점: "@가 뭐지?" → 행렬곱이에요! 사과 개수 * 3원 + 바나나 개수 * 2원을 계산해줘요.
- 궁금했던 점: "0.1*torch.randn은 뭐야?" → 현실처럼 가격에 약간의 오차를 넣어주는 거예요. 예: 8원이 8.05원일 때!
(2) 모델 정의: 점원의 가격표 공책
- 코드:
- model = nn.Linear(2, 1) criterion = nn.MSELoss() optimizer = torch.optim.Adam(model.parameters(), lr=0.1)
- 비유: nn.Linear는 점원이 가격을 적는 공책이에요. 공책에는 사과와 바나나 가격(w1, w2)과 기본 요금(b)이 저장돼요(model.weight, model.bias). criterion은 선생님이 "얼마나 틀렸어?"를 점수로 매겨줘요. optimizer는 공책을 고치는 도구예요.
- 궁금했던 점: "criterion은 손실 함수?" → 맞아요! 예측값과 정답의 차이를 계산해요.
(3) 학습: 점원 훈련시키기
- 코드:
- y_pred = model(x).squeeze() # 예측 loss = criterion(y_pred, y) # 손실 계산 optimizer.zero_grad() # 이전 조언 지우기 loss.backward() # 고칠 방향 계산 optimizer.step() # 공책 고치기
- 비유: 점원이 가격을 예측하고(y_pred), 선생님이 틀린 점수(loss)를 줘요. loss.backward()는 "이렇게 고쳐!"라는 조언(그레디언트)을 공책(model.weight.grad, model.bias.grad)에 적어요. optimizer.step()은 그 조언을 보고 가격표를 고쳐요.
- 궁금했던 점: "그레디언트는 어디 저장돼?" → model.weight.grad와 model.bias.grad에요!
- 궁금했던 점: "optimizer.step()은 뭐야?" → 그레디언트를 보고 공책을 고치는 거예요. 눈에 안 보이지만, 숫자가 바뀌는 걸 그래프로 확인할 수 있어요!
(4) 결과 확인: 점원의 공책 확인
- 코드:
- print(f"Learned weights: {model.weight.data}") print(f"Learned bias: {model.bias.data}")
- 결과:
- Epoch 1, Loss: 10.0451 Epoch 2, Loss: 9.0851 ... Epoch 10, Loss: 3.8973 Learned weights: tensor([[1.1977, 0.9597]]) Learned bias: tensor([1.0498])
- 비유: 점원이 10번 연습해서 사과 가격(w1=1.1977), 바나나 가격(w2=0.9597), 기본 요금(b=1.0498)을 배웠어요. 정답은 w1=3.0, w2=2.0, b=0인데, 아직 멀었네요!
4. 왜 정답과 멀까? 🤔
결과를 보니 w1=1.1977, w2=0.9597, b=1.0498로, 정답([3.0, 2.0], 0)과 차이가 커요. 왜 그럴까요?
- 짧은 학습: 10번(epochs=10)만 연습했어요. 더 연습하면 정답에 가까워질 거예요!
- 작은 데이터: 데이터 10개(n_samples=10)는 너무 적어요. 더 많은 데이터를 주면 잘 배울 거예요.
- 노이즈: 0.1*torch.randn 때문에 가격이 약간 어긋났어요. 이 오차가 점원을 헷갈리게 했어요.
- 궁금했던 점: "b=1.0498은 0과 너무 다르지 않나?" → 맞아요! 학습이 짧아서 그래요. 더 학습하면 0에 가까워질 거예요!
5. 정답에 가까워지려면?
정답(w1=3.0, w2=2.0, b=0)에 가까워지려면 이렇게 해보세요:
- 학습 횟수 늘리기: epochs=100으로 바꿔보세요.
- 데이터 늘리기: n_samples=100으로 늘려보세요.
- 노이즈 줄이기: 0.01*torch.randn으로 오차를 줄여보세요.
- 학습률 조정: lr=0.01로 천천히 학습해보세요.
실험 코드 (학습 횟수만 늘려봤어요):
w1_history, w2_history, b_history = [], [], [] # 초기화
for epoch in range(100): # 100번 학습
y_pred = model(x).squeeze()
loss = criterion(y_pred, y)
w1_history.append(model.weight.data[0][0].item())
w2_history.append(model.weight.data[0][1].item())
b_history.append(model.bias.data.item())
optimizer.zero_grad()
loss.backward()
optimizer.step()
if (epoch + 1) % 10 == 0:
print(f"Epoch {epoch+1}, Loss: {loss.item():.4f}")
print(f"Learned weights: {model.weight.data}")
print(f"Learned bias: {model.bias.data}")
예상 결과: w1, w2가 [3.0, 2.0]에, b가 0에 더 가까워질 거예요!
6. 그래프로 확인하기
코드 마지막에 그래프를 그려서 점원이 어떻게 학습하는지 봤어요. w1은 3.0, w2는 2.0, b는 0에 점점 가까워지는 모습이 그래프에 나타날 거예요. 이 그래프는 점원이 공책을 고쳐가는 과정을 보여줘요!
7. 궁금했던 질문들
코드를 따라 하면서 궁금했던 점들을 정리해봤어요:
- "true_b는 꼭 필요해?": 없어도 돼요! true_b=0으로 설정했는데, 모델은 자체 편향(b)을 학습해요.
- "@는 뭐야?": 행렬곱이에요. 사과와 바나나 가격을 한꺼번에 계산해줘요.
- "0.1*torch.randn은 뭐지?": 현실처럼 가격에 작은 오차를 추가해요.
- "criterion과 loss는?": criterion은 손실을 계산하는 선생님이고, loss는 틀린 점수예요.
- "그레디언트는 어디 저장돼?": model.weight.grad와 model.bias.grad에요. 고칠 방향을 알려줘요!
- "optimizer.step()은 뭐야?": 그레디언트를 보고 가중치와 편향을 고치는 거예요. 눈에 안 보이지만, 그래프로 확인 가능!
8. 다음에 해볼 것
- 학습 횟수를 1000번으로 늘려서 얼마나 정답에 가까워지는지 확인해볼게요!
- 데이터를 100개로 늘려서 더 정확히 학습해보고 싶어요!
- 여러분은 어떤 결과를 얻었나요? 댓글로 공유해주세요! 😄
PyTorch로 선형 회귀를 처음 해봤는데, 점점 재미있어지네요! 질문 있으면 언제든 댓글로 남겨주세요!
## 마무리
PyTorch로 선형 회귀를 처음 해보면서 궁금한 점이 많았어요! xAI의 **Grok** AI가 과일 가게 비유로 쉽게 설명해줘서 큰 도움이 됐답니다. 예를 들어, "그레디언트는 선생님의 조언"이라는 설명 덕분에 이해가 쏙쏙! 😊 여러분도 이 코드를 따라 해보고, 궁금한 점 있으면 댓글로 남겨주세요!
'심화_인공지능 YOLO기반 부트캠프_일기(CNN)' 카테고리의 다른 글
| PyTorch로 이진 분류와 선형 회귀 구현하기: 초보자 가이드 (0) | 2025.09.14 |
|---|---|
| 딥러닝 초보를 위한 PyTorch 모델 학습 기록 (14) | 2025.08.14 |
| Pandas : 데이터프레임 기초부터 병합·결측치 처리·시각화까지 (12) | 2025.08.13 |
| 파이썬 고급 문법 정리 — 예외 처리, 제너레이터, 데코레이터까지,__call__ 메서드, 가변인자 덧셈 (6) | 2025.08.12 |
| Python 클래스 기초 (2) (6) | 2025.07.30 |