(02강) 뉴럴 네트워크 - MLP (Multi-Layer Perceptron)

  • 신경망의 정의, Deep Neural Network

  • Pytorch를 활용한 MLP(Multi-Layer Perceptron) 실습

  • Regression Task, Classification Task, Probabilistic Task의 Loss 함수(or 클래스)는 Pytorch에서 어떻게 구현이 되어있을까요?

  • 참고 페이지: pytorch official docs

1. Neural Networks 란?

  • 인간의 뇌 신경을 모방하여 만든 컴퓨터 시스템

  • 비선형 변환이 반복적으로 이루어져 함수를 근사하는 시스템

Neural networks are function approximators that stack affine transformations followed by nonlinear transformations

1.1. Linear Neural Networks

선형회귀 입력이 1차원이고, 출력이 1차원일 때 이 둘을 연결하는 모델을 찾는

  • Data: 1차원 N개의 input과 output

  • Model: w와 b를 찾는 것

  • Loss: 이루고자 하는 현상이 이루어졌을때 줄어드는 함수 (MSE 사용)

  • Back Propergation을 활용해서 업데이트해 최적의 w, b를 찾는다(Gradient Descent)

  • (step size)가 너무 크면 최소값에 수렴하지 않을 수 있고, 너무 작으면 Local Mimimum에 빠질 수있다.

1.2. Multi dimensional in/out

1.3. Deep Learning

  • Network를 깊게 쌓으면서 표현할 수 있는 영역을 키워주기 위해서는 Activation Function으로 비선형 근사를 시켜주는 과정이 필요하다.

  • ❓저게 왜 더 많은 표현력을 가지게 해주는 것일까?

Activation Function

1.4. Multi-Layer Perceptron

Loss Function

Loss Function의 성질을 이해하고, 이 함수가 왜 내가 원하는 결과를 얻을 수 있는지 이해할 것

  • MSE(Mean Squared Error)

  • CE(Cross Entropy)

  • MLE(Maximum Likelyhood Estimation)

    ※ Probabilistic Task : Output이 숫자가 아닌 확률적인 부분을 추정하고 싶을 때 사용된다.

class MultiLayerPerceptronClass(nn.Module):
    """
        Multilayer Perceptron (MLP) Class
    """
    def __init__(self,name='mlp',xdim=784, hdim=256, ydim=10): # xdim = 28 * 28 픽셀의 바운딩박스, hdim = 256(Hyper Param), ydim = 0~9의 기대값 추출
        super(MultiLayerPerceptronClass,self).__init__()
        self.name = name
        self.xdim = xdim
        self.hdim = hdim
        self.ydim = ydim
        self.lin_1 = nn.Linear(  # h = W2x
            # FILL IN HERE
            self.xdim, self.hdim
        )
        self.lin_2 = nn.Linear( # y = w2h
            # FILL IN HERE
            self.hdim, self.ydim
        )
        self.init_param() # initialize parameters
        
    def init_param(self):
        nn.init.kaiming_normal_(self.lin_1.weight) #He initialization 함수들
        nn.init.zeros_(self.lin_1.bias)
        nn.init.kaiming_normal_(self.lin_2.weight)
        nn.init.zeros_(self.lin_2.bias)

    def forward(self,x):
        net = x
        net = self.lin_1(net)
        net = F.relu(net) # activation function
        net = self.lin_2(net)
        return net

M = MultiLayerPerceptronClass(name='mlp',xdim=784, hdim=256, ydim=10).to(device)
loss = nn.CrossEntropyLoss()
optm = optim.Adam(M.parameters(),lr=1e-3)
#print(M.parameters())
print ("Done.")
print ("Start training.")
M.init_param() # initialize parameters
M.train()
EPOCHS,print_every = 10,1
for epoch in range(EPOCHS):
    loss_val_sum = 0
    for batch_in, batch_out in train_iter:
        # Forward path
        y_pred = M.forward(batch_in.view(-1, 28*28).to(device))
        loss_out = loss(y_pred,batch_out.to(device)) # nn.CrossEntropyLoss()
        # Update
        # FILL IN HERE      # reset gradient 
        optm.zero_grad()
        # FILL IN HERE      # backpropagate
        loss_out.backward() # 미분해서 각각의 그래디언트 백터를 구해주고
        # FILL IN HERE      # optimizer update
        optm.step()         # 원래 파라미터의 그래디언트를 적용
        loss_val_sum += loss_out
    loss_val_avg = loss_val_sum/len(train_iter)
    # Print
    if ((epoch%print_every)==0) or (epoch==(EPOCHS-1)):
        train_accr = func_eval(M,train_iter,device)
        test_accr = func_eval(M,test_iter,device)
        print ("epoch:[%d] loss:[%.3f] train_accr:[%.3f] test_accr:[%.3f]."%
               (epoch,loss_val_avg,train_accr,test_accr))
print ("Done")

Last updated