1. 단항 선형 회귀 실습
* 한 개의 입력이 들어가서 한 개의 출력이 나오는 구조
- import
import torch # 오픈 소스 기계 학습 라이브러리 모듈
import torch.nn as nn # nn 이란? 인경신경망을 구현하기 위한 도구와 모듈제공
import torch.optim as optim # optim 이란 다양한 최적화 알고리즘 구현
import matplotlib.pyplot as plt
|
- 가격을 생성할 때 랜덤한 수 생성
# 파이썬 코드를 재실행해도 같은 결과가 나올 수 있도록 랜덤시드를 설정
torch.manual_seed(2024)
|
- 데이터 직접 만들기
# 1차원 텐서를 생성 / 텐서란? 다차원 배열을 나타내는 데이터 구조 ( 기본적으로 숫자데이터를 저장하고 다양한 수학적 연산을 수행)
X_train = torch.FloatTensor([[1],[2],[3]]) # 1,2,3을 실수 형태로 저장
y_train = torch.FloatTensor([[2],[4],[6]]) # 2,4,6을 실수 형태로 저장
print(X_train)
print(X_train.shape)
print(y_train)
print(y_train.shape)
|
- 산점도 그리기
# 산점도 그림
# x_train x축에 해당하는 입력 데이터 ,y_train y축에 해당하는 목표 변수(타깃)
plt.figure(figsize = (6, 4))
plt.scatter(X_train, y_train)
|
![]() |
- 머신러닝 모델 만들기
# 직선의 방정식 y = wx + b
model = nn.Linear(1, 1) # 데이터를 하나 넣으면 하나 출력
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>) |
- 예측한 기울기와 절편 확인
# 기울기와 바이어스
# 학습전이라 임의의 값으로 설정됨 list(model.parameters())
# 가중치(W): 0.0634, 편향(b): 0.6625
# x=1 일 때, y_pred = 0.0634 + 0.6625 = 0.7259
# x=2 일 때, y_pred = (0.0634*2) + 0.6625 = 0.7893
|
[Parameter containing: tensor([[0.0634]], requires_grad=True), Parameter containing: tensor([0.6625], requires_grad=True)] |
- MSE(Mean Squared Error, 평균 제곱 오차)를 계산
신경망의 예측값 실제 타겟 값 간의 차이를 제곱한 후 평균
# MSE 값
((y_pred - y_train) ** 2).mean()
# 예측값 - 실제값, 제곱하기, 평균내기
|
tensor(12.8082, grad_fn=<MeanBackward0>) |
- 손실 함수: 예측값과 실제값이 얼마나 차이가 나는지를 측정
loss = nn.MSELoss()(y_pred, y_train)
loss
|
tensor(12.8082, grad_fn=<MseLossBackward0>) |
2. 경사하강법
SGD(Stochasitc Gradient Desert)* 비용 함수의 값을 최소로 하는 w 와 b를 찾는 알고리즘을 옵티마이저 알고리즘이라고 함 (최적화 알고리즘)
* "옵티마이저 알고리즘" 중 가장 기본적인 기술이 경사하강법
* 옵티마이저 알고리즘을 통해 w와 b를 찾아내는 과정을 "학습"이라고 부름
* 학습률(Learning rate) : 한번 W를 움직이는 거리 (increment strp)
- 옵티마이저 객체 생성
# SGD(Stochasitc Gradient Desert)
# 랜덤하게 데이터를 하나씩 뽑아서 loss를 만듦
# 데이터를 뽑고 다시 데이터에 넣고를 반복
# 빠르게 방향을 결정
# 학습률(Learning rate): 한 번 움직이는 거리(increment step)
optimizer = optim.SGD(model.parameters(), lr=0.01)
|
- 선형 회귀
# 손실 함수를 계산
loss = nn.MSELoss()(y_pred, y_train)
# gradient를 초기화
optimizer.zero_grad()
# 역전파 : 비용함수를 미분하여 gradient(기울기) 재계산
loss.backward() # 미분을 취해서 기울기와 절편을 새롭게 찾아냄
# W와 b를 업데이트
optimizer.step()
print(list(model.parameters()))
# W: [[-0.2177]] b:[0.7267]
|
[Parameter containing: tensor([[0.2177]], requires_grad=True), Parameter containing: tensor([0.7267], requires_grad=True)] |
- 모델을 학습시키기
# 반복학습을 통해 오차가 있는 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}/{epoch} 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 |
- 주석
더보기
# 에포크 수 설정
epochs = 1000
# 에포크 반복문 시작
for epoch in range(epochs + 1):
# 모델을 사용하여 훈련 데이터(X_train)에 대한 예측 값(y_pred) 계산
y_pred = model(X_train)
# 예측 값(y_pred)과 실제 값(y_train) 간의 평균 제곱 오차(MSE) 손실 계산
loss = nn.MSELoss()(y_pred, y_train)
# 옵티마이저의 기울기(gradient) 초기화
optimizer.zero_grad()
# 손실에 대한 그래디언트 계산(역전파)
loss.backward()
# 옵티마이저를 사용하여 모델 파라미터 업데이트
optimizer.step()
# 100번째 에포크마다 현재 에포크와 손실 값을 출력
if epoch % 100 == 0:
print(f'Epoch {epoch}/{epochs} Loss: {loss:.6f}')
|
- 예측한 기울기와 절편 확인
# parameter은 nn.module 클래스 방법( 모델이 가능한 확률을 반환하는 기여를 함)
print(list(model.parameters()))
# W :1.9499 b: 0.1138
|
[Parameter containing: tensor([[1.9499]], requires_grad=True), Parameter containing: tensor([0.1138], requires_grad=True)] |
- 입력 데이터 x_test에 대한 예측값 y_pred를 출력
x_test = torch.FloatTensor([[5]])
y_pred = model(x_test)
print(y_pred)
|
tensor([[9.8635]], grad_fn=<AddmmBackward0>) |
3. 다중 선형 회귀
여러 개의 입력이 들어가서 한 개의 출력이 나오는 구조
- X_train과 y_train이라는 두 개의 텐서를 정의하고, 이들의 값을 출력
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]])
print(X_train, X_train.shape)
print(y_train, y_train.shape)
|
tensor([[ 73., 80., 75.], [ 93., 88., 93.], [ 89., 91., 90.], [ 96., 98., 100.], [ 73., 66., 70.]]) torch.Size([5, 3]) tensor([[150.], [190.], [180.], [200.], [130.]]) torch.Size([5, 1]) |
|
- 선형 회귀 모델 정의
입력 변수가 3개인 경우에 대해 각 변수에 대한 가중치를 학습하여 예측값을 계산
# y = W1x1 + W2x2 + W3x3 + b
model = nn.Linear(3,1)
print(model)
|
Linear(in_features=3, out_features=1, bias=True) |
입력 차원이 3이고 출력 차원이 1인 선형 회귀 모델을 정의 합니다. |
- 최적화 함수 정의
# 확률적 경사 하강법
optimizer = optim.SGD(model.parameters(),lr=0.00001)
|
|
- 선형 회귀 모델을 학습하는 과정
#학습
epochs = 10000
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}/{epoch} Loss: {loss:.6f}')
|
Epoch 0/0 Loss: 38561.125000 Epoch 100/100 Loss: 43.880661 Epoch 200/200 Loss: 43.343727 Epoch 300/300 Loss: 42.829872 Epoch 400/400 Loss: 42.337685 ......... Epoch 9500/9500 Loss: 27.417210 Epoch 9600/9600 Loss: 27.343838 Epoch 9700/9700 Loss: 27.270786 Epoch 9800/9800 Loss: 27.198359 Epoch 9900/9900 Loss: 27.126339 Epoch 10000/10000 Loss: 27.054819 * Epoch 높아질수록 Loss 낮아짐!! |
- 주석
더보기
# 학습
epochs = 10000 # 총 학습 에포크 수를 10000으로 설정
for epoch in range(epochs + 1): # 0부터 10000까지 반복
y_pred = model(X_train) # 모델에 학습 데이터셋을 입력하여 예측값 계산
loss = nn.MSELoss()(y_pred, y_train) # 예측값과 실제 값 사이의 손실(평균 제곱 오차) 계산
optimizer.zero_grad() # 역전파 이전에 기울기 초기화
loss.backward() # 손실 값에 대해 역전파를 수행하여 기울기 계산
optimizer.step() # 기울기를 사용하여 모델의 매개변수 업데이트
if epoch % 100 == 0: # 에포크가 100의 배수일 때마다 손실 값 출력
print(f'Epoch {epoch}/{epochs} Loss: {loss:.6f}')
|
|
- 모델의 가중치와 편향을 출력
print(list(model.parameters())) # W : [0.3478, 0.6414, 1.0172] # b : [-0.2856]
|
[Parameter containing: tensor([[0.3478, 0.6414, 1.0172]], requires_grad=True), Parameter containing: tensor([-0.2856], requires_grad=True)] |
model의 학습 가능한 모든 매개변수들을 리스트로 변환하고 출력합니다. nn.Linear(3, 1) 모델은 3개의 입력과 1개의 출력을 가지므로, 가중치 행렬 W는 (1, 3) 형태이고, 편향 b는 (1,) 형태입니다.
|
- 결과(쌤)
- 선형 회귀 모델을 사용하여 새로운 입력 데이터 x_test에 대한 예측값을 계산
# 93,93,93 일때 185 나오면 맞음
x_test = torch.FloatTensor([[93, 93, 93]])
y_pred=model(x_test)
print(y_pred)
|
tensor([[186.3026]], grad_fn=<AddmmBackward0>) |
|
- 결과(쌤)
4. temp 데이터 활용하기
기온 데이터
- 과제 (단항 선형 회귀)
- import
import pandas as pd
|
- 데이터 인코딩하면서 가져오기
df = pd.read_csv('/content/drive/MyDrive/1. KDT/6. 머신러닝 딥러닝/데이터/temps.csv', encoding='ms949' )
df.head()
|
![]() |
- null 값 삭제
df.isnull().mean()
df = df.dropna()
df.isnull().mean()
|
지점 0.000000 지점명 0.000000 일시 0.000000 기온(°C) 0.000342 지면온도(°C) 0.000000 dtype: float64 --------------------------------------- 지점 0.0 지점명 0.0 일시 0.0 기온(°C) 0.0 지면온도(°C) 0.0 dtype: float64 |
- [ '기온(°C)' ]과 [ '지면온도(°C)' ]을 추출하여 PyTorch 텐서로 변환
x_data = df[['기온(°C)']]
y_data = df[['지면온도(°C)']]
x_data = torch.FloatTensor(x_data.values)
y_data = torch.FloatTensor(y_data.values)
print(x_data.shape)
print(y_data.shape)
|
torch.Size([8779, 1]) torch.Size([8779, 1]) |
- 텐서의 내용 출력
x_data
y_data
|
tensor([[-8.7000], [-7.3000], [-6.7000], ..., [-7.3000], [-9.0000], [-9.2000]]) ----------------------------- tensor([[-2.9000], [-2.4000], [-2.2000], ..., [-1.2000], [-1.5000], [-1.2000]]) |
- 산점도(Scatter plot)를 그리기
plt.figure(figsize=(8, 6))
plt.scatter(x_data, y_data)
|
![]() |
- 1차원 입력과 1차원 출력을 가지는 선형 회귀 모델을 정의
확률적 경사 하강법(SGD) 옵티마이저를 설정
모델의 초기 가중치와 편향을 출력
model = nn.Linear(1, 1)
optimizer = torch.optim.SGD(model.parameters(), lr=0.001)
print(list(model.parameters())) # W: -0.5700, b: 0.2403
|
[Parameter containing: tensor([[-0.5700]], requires_grad=True), Parameter containing: tensor([0.2403], requires_grad=True)] |
- 선형 회귀 모델 학습
epochs = 10000
for epoch in range(epochs + 1):
y_pred = model(x_data)
loss = nn.MSELoss()(y_pred, y_data)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if epoch % 100 == 0:
print(f'Epoch: {epoch}/{epochs} Loss: {loss:.6f}')
|
Epoch: 0/10000 Loss: 727.285767 Epoch: 100/10000 Loss: 13.042105 Epoch: 200/10000 Loss: 13.029263 Epoch: 300/10000 Loss: 13.018347 Epoch: 400/10000 Loss: 13.009065 Epoch: 500/10000 Loss: 13.001172 Epoch: 600/10000 Loss: 12.994462 Epoch: 700/10000 Loss: 12.988756 Epoch: 800/10000 Loss: 12.983907 Epoch: 900/10000 Loss: 12.979782 Epoch: 1000/10000 Loss: 12.976276 Epoch: 1100/10000 Loss: 12.973297 Epoch: 1200/10000 Loss: 12.970764 ............... Epoch: 9300/10000 Loss: 12.956378 Epoch: 9400/10000 Loss: 12.956378 Epoch: 9500/10000 Loss: 12.956379 Epoch: 9600/10000 Loss: 12.956379 Epoch: 9700/10000 Loss: 12.956379 Epoch: 9800/10000 Loss: 12.956379 Epoch: 9900/10000 Loss: 12.956379 Epoch: 10000/10000 Loss: 12.956379 |
- 학습이 진행된 후의 선형 회귀 모델의 파라미터(가중치 W와 편향 b) 값을 출력
list(model.parameters()) # W: 1.0854, b: 0.8199
|
[Parameter containing: tensor([[1.0854]], requires_grad=True), Parameter containing: tensor([0.8198], requires_grad=True)] |
- 입력 데이터 x_data에 대한 예측값을 계산하고, 이 값을 NumPy 배열로 변환하여 출력
y_pred = model(x_data).detach().numpy()
y_pred
|
array([[-8.623071], [-7.103529], [-6.452296], ..., [-7.103529], [-8.948688], [-9.165765]], dtype=float32) |
- 데이터 포인트와 학습된 모델에 의한 예측 포인트를 포함하는 산점도 그리기
plt.figure(figsize=(8, 6))
plt.scatter(x_data, y_data)
plt.scatter(x_data, y_pred)
|
![]() |
- 새로운 입력 데이터에 대한 예측값을 계산
result = model(torch.FloatTensor([[26]]))
result
|
tensor([[29.0399]], grad_fn=<AddmmBackward0>) |
|
'AI > 딥러닝' 카테고리의 다른 글
06. 비선형 활성화 함수 (0) | 2024.06.20 |
---|---|
05. 딥러닝 (0) | 2024.06.20 |
04. 데이터로더(Data Loader) (0) | 2024.06.20 |
03. 논리회귀 (단항, 다중) | 시그모이드(sigmoid) 함수 (0) | 2024.06.19 |
01. 파이토치(Pytorch) (0) | 2024.06.18 |