2020. 2. 6. 22:15ㆍnlp
파이토치로 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)
'nlp' 카테고리의 다른 글
[DL Wizard] Recurrent Neural Network with PyTorch 번역 및 정리 (0) | 2020.02.08 |
---|---|
그림으로 보는 RNN/LSTM과 GRU 번역 및 정리 (0) | 2020.02.07 |
CNN for NLP 번역 및 정리 (0) | 2020.02.06 |
CNN : Convolutional Neural Network 정리 (0) | 2020.02.06 |
[DL Wizard] Weight Initializations & Activation Functions 번역 및 정리 (0) | 2020.02.05 |