코딩걸음마

[딥러닝] Pytorch 선형결합층(Linear_layer) 본문

딥러닝_Pytorch

[딥러닝] Pytorch 선형결합층(Linear_layer)

코딩걸음마 2022. 6. 26. 17:20
728x90

1. Linear layer의 작동 구조

인공신경망(NN)은 연속적인 함수전달체계를 이루고 있다. 어떤 정보가 입력되었을때 그 정보에 대한 강도를 어느정도로 할 것인지 또한 보정값을 얼마나 줄 것인지 정할 수 있다. 입력값과 출력값이 선형관계 즉 y = ax=b 라고 할 때 다음 방법을 사용할 수 있다.

import torch
W = torch.FloatTensor([[1, 2],
                       [3, 4],
                       [5, 6],
                       [7, 8]]
                     )

b = torch.FloatTensor([4, 2])

가중치(w)와 보정값(b)

그럼 주어진 가중치와 보정값으로 선형 결합층(Linear Layer)함수를 만들어보자

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

이제 입력데이터에 값을 입력하면, 선형결합층을 통과하여 출력층 y가 나오게 된다.

그러면 입력데이터를 생성하고 입력해보자

x = torch.FloatTensor([[1, 1, 1 ,1],
                       [2, 2, 2, 2],
                       [3, 3, 3, 3],
                       [4, 4, 4, 4]])

print(x.size())
y = linear(x, W, b)

 

 

2. nn.Module을 활용한 Linear layer의 작동

다행히도 위에서 확인한 Linear layer 함수를 매번 만들필요 없다.

nn.Module 클래스를 상속받은 클래스를 하나 생성하여 반복적으로 사용할 것이다.

아래의 코드를 보자

import torch.nn as nn
class MyLinear(nn.Module):
    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)

nn.Module 클래스를 상속받은 MyLinear클래스를 생성하고 

__init__ 으로 입력층의 차원과 출력층의 차원을 입력 받습니다.

 

그리고 w와 b에 각각 (n,m), (m)을 지정해준다.

class MyLinear(nn.Module):

    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)

    # You should override 'forward' method to implement detail.
    # The input arguments and outputs can be designed as you wish.
    def forward(self, x):
        # |x| = (batch_size, input_dim)
        y = torch.matmul(x, self.W) + self.b
        # |y| = (batch_size, input_dim) * (input_dim, output_dim)
        #     = (batch_size, output_dim)
        
        return y

이 코드에서는 아래 코드를 입력시 parmeters 출력이 안된다는 점이 있다.

for p in linear.parameters():
    print(p)

 

 

그러므로 다음의 코드를 사용하자

class MyLinear(nn.Module):

    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):
        # |x| = (batch_size, input_dim)
        y = torch.matmul(x, self.W) + self.b
        # |y| = (batch_size, input_dim) * (input_dim, output_dim)
        #     = (batch_size, output_dim)
        
        return y
linear = MyLinear(4, 2)

y = linear(x)
for p in linear.parameters():
    print(p)
Parameter containing:
tensor([[0., 0.],
        [0., 0.],
        [0., 0.],
        [0., 0.]], requires_grad=True)
Parameter containing:
tensor([6.1879e-03, 4.5911e-41], requires_grad=True)

 

 

 

위 코드를 더 축약해서 w,b 부분의 nn~ 뒷 코드를 더 축약하여 표현하면 다음과 같다.

 

class MyLinear(nn.Module):

    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):
        # |x| = (batch_size, input_dim)
        y = self.linear(x)
        # |y| = (batch_size, output_dim)
        
        return y
linear = MyLinear(4, 2)

y = linear(x)
print(y.size())
torch.Size([4, 2])
for i in linear.parameters():
    print(i)
Parameter containing:
tensor([[-0.1525,  0.4783,  0.2501,  0.2255],
        [ 0.2465, -0.4301, -0.0415, -0.4306]], requires_grad=True)
Parameter containing:
tensor([-0.2435, -0.0917], requires_grad=True)
728x90
Comments