PyTorch 기초 - 선형 계층

ingeol·2023년 2월 14일
0

pytorch

목록 보기
1/5

파이토치 기초 - 선형계층

import torch
x = torch.FloatTensor([[1,2],[3,4],[5,6]])
y = torch.FloatTensor([[1,2],[1,2]])
print(x.size(), y.size())
# -> torch.Size([3, 2]) torch.Size([2, 2])
z = torch.matmul(x,y)
print(z.size())
# -> torch.Size([3, 2])

bmm함수는 행렬 곱이 3번 수행되는 연산을 병렬로 동시에 진행 가능하다.

x = torch.FloatTensor(3,3,2)
y = torch.FloatTensor(3,2,3)

z = torch.bmm(x,y)
print(z.size())
# -> torch.Size([3, 3, 3])
W = torch.FloatTensor([[1,2],[3,4],[5,6]])
b = torch.FloatTensor([2,2])

def linear(x, W, b):
    y = torch.matmul(x, W) + b

    return y

x = torch.FloatTensor(4,3)
print(linear(x,W,b).size())
# -> torch.Size([4, 2])

파이토치에는 nn 패키지가 있고 torch.nn.Module 이라는 추상 클래스를 상속 받아 정의 되어 있다.

  • nn.Module을 상속받은 클래스는 2개의 메서드, init, forward를 오버라이드(override)한다.
  • init 함수는 계층 내부에 필요한 변수 선언, 다른 계층을 소유할 수 있다.
  • forward함수는 계층을 통과하는데 필요한 계산 수행한다.
import torch.nn as nn
class MyLinear(nn.Module):
    # __init__ 과 forward override. 
    # __init__ 은 계층 내부에 필요한 변수 선언 및 다른 계층을 소유할 수 있다.

    def __init__(self, input_dim = 3, output_dim = 2):
        self.input_dim = input_dim
        self.output_dim = output_dim

        super().__init__()

        self.W = torch.FloatTensor(input_dim, output_dim)
        self.b = torch.FloatTensor(output_dim)

    def forward(self, x):
        y = torch.matmul(x, self.W) + self.b

        return y

linear = MyLinear(3,2)
y = linear(x) # forward는 직접 호출할 필요가 없다. __call__과 nn.Module은 매핑되어 있음.
print(y)
'''
tensor([[2.1715e-18, 1.3298e+22],
        [2.1715e-18, 1.3298e+22],
        [2.1715e-18, 1.3298e+22],
        [2.1715e-18, 1.3298e+22]])
'''
for p in linear.parameters():
    print(p)
#- > 아무것도 나오지 않는다.

nn.Parameter

위의 코드는 내부에 학습할 수 있는 파라미터가 없는 것으로 인식해서 위의 for 문장에 아무것도 출력되지 않는다.

아래의 nn.Parameter 클래스를 활용하여 파라미터가 출력 가능하게 만든다.

class MyLinear(nn.Module):
    # __init__ 과 forward override. 
    # __init__ 은 계층 내부에 필요한 변수 선언 및 다른 계층을 소유할 수 있다.

    def __init__(self, input_dim = 3, output_dim = 2):
        self.input_dim = input_dim
        self.output_dim = output_dim

        super().__init__()

        self.W = nn.Parameter(torch.FloatTensor(input_dim, output_dim))
        self.b = nn.Parameter(torch.FloatTensor(output_dim))

    def forward(self, x):
        y = torch.matmul(x, self.W) + self.b

        return y
for p in linear.parameters():
    print(p)
'''
Parameter containing:
tensor([[1.7377e-35, 0.0000e+00],
        [5.3811e-38, 0.0000e+00],
        [0.0000e+00, 0.0000e+00]], requires_grad=True)
Parameter containing:
tensor([-1.8174e+34,  4.5649e-41], requires_grad=True)
'''

torch.nn 사용

위에는 복잡한 방법으로 선형계층을 보였지만 간단한 방법도 존재한다.

torch.nn에 미리 정의된 선형 계층을 불러 쓰면 간단해 진다.


x = torch.FloatTensor(4,3)
linear = nn.Linear(3,2)
y = linear(x)

for p in linear.parameters():
    print(p)
'''
Parameter containing:
tensor([[-0.2501, -0.4086,  0.3287],
        [ 0.1874, -0.5189,  0.5299]], requires_grad=True)
Parameter containing:
tensor([ 0.2059, -0.0335], requires_grad=True)
'''
class MyLinear(nn.Module):
    # __init__ 과 forward override. 
    # __init__ 은 계층 내부에 필요한 변수 선언 및 다른 계층을 소유할 수 있다.

    def __init__(self, input_dim = 3, output_dim = 2):
        self.input_dim = input_dim
        self.output_dim = output_dim

        super().__init__()

        self.linear = nn.Linear(input_dim, output_dim)

    def forward(self, x):
        y = self.linear(x)

        return y

0개의 댓글