티스토리 뷰
CNN case study 01 VGGNet
학습 목표: VGGNet을 직접 구현해보고 CIFAR10 데이터셋 분류 모델을 학습 시켜 본다. 또한 pre-trained VGGNET을 CIFAR10 데이터 셋으로 fine-tuning하는 방법을 학습한다.
import torch
import torch.nn as nn
import torchvision.datasets as datasets
import torchvision.transforms as transforms
1.2 VGGNet 모델 설명
VGGNet은 3x3 사이즈의 필터로 구성된 컨볼루션 레이어를 사용한다.
3x3 필터 사이즈의 컨볼루션 레이어를 두 번 거치면 receptive field가 5x5가 된다. 그리고 세번 거치면 7x7이 된다.
하지만 똑같은 receptive field를 가지는 5x5 필터를 사용하면 25개의 파라미터를 학습해야 하는 것에 비해, 3x3 필터를 두번 사용하면 9+9=18개의 파라미터를 학습하면 된다.
따라서 VGGNet은 파라미터 수가 더 많은 CNN모델과 비교했을 때, 같은 크기의 receptive field를 가지면서 더 적은 파라미터 수를 학습할 수 있다는 장점이 있다.
VGGNet은 아래 그림처럼 16개의 레이어와 19개의 레이어를 사용하는 VGG16과 VGG19의 두가지 버전이 있다. 본 실습에서는 VGG19을 구현한다.
1.2 VGGNet 모델 구현
VGG19은 그림과 같이 3x3 필터로 구성된 컨볼루션 레이어를 연속으로 두번 적용하거나 네번 적용한 후 pooling 연산을 적용하는 구조가 반복되는 모델이다.
반복되어 사용되는 컨볼루션 레이어를 두번 거치고 풀링을 적용하는 블럭을 정의한다.
# Conv Layer 2개로 구성된 ConvBlock 구현
class ConvBlock1(nn.Module):
def __init__(self, in_dim, out_dim):
super(ConvBlock1, self).__init__()
self.in_dim = in_dim
self.out_dim = out_dim
self.main = nn.Sequential(nn.Conv2d(self.in_dim, self.out_dim, kernel_size=3, padding=1),
nn.BatchNorm2d(self.out_dim),
nn.ReLU(),
nn.Conv2d(self.out_dim, self.out_dim, kernel_size=3, padding=1),
nn.BatchNorm2d(self.out_dim),
nn.ReLU(),
nn.MaxPool2d(2)
)
def forward(self, x):
out = self.main(x)
return out
<코드 설명>
1. 클래스 및 초기화 메서드 정의
class ConvBlock1(nn.Module):
* ConvBlock1는 PyTorch의 기본 모듈 클래스 nn.Module을 상속받는 클래스를 정의합니다. 이 클래스는 네트워크의 하나의 블록을 구성하는 역할을 합니다.
def __init__(self, in_dim, out_dim):
super(ConvBlock1, self).__init__()
- __init__ 메서드는 이 클래스의 생성자입니다. in_dim과 out_dim은 각각 입력과 출력의 채널 수를 정의합니다.
- super(ConvBlock1, self).__init__()은 상위 클래스(nn.Module)의 생성자를 호출하여 부모 클래스의 초기화 과정을 실행합니다.
2. 인스턴스 변수 할당
self.in_dim = in_dim
self.out_dim = out_dim
- in_dim과 out_dim을 클래스 인스턴스의 변수로 할당합니다. 이후 이 변수를 사용하여 신경망의 레이어를 구성합니다.
3. 신경망 구성
self.main = nn.Sequential(
- nn.Sequential은 여러 레이어를 순차적으로 쌓아주는 모듈입니다. self.main에 이 모듈을 할당하여 이후 forward 메서드에서 사용할 수 있게 합니다.
4. 첫 번째 컨볼루션 층
nn.Conv2d(self.in_dim, self.out_dim, kernel_size=3, padding=1),
- nn.Conv2d는 2D 컨볼루션 레이어를 정의합니다. 여기서 in_dim은 입력 채널 수, out_dim은 출력 채널 수, kernel_size=3은 3x3 필터를 사용하며, padding=1은 출력 이미지 크기가 입력 이미지 크기와 동일하게 유지되도록 합니다.
5. 배치 정규화
nn.BatchNorm2d(self.out_dim),
- nn.BatchNorm2d는 2D 배치 정규화를 수행하는 레이어입니다. 배치 정규화는 학습을 안정화하고 속도를 높여줍니다. self.out_dim은 채널 수를 의미합니다.
6. ReLU 활성화 함수
nn.ReLU(),
- nn.ReLU는 비선형 활성화 함수인 ReLU(Rectified Linear Unit)를 적용합니다. ReLU는 음수를 0으로 바꾸고 양수는 그대로 유지합니다.
7. 두 번째 컨볼루션 층
nn.Conv2d(self.out_dim, self.out_dim, kernel_size=3, padding=1),
- 두 번째 컨볼루션 층입니다. 이번에도 3x3 필터와 동일한 padding을 사용하지만, 입력과 출력 채널 수가 모두 self.out_dim으로 동일합니다.
10. Max Pooling 레이어
nn.MaxPool2d(2)
- nn.MaxPool2d(2)는 2x2 크기의 윈도우로 Max Pooling을 수행하는 레이어입니다. 이 레이어는 입력의 공간적 크기를 줄이는 데 사용됩니다. 여기서는 2x2 영역에서 가장 큰 값을 선택하여 공간적 크기를 절반으로 줄입니다.
11. Forward 메서드 정의
def forward(self, x):
out = self.main(x)
return out
- forward 메서드는 모델이 입력을 받아서 출력을 생성하는 과정입니다. x는 입력 데이터이고, out은 처리된 출력입니다.
- 입력 x는 self.main에 정의된 순차적인 레이어를 통해 순차적으로 처리되며, 최종 출력이 반환됩니다.
-----
위에서 구현된 코드 검증
conv_block = ConvBlock1(64, 128)
dummy_x = torch.randn([2,64,64,64])
dummy_pred = conv_block(dummy_x)
print(dummy_pred.shape)
dummy_x가 forward(self, x)의 x로 들어가는 것. torch는 인스턴스 만들면 forward를 바로 가져온다고함.
그리고 x가 레이어를 탄 결과값이 retrun 된다고 함.
1. ConvBlock1 클래스의 인스턴스 생성
conv_block = ConvBlock1(64, 128)
- 여기서 ConvBlock1(64, 128)는 ConvBlock1 클래스의 인스턴스를 생성하는 코드입니다.
- 64는 입력 채널 수 (in_dim), 128은 출력 채널 수 (out_dim)입니다.
- conv_block 변수는 이제 64개의 입력 채널을 받아 128개의 출력 채널을 생성하는 컨볼루션 블록을 가리킵니다.
2. 더미 입력 데이터 생성
dummy_x = torch.randn([2, 64, 64, 64])
- torch.randn([2, 64, 64, 64])는 무작위 값으로 구성된 텐서를 생성합니다.
- torch.randn는 평균이 0이고 표준편차가 1인 정규분포에서 무작위 값을 샘플링합니다.
- 생성된 텐서의 크기는 [2, 64, 64, 64]입니다.
- 2는 배치 크기(batch size)를 나타내며, 한 번에 2개의 이미지를 처리할 수 있습니다.
- 64는 채널 수(channel), 64x64는 이미지의 가로와 세로 크기를 의미합니다.
- 즉, dummy_x는 2개의 64채널 이미지를 가지며, 각 이미지의 크기는 64x64입니다.
3. 컨볼루션 블록을 통과시켜 출력 생성
dummy_pred = conv_block(dummy_x)
- conv_block(dummy_x)는 더미 데이터를 conv_block에 입력하고, 처리된 결과를 dummy_pred에 저장합니다.
- ConvBlock1의 forward 메서드가 호출되어, dummy_x가 ConvBlock1 내부의 레이어들을 순차적으로 통과하면서 변환됩니다.
4. 출력 텐서의 크기 확인
print(dummy_pred.shape)
- dummy_pred.shape는 출력 텐서의 크기를 반환합니다.
- 이를 출력하여 결과적으로 컨볼루션 블록을 통과한 데이터의 크기를 확인할 수 있습니다.
5. 출력 크기 설명
이제 이 블록을 통과한 결과인 dummy_pred.shape가 어떻게 계산되는지 설명하겠습니다:
- 첫 번째 컨볼루션 레이어:
- 입력: [2, 64, 64, 64]
- 출력: [2, 128, 64, 64] (채널 수가 64 → 128로 증가)
- 첫 번째 배치 정규화 및 ReLU:
- 출력: [2, 128, 64, 64] (크기 변화 없음)
- 두 번째 컨볼루션 레이어:
- 출력: [2, 128, 64, 64] (채널 수 유지)
- 두 번째 배치 정규화 및 ReLU:
- 출력: [2, 128, 64, 64] (크기 변화 없음)
- Max Pooling 레이어:
- 출력: [2, 128, 32, 32] (Max Pooling에 의해 가로와 세로 크기가 64 → 32로 절반으로 줄어듦)
최종 출력의 크기는 [2, 128, 32, 32]가 됩니다.
----
위에서 정의한 두 블럭을 이용하여 VGG19 정의
class VGG19(nn.Module):
def __init__(self, in_dim, out_dim):
super(VGG19, self).__init__()
self.convlayer1 = ConvBlock1(in_dim, 64)
self.convlayer2 = ConvBlock1(64, 128)
self.convlayer3 = ConvBlock2(128, 256)
self.convlayer4 = ConvBlock2(256, 512)
self.convlayer5 = ConvBlock2(512, 512)
self.linear = nn.Sequential(
nn.Linear(512, 512),
nn.ReLU(),
nn.Linear(512, 128),
nn.ReLU(),
nn.Linear(128, out_dim),
)
def forward(self, input):
out = self.convlayer1(input)
out = self.convlayer2(out)
out = self.convlayer3(out)
out = self.convlayer4(out)
out = self.convlayer5(out).squeeze() # 16 x 512 x 1 x 1에서 뒤 1 x 1 축약
out = self.linear(out)
return out
이 VGG19 클래스는 PyTorch의 nn.Module을 상속받아 구현된 모델로, 주로 이미지 분류 작업에 사용됩니다. 이 클래스는 VGG19 아키텍처를 기반으로 하며, 여러 개의 컨볼루션 블록과 완전 연결(fully connected) 레이어로 구성됩니다. 이 클래스의 각 줄을 하나씩 설명하겠습니다.
1. 클래스 및 초기화 메서드 정의
class VGG19(nn.Module):
def __init__(self, in_dim, out_dim):
super(VGG19, self).__init__()
- VGG19 클래스는 nn.Module을 상속받아 정의된 신경망 모델입니다.
- __init__ 메서드는 모델의 생성자입니다. in_dim과 out_dim은 입력 채널 수와 출력 클래스 수를 정의합니다.
- super(VGG19, self).__init__()은 부모 클래스의 초기화 메서드를 호출합니다.
2. 첫 번째 컨볼루션 레이어 블록
self.convlayer1 = ConvBlock1(in_dim, 64)
- ConvBlock1을 이용하여 첫 번째 컨볼루션 블록을 정의합니다.
- in_dim은 입력 채널 수, 64는 출력 채널 수입니다.
3. 두 번째 컨볼루션 레이어 블록
self.convlayer2 = ConvBlock1(64, 128)
- 두 번째 컨볼루션 블록을 정의합니다.
- 64는 이전 블록의 출력 채널 수, 128은 이 블록의 출력 채널 수입니다.
4. 세 번째 컨볼루션 레이어 블록
self.convlayer3 = ConvBlock2(128, 256)
- ConvBlock2를 사용하여 세 번째 컨볼루션 블록을 정의합니다.
- 128은 입력 채널 수, 256은 출력 채널 수입니다.
- ConvBlock2는 ConvBlock1과 비슷하지만, 컨볼루션 레이어의 구성이 다를 수 있습니다 (예를 들어, 더 많은 레이어나 추가적인 연산이 포함될 수 있습니다).
5. 네 번째 컨볼루션 레이어 블록
self.convlayer4 = ConvBlock2(256, 512)
- 네 번째 컨볼루션 블록을 정의합니다.
- 256은 입력 채널 수, 512는 출력 채널 수입니다.
6. 다섯 번째 컨볼루션 레이어 블록
self.convlayer5 = ConvBlock2(512, 512)
- 다섯 번째 컨볼루션 블록을 정의합니다.
- 512는 입력 채널 수와 출력 채널 수로, 이 블록은 입력을 512 채널로 유지하면서 처리합니다.
7. 완전 연결(fully connected) 레이어 정의
self.linear = nn.Sequential(
nn.Linear(512, 512),
nn.ReLU(),
nn.Linear(512, 128),
nn.ReLU(),
nn.Linear(128, out_dim),
)
- nn.Sequential을 사용하여 완전 연결 레이어를 정의합니다.
- 첫 번째 nn.Linear(512, 512)는 512차원의 입력을 받아 512차원의 출력을 생성합니다.
- 다음으로 ReLU()가 비선형 활성화 함수를 적용합니다.
- 두 번째 nn.Linear(512, 128)는 512차원의 입력을 128차원으로 변환합니다.
- 또 다른 ReLU()가 활성화 함수를 적용합니다.
- 마지막 nn.Linear(128, out_dim)은 128차원의 입력을 받아 out_dim 차원의 출력을 생성합니다. out_dim은 분류할 클래스의 수입니다.
8. Forward 메서드 정의
def forward(self, input):
out = self.convlayer1(input)
out = self.convlayer2(out)
out = self.convlayer3(out)
out = self.convlayer4(out)
out = self.convlayer5(out).squeeze() # 16 x 512 x 1 x 1에서 뒤 1 x 1 축약
out = self.linear(out)
return out
- forward 메서드는 모델이 입력 데이터를 받아서 순차적으로 연산을 수행하여 최종 출력을 생성하는 과정입니다.
- 입력 input은 각 컨볼루션 레이어를 통과하며 차원이 변경됩니다.
- input은 처음에 self.convlayer1에 의해 처리되고, 그 결과는 self.convlayer2로 전달됩니다.
- 이런 방식으로 입력 데이터는 순차적으로 모든 컨볼루션 레이어를 통과합니다.
- 마지막 컨볼루션 블록 self.convlayer5를 통과한 후 출력은 out 변수에 저장됩니다.
- 여기서 squeeze()는 텐서의 크기가 [batch_size, 512, 1, 1]에서 [batch_size, 512]로 변경됩니다. 이는 마지막 두 차원 (1x1)을 제거하기 위함입니다.
- 이후 out은 완전 연결 레이어 self.linear를 통과하여 최종 출력이 생성됩니다.
- 이 출력은 주로 분류 작업에서 클래스별 확률 또는 예측 값을 나타냅니다.
요약
- 이 VGG19 모델은 여러 개의 컨볼루션 블록을 통해 입력 데이터를 처리하고, 마지막에 완전 연결 레이어를 통해 최종 클래스를 예측합니다.
- 각 컨볼루션 블록은 입력을 변환하고, 맥스 풀링을 통해 데이터의 공간적 크기를 줄이면서 특징을 추출합니다.
- 마지막에는 데이터의 차원을 줄이고, 완전 연결 레이어에서 이를 최종 클래스 레이블로 변환합니다.
---
VGG모델 학습하기
import torchvision.models as models
tell_time = Timer()
iter_time = 0
vgg19 = vgg19.cuda() # VGG19 모델 instance를 생성
criterion = nn.CrossEntropyLoss() # cross entrophy loss 함수 정의
optimizer = torch.optim.Adam(vgg19.parameters(), lr=learning_rate) # 학습할 모델의 parameter와 learning rate를 인자로 주어 optimizer 정의
accuracy_list = []
for epoch in range(num_epochs):
vgg19.train()
for i, (images, labels) in enumerate(train_loader):
images = images.cuda()
labels = labels.cuda()
optimizer.zero_grad()
outputs = vgg19(images)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
if (i+1) % 100 == 0:
print ('Epoch [%d/%d], Iter [%d/%d] Loss: %.4f, iter_time: %2.2f'
%(epoch+1, num_epochs, i+1, len(train_dataset)//batch_size, loss.item(), tell_time.toc()-iter_time))
iter_time = tell_time.toc()
accuracy_list = test_on_cifar10(vgg19, accuracy_list)
acc_plot(accuracy_list)
이 코드는 PyTorch를 사용하여 VGG19 모델을 학습시키고, 주기적으로 손실(loss)을 출력하며, 학습 과정 중에 정확도(accuracy)를 평가하는 코드입니다. 코드의 각 부분을 설명해드리겠습니다.
1. Timer 인스턴스 및 변수 초기화
tell_time = Timer()
iter_time = 0
- Timer()는 학습 시간을 측정하기 위한 타이머 객체를 생성합니다.
- iter_time은 반복(iteration) 시간 추적에 사용될 변수입니다.
2. VGG19 모델 인스턴스 생성 및 GPU로 이동
vgg19 = vgg19.cuda()
- vgg19는 VGG19 모델의 인스턴스를 생성합니다. (코드에서 vgg19는 torchvision.models의 VGG19 모델일 것으로 예상됩니다.)
- .cuda()는 모델을 GPU로 이동시킵니다. 이 함수 호출로 인해 모델이 CUDA 호환 GPU에서 연산되도록 합니다.
3. 손실 함수와 옵티마이저 정의
criterion = nn.CrossEntropyLoss()
- nn.CrossEntropyLoss()는 분류 문제에서 자주 사용되는 손실 함수로, 교차 엔트로피 손실을 계산합니다. 출력과 실제 레이블 간의 차이를 측정합니다.
optimizer = torch.optim.Adam(vgg19.parameters(), lr=learning_rate)
- torch.optim.Adam은 Adam 최적화 알고리즘을 사용하여 모델의 매개변수를 업데이트합니다.
- vgg19.parameters()는 모델의 학습 가능한 파라미터를 반환하고, lr=learning_rate는 학습률을 설정합니다.
4. 학습 루프
accuracy_list = []
for epoch in range(num_epochs):
vgg19.train()
- accuracy_list는 각 에폭(epoch) 후의 정확도를 저장할 리스트입니다.
- for epoch in range(num_epochs)는 전체 학습 데이터셋을 여러 번 반복하는 에폭 루프를 시작합니다.
- vgg19.train()는 모델을 학습 모드로 설정합니다. 이는 드롭아웃(dropout) 및 배치 정규화(batch normalization)와 같은 학습 전용 모드를 활성화합니다.
5. 미니 배치 학습
for i, (images, labels) in enumerate(train_loader):
images = images.cuda()
labels = labels.cuda()
- train_loader는 학습 데이터의 미니 배치를 반복합니다. images와 labels는 각각 입력 이미지와 해당 레이블입니다.
- images와 labels를 .cuda()를 호출하여 GPU로 이동시킵니다.
6. 옵티마이저 업데이트
optimizer.zero_grad()
outputs = vgg19(images)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
- optimizer.zero_grad()는 이전 반복에서 계산된 기울기(gradient)를 초기화합니다.
- vgg19(images)는 현재 배치의 이미지에 대한 예측을 생성합니다.
- criterion(outputs, labels)는 모델의 출력과 실제 레이블 간의 손실을 계산합니다.
- loss.backward()는 손실에 대한 기울기를 계산하여 각 매개변수의 업데이트 방향을 제공합니다.
- optimizer.step()은 계산된 기울기를 사용하여 매개변수를 업데이트합니다.
7. 학습 진행 상황 출력
if (i+1) % 100 == 0:
print ('Epoch [%d/%d], Iter [%d/%d] Loss: %.4f, iter_time: %2.2f'
%(epoch+1, num_epochs, i+1, len(train_dataset)//batch_size, loss.item(), tell_time.toc()-iter_time))
iter_time = tell_time.toc()
accuracy_list = test_on_cifar10(vgg19, accuracy_list)
- (i+1) % 100 == 0는 매 100번째 반복마다 학습 진행 상황을 출력합니다.
- 출력된 내용에는 현재 에폭, 반복 횟수, 손실 값, 반복 시간 등이 포함됩니다.
- tell_time.toc()는 타이머의 현재 시간을 반환하며, iter_time과의 차이를 통해 소요 시간을 측정합니다.
- test_on_cifar10(vgg19, accuracy_list)는 모델을 CIFAR-10 데이터셋에서 테스트하고 정확도를 업데이트합니다. 이 함수는 accuracy_list에 정확도 정보를 추가합니다.
8. 정확도 플로팅
acc_plot(accuracy_list)
- 각 에폭이 끝난 후 accuracy_list를 이용해 정확도를 시각화하는 함수 acc_plot을 호출합니다.
- accuracy_list는 각 에폭에서 측정된 정확도를 포함하고 있으며, 이를 플로팅하여 학습 과정 중 정확도의 변화를 시각적으로 확인할 수 있습니다.
요약
- 이 코드는 VGG19 모델을 CIFAR-10 데이터셋으로 학습시키는 과정을 정의합니다.
- 모델의 매개변수를 업데이트하고, 손실을 모니터링하며, 주기적으로 학습 시간을 출력하고 정확도를 평가합니다.
- 학습이 완료된 후, 정확도 변화를 시각화하여 학습 성과를 확인할 수 있습니다.
---
pre trained 모델 사용
class pretrained_vgg(nn.Module):
def __init__(self, pre_vgg):
super(pretrained_vgg, self).__init__()
self.features = nn.Sequential(
*list(pre_vgg.features.children())
)
# Pre-trained VGG19 모델의 fully connected layer만 CIFAR10 데이터에 맞게 변경
self.linear = nn.Sequential(
nn.Linear(512, 512),
nn.ReLU(),
nn.Linear(512, 128),
nn.ReLU(),
nn.Linear(128, 10),
)
def forward(self, x):
out = self.features(x).squeeze()
out = self.linear(out)
return out
이 pretrained_vgg 클래스는 PyTorch의 nn.Module을 상속받아 만든 모델로, 사전 학습된(pretrained) VGG19 모델의 특성 추출 기능을 활용하면서, 출력 레이어를 CIFAR-10 데이터셋에 맞게 조정한 것입니다. 이 클래스를 자세히 설명해 드리겠습니다.
1. 클래스 정의 및 초기화 메서드
class pretrained_vgg(nn.Module):
def __init__(self, pre_vgg):
super(pretrained_vgg, self).__init__()
- pretrained_vgg 클래스는 nn.Module을 상속받아 정의된 신경망 모델입니다.
- __init__ 메서드는 이 클래스의 생성자로, pre_vgg는 사전 학습된 VGG19 모델의 인스턴스를 나타냅니다.
- super(pretrained_vgg, self).__init__()은 부모 클래스 nn.Module의 초기화 메서드를 호출하여 기본 초기화 작업을 수행합니다.
2. 특징 추출 레이어 정의
self.features = nn.Sequential(
*list(pre_vgg.features.children())
)
- self.features는 VGG19 모델의 특징 추출 레이어(컨볼루션과 풀링 레이어)를 정의합니다.
- pre_vgg.features는 사전 학습된 VGG19 모델의 특징 추출 부분을 가져옵니다.
- list(pre_vgg.features.children())는 특징 추출 부분의 자식 레이어들을 리스트로 변환합니다.
- *list(pre_vgg.features.children())는 이 리스트를 언팩하여 nn.Sequential로 래핑합니다. 이를 통해 사전 학습된 VGG19의 컨볼루션 레이어들을 그대로 사용할 수 있습니다.
3. 완전 연결(fully connected) 레이어 정의
self.linear = nn.Sequential(
nn.Linear(512, 512),
nn.ReLU(),
nn.Linear(512, 128),
nn.ReLU(),
nn.Linear(128, 10),
)
- self.linear는 CIFAR-10 데이터셋에 맞게 조정된 완전 연결 레이어를 정의합니다.
- 첫 번째 nn.Linear(512, 512)는 512차원의 입력을 받아 512차원의 출력을 생성합니다.
- ReLU()는 비선형 활성화 함수로, 첫 번째 Linear 레이어의 출력을 활성화합니다.
- 두 번째 nn.Linear(512, 128)는 512차원의 입력을 128차원으로 변환합니다.
- 또 다른 ReLU()가 두 번째 Linear 레이어의 출력을 활성화합니다.
- 마지막 nn.Linear(128, 10)은 128차원의 입력을 10차원으로 변환합니다. 여기서 10은 CIFAR-10의 클래스 수를 나타내며, 최종 출력은 각 클래스에 대한 점수입니다.
4. Forward 메서드 정의
def forward(self, x):
out = self.features(x).squeeze()
out = self.linear(out)
return out
- forward 메서드는 모델이 입력 데이터를 처리하여 출력을 생성하는 과정입니다.
- x는 입력 데이터입니다.
- self.features(x)는 입력 x를 사전 학습된 VGG19의 특징 추출 레이어를 통해 처리합니다.
- squeeze()는 텐서의 차원을 축소합니다. VGG19의 마지막 레이어에서 [batch_size, 512, 1, 1] 형태의 출력을 [batch_size, 512]로 변경합니다. 이는 이미지가 각 채널에 대해 1x1의 특징 맵을 가지기 때문입니다.
- self.linear(out)는 축소된 특징 벡터 out을 완전 연결 레이어를 통해 최종 클래스 점수로 변환합니다.
- 최종적으로, out은 CIFAR-10 데이터셋의 각 클래스에 대한 점수를 나타내는 텐서입니다.
요약
- 이 pretrained_vgg 클래스는 사전 학습된 VGG19 모델의 특징 추출 기능을 재사용하면서, CIFAR-10 데이터셋에 맞게 출력 레이어를 조정합니다.
- features 레이어는 VGG19의 컨볼루션과 풀링 레이어를 포함하며, linear 레이어는 CIFAR-10의 클래스 수에 맞게 조정된 완전 연결 레이어입니다.
- forward 메서드는 입력 이미지를 특징 추출 레이어를 통해 처리하고, 축소된 특징 벡터를 완전 연결 레이어를 통해 최종 클래스 점수로 변환합니다.
'torch' 카테고리의 다른 글
07-04 자연어 처리를 위한 1D CNN 연습문제 풀이 (Pytorch Conv1D 예제) (0) | 2023.01.15 |
---|---|
다층 퍼셉트론으로 MNIST 분류하기 (실습 코드 최신 버전) (0) | 2023.01.15 |
XOR gate (0) | 2023.01.15 |
- Total
- Today
- Yesterday