[DL Wizard] Convolutional Neural Network with PyTorch 번역 및 정리

2020. 2. 6. 22:15nlp

반응형

https://www.deeplearningwizard.com/deep_learning/practical_pytorch/pytorch_convolutional_neuralnetwork/

 

Convolutional Neural Networks (CNN) - Deep Learning Wizard

Convolutional Neural Network with PyTorch About Convolutional Neural Network Transition From Feedforward Neural Network Hidden Layer Feedforward Neural Network Recap of FNN So let's do a recap of what we covered in the Feedforward Neural Network (FNN) sect

www.deeplearningwizard.com

 

파이토치로 CNN 모델 만들기

 

Model A

- 2 Conv, Same Padding

* Same Padding : input size = output size 이도록 padding

- 2 Max Pooling

- 1 FC(=Fully Connected)

 

 

- 입력 데이터는 MNIST 사진 데이터 (채널 1, 가로*세로 28*28)

- batch size = 100

 

Build Model

 

class CNNModel(nn.Module):
    def __init__(self):
        super(CNNModel, self).__init__()
        
        # Conv 1
        # out_channels=16이라는 것은 적용할 필터(커널) 개수가 16개라는 것 
        # cnn1 출력 크기 : 가로*세로=28*28, 채널 크기=16
        # 가로/세로 공식 적용하면 (28+2*2-5)/1 +1 = 28 : 입력 때와 크기 같음
        self.cnn1 = nn.Conv2d(in_channels=1, out_channels=16, kernel_size=5, stride=1, padding=2)
        self.relu1 = nn.ReLU()
        
        # Max pool1
        # maxpool1 출력 크기 = 가로*세로=14*14, 채널 크기=16
        # 가로/세로 공식 적용하면 28/2 = 14
        self.maxpool1 = nn.MaxPool2d(kernel_size=2)
        
        # Conv 2
        # cnn2 출력 크기 = 가로*세로=14*14, 채널 크기=32
        # 가로/세로 공식 적용하면 (14+2*2-5)/1 + 1 = 14 : 입력 때와 크기 같음
        self.cnn2 = nn.Conv2d(in_channels=16, out_channels=32, kernel_size=5, stride=1, padding=2)
        self.relu2 = nn.ReLU()
        
        # Max pool2
        # maxpool2 출력 크기 = 가로*세로=7*7, 채널 크기=32
        # 가로/세로 공식 적용하면 14/2 = 7
        self.maxpool2 = nn.MaxPool2d(kernel_size=2)
        
        # Fully connected 1 (readout)
        self.fc1 = nn.Linear(32*7*7, 10)
        
    def forward(self, x):
        # Conv1
        out = self.cnn1(x)
        out = self.relu1(out)
        
        # Max pool1
        out = self.maxpool1(out)
        
        # Conv2
        out = self.cnn2(out)
        out = self.relu2(out)
        
        # Max pool2
        out = self.maxpool2(out)
        
        # FC 레이어에 넣기 위해 Reshape
        # 원래 크기 : (100, 32, 7, 7)
        # reshape 후 크기 : (100, 32*7*7)
        # out.size(0) = 100 (batch_size)
        out = out.view(out.size(0), -1)
        
        # Linear Function (readout)
        out = self.fc1(out)
        
        return out

 

Instantiate Model

 

model = CNNModel()

 

Instantiate Loss

 

criterion = nn.CrossEntropyLoss()

 

Instatiate Optimizer

 

learning_rate = 0.01
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)

 

Parameter 자세히 보기 

 

• 전체 파라미터 개수 = 6

- len(list(model.parameters()))

- conv1 필터 파라미터, conv1 편향 파라미터, conv2 필터 파라미터, conv2 편향 파라미터, FC 가중치 파라미터, FC 편향 파라미터로 6개 

 

• conv1 필터 파라미터

- list(model.parameters())[0].size() # [16,1,5,5]

- 필터(커널) 개수가 16개 (∵ output_channels=16)

- 채널은 1개 (∵ 흑백 사진)

- 필터 크기는 5*5 (∵ kernel_size=5)

 

• conv1 편향 파라미터

- list(model.parameters())[1].size() # [16]

 - 필터(커널) 개수가 16개니까 

 

• conv2 필터 파라미터

- list(model.parameters())[2].size() # [32,16,5,5]

- 필터(커널) 개수가 32개 (∵ out_channels=32)

- 채널은 16개 (∵ in_channels=16)

- 필터 크기는 5*5 (∵ kernel_size=5)

 

• conv2 편향 파라미터

- list(model.parameters())[3].size() # [32]

 - 필터(커널) 개수가 32개니까 

 

• FC 가중치 파라미터

- list(model.parameters())[4].size() # [10, 1568]

- FC 레이어의 입력 : (100, 32*7*7) = (100, 1568)

- FC 레이어의 출력 : (100, 10) 

- 0-9, 10개의 숫자 각각에 해당하는 확률이나까 10, 미니배치 크기가 100이니까 100

 

• FC 편향 파라미터

- list(model.parameters())[5].size() # [10]

- 0-9, 10개 숫자 각각에 대한 편향 

 

 

Train Model

 

iter = 0
for epoch in range(num_epochs):
    for i, (images, labels) in enumerate(train_loader):
        # Load images
        images = images.requires_grad_()

        # Clear gradients w.r.t. parameters
        optimizer.zero_grad()

        # Forward pass to get output/logits
        outputs = model(images)

        # Calculate Loss: softmax --> cross entropy loss
        loss = criterion(outputs, labels)

        # Getting gradients w.r.t. parameters
        loss.backward()

        # Updating parameters
        optimizer.step()

        iter += 1

        if iter % 500 == 0:
            # Calculate Accuracy         
            correct = 0
            total = 0
            # Iterate through test dataset
            for images, labels in test_loader:
                # Load images
                images = images.requires_grad_()

                # Forward pass only to get logits/output
                outputs = model(images)

                # Get predictions from the maximum value
                _, predicted = torch.max(outputs.data, 1)

                # Total number of labels
                total += labels.size(0)

                # Total correct predictions
                correct += (predicted == labels).sum()

            accuracy = 100 * correct / total

            # Print Loss
            print('Iteration: {}. Loss: {}. Accuracy: {}'.format(iter, loss.item(), accuracy))

 

Model B

- 2 Conv, Same Padding

* Same Padding : input size = output size 이도록 padding

- 2 Average Pooling

- 1 FC(=Fully Connected)

 

 

차이점

 

# Average pool1
self.avgpool1 = nn.AvgPool2d(kernel_size=2)

# Average pool2
self. avgpool2 = nn.AvgPool2d(kernel_size=2)

 

Model C

- 2 Conv, Valid Padding

* Valid Padding : input size > output size 이도록 padding

- 2 Max Pooling

- 1 FC(=Fully Connected)

 

차이점

 

# Conv1
self.cnn1 = nn.Conv2d(in_channels=1, out_channels=16, kernel_size=5, stride=1, padding=0)

# Conv 2
self.cnn2 = nn.Conv2d(in_channels=16, out_channels=32, kernel_size=5, stride=1, padding=0)

 

 

반응형