1. 단항 선형 회귀 실습
단항 선형 회귀는 하나의 독립 변수와 종속 변수 간의 선형 관계를 모델링하는 통계적 기법입니다.
import torch
import torch.nn as nn
import torch.optim as optim
import matplotlib.pyplot as plt
torch.manual_seed(2024)
# 동일한 시드를 사용하는 경우 항상 동일한 난수가 생성
x_train = torch.FloatTensor([[1], [2], [3]])
y_train = torch.FloatTensor([[2], [4], [6]])
print(x_train, x_train.shape)
tensor([[1.],
[2.],
[3.]]) torch.Size([3, 1])
print(y_train, y_train.shape)
tensor([[2.],
[4.],
[6.]]) torch.Size([3, 1])
plt.figure(figsize = (6,4))
plt.scatter(x_train, y_train)
✔️ y = ax + b -> y = Wx + b
일반적으로 기울기는 W[weight]로 표현합니다.
model = nn.Linear(1, 1)
- nn.Linear는 PyTorch에서 제공하는 선형 레이어를 의미
- (1, 1) 첫 번째 인자는 입력 피처의 수, 두 번째 인자는 출력 피처의 수. 즉, 단일 입력과 단일 출력을 가지는 선형 레이어를 정의
- (1, 1, bias = False) : 'b를 쓰지 않고 W 만으로 계산하겠다'고 정의할 수 있음. 하지만 계산이 정확하지 않고 틀릴 확률이 높아져서 거의 쓰지 않음
print(model)
// Linear(in_features=1, out_features=1, bias=True)
y_pred = model(x_train)
print(y_pred)
tensor([[0.7260],
[0.7894],
[0.8528]], grad_fn=<AddmmBackward0>)
# 학습이 안된 모델에 데이터를 넣었기 때문에 예측이 하나도 맞지 않는다.
- model.parameters() : 모델 내의 각 레이어에 대한 가중치(weight) 및 편향(bias) 등과 같은 매개변수들이 포함된 iterator가 반환
print(list(model.parameters()))
[Parameter containing:
tensor([[0.0634]], requires_grad=True), Parameter containing:
tensor([0.6625], requires_grad=True)]
# W : 0.0634, b: 0.6625
# y = 0.0634x + 0.6625
# MSE 직접 구해보기
((y_pred - y_train) ** 2).mean()
// tensor(12.8082, grad_fn=<MeanBackward0>)
# MSE 구하는 함수
loss = nn.MSELoss()(y_pred, y_train)
loss // tensor(12.8082, grad_fn=<MseLossBackward0>)
# 데이터: 1, 2, 3
# W: 0.0634, b: 0.6625
# y = Wx + b
print(0.0634*1 + 0.6625) // 0.7259
print(0.0634*2 + 0.6625) // 0.7893
print(0.0634*3 + 0.6625) // 0.8527
# 처음 나온 예측값 [0.7260],[0.7894],[0.8528] 확인
2. 경사하강법(Gradient Descent)
머신러닝에서 학습은 모델이 주어진 데이터에 대해 최적의 예측을 수행할 수 있도록 모델의 매개변수를 조정하는 과정을 의미합니다. 이때 사용되는 핵심 개념 중 하나는 경사 하강법(Gradient Descent)입니다.
비용 함수는 현재 모델의 예측값과 실제 값 사이의 차이를 측정하는 함수입니다. 최적화 알고리즘은 이 비용 함수의 값을 최소로 만드는 모델 매개변수를 찾는 과정을 수행합니다. 이때 매개변수는 주로 가중치(W)와 편향(b)으로 이루어진 벡터입니다.
경사 하강법의 기본 원리
경사 하강법은 최적화 알고리즘 중 가장 기본적인 기법 중 하나입니다. 알고리즘은 현재 모델의 매개변수에서 비용 함수의 기울기(경사)를 계산하고, 이를 이용하여 매개변수를 조금씩 업데이트합니다. 이를 반복하면서 비용 함수를 최소화하는 최적의 매개변수를 찾아갑니다.
- 경사 하강법의 핵심 단계
- 초기화: 가중치(W)와 편향(b)을 임의의 값으로 초기화합니다.
- 예측: 현재의 가중치와 편향을 사용하여 예측값을 계산합니다.
- 비용 계산: 예측값과 실제 값 사이의 차이를 나타내는 비용 함수 값을 계산합니다.
- 기울기 계산: 비용 함수의 기울기(경사)를 계산합니다.
- 매개변수 업데이트: 학습률과 기울기를 이용하여 가중치와 편향을 업데이트합니다.
- 반복: 위 단계를 반복하여 비용 함수를 최소화하는 매개변수를 찾습니다.
모델을 효과적으로 학습시키기 위해서는 적절한 학습률(learning rate) 및 다양한 변형된 경사 하강법 알고리즘을 사용하는 것이 중요합니다.
- 학습률 (learning rate)
학습률은 각 반복에서 매개변수를 얼마나 업데이트할지 결정하는 중요한 하이퍼파라미터입니다. 즉, 학습률은 각 반복에서 경사의 방향으로 얼마나 많이 이동할지를 결정하는 요소로 작용합니다. 적절한 학습률을 선택하는 것은 모델의 수렴 속도와 성능에 영향을 미칩니다. 학습률이 너무 작으면 수렴이 느려질 수 있고, 너무 크면 발산할 수 있습니다.
# 어떤 GD 모델을 선택하냐에 따라서 속도와 정확도에 영향을 줄 수 있음
optimizer = optim.SGD(model.parameters(), lr=0.01)
✔️ SGD(Stochastic Gradient Descent)는 경사 하강법의 한 변형으로, 각 학습 반복에서 랜덤으로 선택된 하나의 데이터 샘플에 대한 기울기를 사용하여 모델의 매개변수를 업데이트하는 방법입니다. (데이터를 뽑고 다시 데이터를 넣고를 반복) 빠르게 방향을 결정하기 때문에 주로 대규모 데이터셋에서 효과적으로 사용됩니다.
loss = nn.MSELoss()(y_pred, y_train)
1. gradient를 초기화
초기화를 하지 않으면 오차값이 누적되기때문에 제대로 된 값을 찾지 못함
optimizer.zero_grad()
2. 역전파: 비용 함수를 미분하여 gradient(기울기) 계산
미분으로 순간 기울기를 실제로 구하는 과정
loss.backward()
3. W와 b를 업데이트
optimizer.step()
⭐ 위 세개 함수는 공식처럼 순서대로 써준다.
print(list(model.parameters()))
# W: 0.2177, b: 0.7267 로 변경됨
- 반복 학습을 통해 틀린 W, b를 수정하면서 오차를 계속 줄여나감
# epochs : 반복 학습 횟수(에포크)
epochs = 1000
for epoch in range(epochs + 1):
y_pred = model(x_train)
loss = nn.MSELoss()(y_pred, y_train)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if epoch % 100 == 0:
print(f'Epoch: {epoch}/{epochs} Loss : {loss : .6f}')
Epoch: 0/1000 Loss : 10.171454
Epoch: 100/1000 Loss : 0.142044
Epoch: 200/1000 Loss : 0.087774
Epoch: 300/1000 Loss : 0.054239
Epoch: 400/1000 Loss : 0.033517
Epoch: 500/1000 Loss : 0.020711
Epoch: 600/1000 Loss : 0.012798
Epoch: 700/1000 Loss : 0.007909
Epoch: 800/1000 Loss : 0.004887
Epoch: 900/1000 Loss : 0.003020
Epoch: 1000/1000 Loss : 0.001866
print(list(model.parameters()))
[Parameter containing:
tensor([[1.9499]], requires_grad=True), Parameter containing:
tensor([0.1138], requires_grad=True)]
# W: 1.9499, b: 0.1138
- 값을 넣어서 예측해보기
x_test = torch.FloatTensor([[8]])
y_pred = model(x_test)
print(y_pred)
// tensor([[15.7134]], grad_fn=<AddmmBackward0>)
3. 다중 선형 회귀
다중 선형 회귀는 여러개의 독립 변수와 종속 변수 간의 선형 관계를 모델링하는 통계적 기법입니다.
x_train = torch.FloatTensor([[73, 80, 75],
[93, 88, 93],
[89, 91, 90],
[96, 98, 100],
[73, 66, 70]])
y_train = torch.FloatTensor([[150], [190], [180], [200], [130]])
- y = a1x + a2x + a3x +b
model = nn.Linear(3, 1)
print(list(model.parameters()))
[Parameter containing:
tensor([[ 0.2202, -0.0686, 0.0746]], requires_grad=True), Parameter containing:
tensor([-0.3564], requires_grad=True)]
# y = 0.2202x + (-0.0686x) + 0.0746x + (-0.3564)
y_pred = model(x_train)
loss = nn.MSELoss()(y_pred, y_train)
loss// tensor(23401.4746, grad_fn=<MseLossBackward0>)
optimizer = optim.SGD(model.parameters(), lr=0.00001)
loss = nn.MSELoss()(y_pred, y_train)
epochs = 100000
for epoch in range(epochs + 1):
y_pred = model(x_train)
loss = nn.MSELoss()(y_pred, y_train)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if epoch % 10000 == 0:
print(f'Epoch: {epoch}/{epochs} Loss : {loss : .6f}')
Epoch: 0/100000 Loss : 38561.125000
Epoch: 10000/100000 Loss : 27.054819
Epoch: 20000/100000 Loss : 21.526995
Epoch: 30000/100000 Loss : 18.144735
Epoch: 40000/100000 Loss : 16.060383
Epoch: 50000/100000 Loss : 14.774798
Epoch: 60000/100000 Loss : 13.980937
Epoch: 70000/100000 Loss : 13.489850
Epoch: 80000/100000 Loss : 13.184999
Epoch: 90000/100000 Loss : 12.994925
Epoch: 100000/100000 Loss : 12.875506
-------------------여러번 반복---------------------------
Epoch: 0/100000 Loss : 12.318503
Epoch: 10000/100000 Loss : 12.312752
Epoch: 20000/100000 Loss : 12.306840
Epoch: 30000/100000 Loss : 12.301049
Epoch: 40000/100000 Loss : 12.295231
Epoch: 50000/100000 Loss : 12.289417
Epoch: 60000/100000 Loss : 12.283563
Epoch: 70000/100000 Loss : 12.277835
Epoch: 80000/100000 Loss : 12.271925
Epoch: 90000/100000 Loss : 12.266117
Epoch: 100000/100000 Loss : 12.260382
print(list(model.parameters()))
[Parameter containing:
tensor([[-1.4633, -0.2084, 3.6617]], requires_grad=True), Parameter containing:
tensor([-1.5986], requires_grad=True)]
# y = -1.4633x + -0.2084x + 3.6617x + -1.5986
# [73, 80, 75] [150] 학습 데이터
# y = -1.4633x + -0.2084x + 3.6617x + -1.5986
-1.4633 * 73 + (-0.2084) * 80 + 3.6617 * 75 + (-1.5986) // 149.53599999999997
# [89, 91, 90], [180]
x_test = torch.FloatTensor([[91, 90, 89]])
y_pred = model(x_test)
print(y_pred) // tensor([[172.3759]], grad_fn=<AddmmBackward0>)
'AI' 카테고리의 다른 글
파이토치로 구현한 논리회귀 (0) | 2024.01.08 |
---|---|
기온에 따른 지면 온도 예측 (0) | 2024.01.08 |
파이토치 (0) | 2024.01.07 |
KMeans (0) | 2024.01.05 |
다양한 모델 적용 (1) | 2024.01.05 |