본문 바로가기
AI/딥러닝

[AI 부트캠프] DAY 89 - 트랙학습 CV 3

by HOHHOH 2023. 11. 25.

[오늘의 일지]

트랙학습 실시간 강의 - 컬러 이미지 분류 모델 실습

[상세 내용]

컬러 이미지 분류 모델 실습

컬러 이미지 불러오기

- 이번 컬러 이미지도 토치비전을 이용해서  CIFAR10라는 데이터를 불러와서 tensor를 통해 정규화를 시켜서 학습에 맞는 형식으로 변환을 시켰습니다. 

transform = transforms.Compose(
    [transforms.ToTensor(),
     transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])

batch_size = 4

trainset = torchvision.datasets.CIFAR10(root='./data', train=True,
                                        download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=batch_size,
                                          shuffle=True, num_workers=2)

testset = torchvision.datasets.CIFAR10(root='./data', train=False,
                                       download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=batch_size,
                                         shuffle=True, num_workers=2)

classes = ('plane', 'car', 'bird', 'cat',
           'deer', 'dog', 'frog', 'horse', 'ship', 'truck')

 

이미지 예시

 

CNN을 nn.Sequential 없이 구현해 보기

- 엊그제 실습에서는 nn.Sequential을 사용해서 괄호 안에 한꺼번에 구현을 했었는데 이번에는 없이 구현하는 것을 연습해 보았습니다. 눈으로 보이는 것은 확실히 코드량이 많아져서 비효율적이긴 했지만 하나씩 추가하면서 pooling을 계산하고 연습하기에는 나쁘지 않았습니다.

import torch.nn as nn
import torch.nn.functional as F


class Net(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = nn.Conv2d(3, 16, 3, padding=1)
        self.conv2 = nn.Conv2d(16, 32, 3, padding=1)
        self.conv3 = nn.Conv2d(32, 64, 3, padding=1)
        self.pool = nn.MaxPool2d(2, 2)
        self.relu = nn.ReLU()
        self.flatten = nn.Flatten()
        self.fc1 = nn.Linear(64*8*8, 512)
        self.fc2 = nn.Linear(512, 256)
        self.fc3 = nn.Linear(256, 10)

    def forward(self, x):
        x = self.conv1(x)
        x = self.relu(x)
        x = self.pool(x)
        x = self.conv2(x)
        x = self.relu(x)
        x = self.pool(x)
        x = self.conv3(x)
        x = self.relu(x)
        x = self.flatten(x)
        x = self.fc1(x)
        x = self.relu(x)
        x = self.fc2(x)
        x= self.relu(x)
        x = self.fc3(x)
        return x


net = Net()
net.to(device)

 

학습 결과

- 컬러 이미지라서 그런지 엊그제 했던 실습 데이터인 fashion MNIST 보다 정확도가 나오지 않았습니다. 그리고 이상한 점은 제가 코드를 잘 못 짜서 그런지도 모르겠는데 GPU를 사용할 때마다 학습할 때 loss 함숫값이 계속 0으로 나와서 정확한 결과를 얻지 못했고 여러 가지 옵티마이저를 바꿔가면서 학습을 해보았는데 정확도가 약 70%가 최적의 결과였던 거 같습니다.

for epoch in range(4):   # 데이터셋을 수차례 반복합니다.

    running_loss = 0.0
    for i, data in enumerate(trainloader, 0):
        inputs, labels = data
        inputs, labels = inputs.to(device), labels.to(device)

        # 변화도(Gradient) 매개변수를 0으로 만들고
        optimizer.zero_grad()

        # 순전파 + 역전파 + 최적화를 한 후
        net.train()
        outputs = net(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        # 통계를 출력합니다.
        running_loss += loss.item()
        if i % 2000 == 1999:    # print every 2000 mini-batches
            print(f'[{epoch + 1}, {i + 1:5d}] loss: {running_loss / 2000:.3f}')
            running_loss = 0.0

print('Finished Training')

 

correct = 0
total = 0
# 학습 중이 아니므로, 출력에 대한 변화도를 계산할 필요가 없습니다
with torch.no_grad():
    for data in testloader:
        images, labels = data
        # 신경망에 이미지를 통과시켜 출력을 계산합니다
        outputs = net(images)
        # 가장 높은 값(energy)를 갖는 분류(class)를 정답으로 선택하겠습니다
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

print(f'Accuracy of the network on the 10000 test images: {100 * correct // total} %')

>>>>>>>>>>>>>>>
Accuracy of the network on the 10000 test images: 70 %

 

# 각 분류(class)에 대한 예측값 계산을 위해 준비
correct_pred = {classname: 0 for classname in classes}
total_pred = {classname: 0 for classname in classes}

# 변화도는 여전히 필요하지 않습니다
with torch.no_grad():
    for data in testloader:
        images, labels = data
        outputs = net(images)
        _, predictions = torch.max(outputs, 1)
        # 각 분류별로 올바른 예측 수를 모읍니다
        for label, prediction in zip(labels, predictions):
            if label == prediction:
                correct_pred[classes[label]] += 1
            total_pred[classes[label]] += 1


# 각 분류별 정확도(accuracy)를 출력합니다
for classname, correct_count in correct_pred.items():
    accuracy = 100 * float(correct_count) / total_pred[classname]
    print(f'Accuracy for class: {classname:5s} is {accuracy:.1f} %')
    
>>>>>>>>>>>>>>>>>>>>

Accuracy for class: plane is 69.2 %
Accuracy for class: car   is 80.7 %
Accuracy for class: bird  is 55.6 %
Accuracy for class: cat   is 75.5 %
Accuracy for class: deer  is 63.1 %
Accuracy for class: dog   is 52.9 %
Accuracy for class: frog  is 67.1 %
Accuracy for class: horse is 76.0 %
Accuracy for class: ship  is 79.1 %
Accuracy for class: truck is 81.6 %

 

[마무리]

 오늘은 어제의 어려웠던 온라인 수업 대신에 다시 실시간 강의가 있었습니다. 수업은 CNN 코드를 이용해서 연습을 해보고 한 번 더 코드를 짜는 연습을 하면서 학습 코드에 익숙해지기 좋은 과정이었습니다. 저는 아직 차원에 관한 부분을 완벽하게 이해하지 못했기 때문에 그 부분을 더 공부해서 보완하면 좋겠다고 판단했습니다.

반응형

댓글