파이토치(선형 회귀)

짬그브·2025년 3월 24일

선형 회귀

딥러닝은 자그마한 통계의 결과들이 무수히 얽히고설켜 이루어지는 복잡한 연산의 결정체
딥러닝을 이해하려면 딥러닝의 가장 말단에서 이루어지는 가장 기본적인 두 가지 계산원리, 선형회귀로지스틱 회귀 를 알아야함
가장 훌륭한 예측선 긋기란 통계학 용어인 선형 회귀 (linear regression)를 쉽게 풀어서 쓴 것
머신러닝은 제대로 된 선을 긋는 작업부터 시작됨
선의 방향을 잘 정하면 그 선을 따라가는 것만으로도 지금은 보이지 않는 미래의 것을 예측할 수 있기 때문

선형 회귀의 정의

"학생들의 중간고사 성적이 다 다르다."

위 문장이 나타낼 수 있는 정보는 너무 제한적
학급의 학생마다 제각각 성적이 다르다는 당연한 사실 외에는 알 수 있는 게 없음

"학생들의 중간고사 성적이 [ ] 에 따라 다 다르다."

이 문장은 정보가 담길 여지를 열어 놓고 있음
[ ] 부분에 시험 성적을 좌우할 만한 여러 가지 것이 들어간다면 좀 더 많은 사실을 전달할 수 있음
예를 들면 공부한 시간, 시험 당일의 컨디션, 사교육비 지출액 등이 들어갈 수 있음
무엇이 들어가든지 해당 성적의 이유를 나름대로 타당하게 설명할 수 있음
따라서 이 문장이 중간고사 성적의 차이와 이유를 나타낼 때 더욱 효과적

여기서 [ ]에 들어갈 내용을 '정보' 라고 함
머신러닝과 딥러닝은 이 정보가 필요함
-> 많은 정보가 더 정확한 예측을 가능케하며, 이때의 '많은 정보'가 곧 '빅데이터'

독립 변수 x 하나만으로는 정확히 설명할 수 없을 때는 x 값을 여러 개(x1,x2,x3 등) 준비한다.
하나의 x 값만으로도 y 값을 설명 할 수 있을 때 이를 단순 선형 회귀 (simple linear regression) 라고 함
x 값이 여러 개 필요할 때는 다중 선형 회귀 (multiple linear regression)라고 함

import torch

w = torch.tensor(2., requires_grad=True)
y = 7 * w
y.backward()
print('w 로 미분한 값:', w.grad)
print()

w2 = torch.tensor(3.,requires_grad=True)
for epoch in range(20):
    y2 = 5 * w2
    y2.backward()
    print('w2로 미분한 값:',w2.grad)
    w2.grad.zero_()


w 로 미분한 값: tensor(7.)

w2로 미분한 값: tensor(5.)
w2로 미분한 값: tensor(5.)
w2로 미분한 값: tensor(5.)
w2로 미분한 값: tensor(5.)
w2로 미분한 값: tensor(5.)
w2로 미분한 값: tensor(5.)
w2로 미분한 값: tensor(5.)
w2로 미분한 값: tensor(5.)
w2로 미분한 값: tensor(5.)
w2로 미분한 값: tensor(5.)
w2로 미분한 값: tensor(5.)
w2로 미분한 값: tensor(5.)
w2로 미분한 값: tensor(5.)
w2로 미분한 값: tensor(5.)
w2로 미분한 값: tensor(5.)
w2로 미분한 값: tensor(5.)
w2로 미분한 값: tensor(5.)
w2로 미분한 값: tensor(5.)
w2로 미분한 값: tensor(5.)
w2로 미분한 값: tensor(5.)

다중 선형 회귀

import torch
x1_train = torch.FloatTensor([[73],[93],[89],[96],[73]])
x2_train = torch.FloatTensor([[88],[88],[91],[98],[65]])
x3_train = torch.FloatTensor([[75],[92],[98],[100],[70]])
y_train = torch.FloatTensor([[152],[185],[180],[196],[142]])

w1 = torch.zeros((1,1), requires_grad=True)
w2 = torch.zeros((1,1), requires_grad=True)
w3 = torch.zeros((1,1), requires_grad=True)
b = torch.zeros(1, requires_grad=True)

import torch.optim as optim

optimizer = optim.SGD([w1,w2,w3,b],lr=1e-5)

for epoch in range(1000):
    hypothesis = torch.mm(x1_train, w1) + torch.mm(x2_train, w2) + torch.mm(x3_train, w3) + b
    loss = torch.mean((hypothesis - y_train) ** 2)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    if epoch % 100 == 0:
        print(f'epoch:{epoch+1},w1:{w1.item()},w2:{w2.item()},w3: {w3.item()},b:{b.item()}, loss{loss.item():.3f}')
        

epoch:1,w1:0.29401201009750366,w2:0.29789599776268005,w3: 0.30239999294281006,b:0.0034199999645352364, loss29661.801
epoch:101,w1:0.6779763102531433,w2:0.6380272507667542,w3: 0.6730436682701111,b:0.00775424437597394, loss13.526
epoch:201,w1:0.7012343406677246,w2:0.6150785684585571,w3: 0.6730748414993286,b:0.00790213979780674, loss12.457
epoch:301,w1:0.7233471870422363,w2:0.5937857031822205,w3: 0.6725858449935913,b:0.0080468924716115, loss11.513
epoch:401,w1:0.7443873286247253,w2:0.5740330815315247,w3: 0.6716203093528748,b:0.00818843673914671, loss10.678
epoch:501,w1:0.7644217014312744,w2:0.5557137727737427,w3: 0.6702187061309814,b:0.008326703682541847, loss9.938
epoch:601,w1:0.783513069152832,w2:0.5387276411056519,w3: 0.6684189438819885,b:0.008461643010377884, loss9.281
epoch:701,w1:0.8017199039459229,w2:0.5229817628860474,w3: 0.6662552952766418,b:0.008593201637268066, loss8.696
epoch:801,w1:0.8190968632698059,w2:0.5083893537521362,w3: 0.6637607216835022,b:0.00872134231030941, loss8.175
epoch:901,w1:0.8356946110725403,w2:0.4948699474334717,w3: 0.660965085029602,b:0.008846033364534378, loss7.708

다른방법

import torch
x_train = torch.FloatTensor([[73,80,75],
                             [93,88,93],
                             [89,91,88],
                             [96,98,100],
                             [73,66,70]])

y_train = torch.FloatTensor([[152],[185],[180],[196],[142]])

W = torch.zeros((3,1), requires_grad=True)
b = torch.zeros(1, requires_grad=True)

import torch.optim as optim

optimizer = optim.SGD([W,b],lr=1e-5)

for epoch in range(1000):
    hypothesis = x_train.matmul(W) + b
    loss = torch.mean((hypothesis - y_train) ** 2)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    if epoch % 100 == 0:
        print(f'epoch:{epoch+1}, {W}')

epoch:1, tensor([[0.2940],
        [0.2936],
        [0.2959]], requires_grad=True)
epoch:101, tensor([[0.6754],
        [0.6639],
        [0.6748]], requires_grad=True)
epoch:201, tensor([[0.6805],
        [0.6587],
        [0.6749]], requires_grad=True)
epoch:301, tensor([[0.6855],
        [0.6536],
        [0.6750]], requires_grad=True)
epoch:401, tensor([[0.6904],
        [0.6486],
        [0.6750]], requires_grad=True)
epoch:501, tensor([[0.6952],
        [0.6438],
        [0.6751]], requires_grad=True)
epoch:601, tensor([[0.6998],
        [0.6391],
        [0.6751]], requires_grad=True)
epoch:701, tensor([[0.7044],
        [0.6346],
        [0.6750]], requires_grad=True)
epoch:801, tensor([[0.7089],
        [0.6302],
        [0.6750]], requires_grad=True)
epoch:901, tensor([[0.7132],
        [0.6259],
        [0.6749]], requires_grad=True)

다른방법 2

import torch
x_train = torch.FloatTensor([[73,80,75],
                             [93,88,93],
                             [89,91,88],
                             [96,98,100],
                             [73,66,70]])

y_train = torch.FloatTensor([[152],[185],[180],[196],[142]])



import torch.nn as nn

model = nn.Linear(3,1)


import torch.optim as optim

optimizer = optim.SGD(model.parameters(),lr=1e-5)

for epoch in range(1000):
    hypothesis = model(x_train)
    loss = torch.mean((hypothesis - y_train) ** 2)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    if epoch % 100 == 0:
        print(f'epoch:{epoch+1}', end=' ')
        for param in model.parameters():
            print(param, end=' ')
        print()

epoch:1 Parameter containing:
tensor([[0.2177, 0.0552, 0.3283]], requires_grad=True) Parameter containing:
tensor([0.3690], requires_grad=True) 
epoch:101 Parameter containing:
tensor([[0.6891, 0.5209, 0.7988]], requires_grad=True) Parameter containing:
tensor([0.3746], requires_grad=True) 
epoch:201 Parameter containing:
tensor([[0.6921, 0.5189, 0.7978]], requires_grad=True) Parameter containing:
tensor([0.3747], requires_grad=True) 
epoch:301 Parameter containing:
tensor([[0.6950, 0.5169, 0.7968]], requires_grad=True) Parameter containing:
tensor([0.3749], requires_grad=True) 
epoch:401 Parameter containing:
tensor([[0.6979, 0.5150, 0.7958]], requires_grad=True) Parameter containing:
tensor([0.3750], requires_grad=True) 
epoch:501 Parameter containing:
tensor([[0.7008, 0.5132, 0.7948]], requires_grad=True) Parameter containing:
tensor([0.3751], requires_grad=True) 
epoch:601 Parameter containing:
tensor([[0.7036, 0.5114, 0.7938]], requires_grad=True) Parameter containing:
tensor([0.3752], requires_grad=True) 
epoch:701 Parameter containing:
tensor([[0.7064, 0.5097, 0.7928]], requires_grad=True) Parameter containing:
tensor([0.3754], requires_grad=True) 
epoch:801 Parameter containing:
tensor([[0.7091, 0.5080, 0.7918]], requires_grad=True) Parameter containing:
tensor([0.3755], requires_grad=True) 
epoch:901 Parameter containing:
tensor([[0.7117, 0.5064, 0.7907]], requires_grad=True) Parameter containing:
tensor([0.3756], requires_grad=True) 

다른방법 3

import torch
x_train = torch.FloatTensor([[73,80,75],
                             [93,88,93],
                             [89,91,88],
                             [96,98,100],
                             [73,66,70]])

y_train = torch.FloatTensor([[152],[185],[180],[196],[142]])



import torch.nn as nn

model = nn.Linear(3,1)


import torch.optim as optim

optimizer = optim.SGD(model.parameters(),lr=1e-5)
loss_func = nn.MSELoss()


for epoch in range(1000):
    hypothesis = model(x_train)
    loss = loss_func(hypothesis,y_train)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    if epoch % 100 == 0:
        print(f'epoch:{epoch+1}', end=' ')
        for param in model.parameters():
            print(param, end=' ')
        print()

epoch:1 Parameter containing:
tensor([[ 0.5792,  0.5215, -0.2209]], requires_grad=True) Parameter containing:
tensor([-0.2632], requires_grad=True) 
epoch:101 Parameter containing:
tensor([[0.9646, 0.8923, 0.1639]], requires_grad=True) Parameter containing:
tensor([-0.2588], requires_grad=True) 
epoch:201 Parameter containing:
tensor([[0.9701, 0.8841, 0.1665]], requires_grad=True) Parameter containing:
tensor([-0.2588], requires_grad=True) 
epoch:301 Parameter containing:
tensor([[0.9756, 0.8762, 0.1690]], requires_grad=True) Parameter containing:
tensor([-0.2587], requires_grad=True) 
epoch:401 Parameter containing:
tensor([[0.9808, 0.8684, 0.1715]], requires_grad=True) Parameter containing:
tensor([-0.2587], requires_grad=True) 
epoch:501 Parameter containing:
tensor([[0.9859, 0.8609, 0.1739]], requires_grad=True) Parameter containing:
tensor([-0.2587], requires_grad=True) 
epoch:601 Parameter containing:
tensor([[0.9909, 0.8535, 0.1763]], requires_grad=True) Parameter containing:
tensor([-0.2587], requires_grad=True) 
epoch:701 Parameter containing:
tensor([[0.9957, 0.8464, 0.1786]], requires_grad=True) Parameter containing:
tensor([-0.2587], requires_grad=True) 
epoch:801 Parameter containing:
tensor([[1.0004, 0.8394, 0.1809]], requires_grad=True) Parameter containing:
tensor([-0.2587], requires_grad=True) 
epoch:901 Parameter containing:
tensor([[1.0049, 0.8326, 0.1831]], requires_grad=True) Parameter containing:
tensor([-0.2587], requires_grad=True) 
profile
+AI to AI+

0개의 댓글