pytorch CNN 모델 output shape 관련 질문

24.05.04 02:51 작성 24.05.04 02:51 수정 조회수 23

0

CIFAR10 데이터셋을 이용해서 cnn을 구현하고 training 실습을 하는데 계속 모델의 output shape과 관련해서 CrossEntropyLoss를 이용해서 loss를 계산하는 부분에서

ValueError: Expected input batch_size (1) to match target batch_size (4).

와 같은 에러가 발생합니다.

input과 labels의 배치 사이즈에 따라 마지막 output의 shape이 torch.Size([4, 10])와 같이 나와야 정상적으로 loss를 계산할 수 있을텐데 계속해서 torch.Size([1, 10])의 shape이 나옵니다.

혹시몰라 좀 더 간단한 다른 모델로 구현해보니 정상적으로 batch_size가 일치하는데 해당 모델을 이용할 때만 오류가 발생합니다.

batch_size를 바꿔가면서 테스트해보니 모델에 어떤 문제로 인해 계속 output의 batch_size가 설정한 batch_size의 1/4로 나오게 되는 것 같은데 모델에서 어떤 부분이 문제인지 못 찾겠습니다.

CNN 모델은 아래와 같이 구현했습니다. 모델의 output shape이 정상적으로 torch.Size([batch_size, 10])과 같이 나올 수 있으려면 어떻게 해결해야 할까요?

class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()

        # Layer#1
        self.conv1 = nn.Conv2d(in_channels=3, out_channels=64, kernel_size=3)
        self.conv2 = nn.Conv2d(in_channels=64, out_channels=64, kernel_size=3)

        self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
        self.dropout = nn.Dropout(0.5)

        # Layer#2
        self.conv3 = nn.Conv2d(in_channels=64, out_channels=128, kernel_size=3)

        # Layer#3
        self.conv4 = nn.Conv2d(in_channels=128, out_channels=256, kernel_size=3)

        # Layer#4
        self.fc1 = nn.Linear(4*4*256, 512)
        # Layer#5
        self.fc2 = nn.Linear(512, 512)
        # Layer#6
        self.fc3 = nn.Linear(512, 10)



    def forward(self, x):

        # Layer#1
        x = self.conv1(x)
        x = F.relu(x)
        x = self.dropout(x)
        x = self.conv2(x)
        x = F.relu(x)
        x = self.dropout(x)
        x = self.pool(x)

        # Layer#2
        x = self.conv3(x)
        x = F.relu(x)
        x = self.dropout(x)
        x = self.pool(x)

        # Layer#3
        x = self.conv4(x)
        x = F.relu(x)
        x = self.dropout(x)
        x = self.pool(x)

        # Layer#4
        x = x.view(-1, 4*4*256)
        x = self.fc1(x)
        x = F.relu(x)

        # Layer#5
        x = self.fc2(x)
        x = F.relu(x)

        # Layer#6
        x = self.fc3(x)
        x = F.softmax(x)

        return x

답변 1

답변을 작성해보세요.

0

인프런 AI 인턴님의 프로필

인프런 AI 인턴

2024.05.05

안녕하세요, 인프런 AI 인턴입니다.

jjun4662님의 질문에 답변드리겠습니다. CIFAR10 데이터셋을 사용하여 CNN 모델을 학습시킬 때 발생하는 output shape 관련 문제는 일반적으로 모델의 구조나 데이터의 배치 처리 과정에서 발생할 수 있습니다. 여러분의 코드를 봤을 때, 모델 구조 자체에는 큰 문제가 없어 보입니다. 하지만, 마지막 레이어에서 F.softmax를 사용하고 계신데, CrossEntropyLoss를 사용할 경우 이 함수는 내부적으로 softmax 계산을 포함하고 있기 때문에, 모델의 마지막 출력에서 F.softmax를 사용하지 않아야 합니다.

따라서, 모델의 마지막 레이어에서 F.softmax(x) 대신 x를 그대로 반환하도록 변경해보세요. PyTorch의 CrossEntropyLoss는 로짓(logit)을 입력으로 받으며, 내부적으로 softmax를 계산합니다. 따라서, 모델의 출력을 그대로 loss 함수에 전달하면 되겠습니다.

# Layer#6
x = self.fc3(x)
# x = F.softmax(x)는 제거합니다.
return x

또한, 언급하신 문제가 여전히 발생한다면, 데이터 로더의 batch_size 설정을 다시 확인해보시길 바랍니다. 모델의 입력과 레이블의 배치 사이즈가 일치하는지 확인하는 것이 중요합니다. PyTorch에서 데이터 로더를 설정할 때 사용하는 batch_size 파라미터가 모든 배치에 대해 일관되게 적용되고 있는지 확인해보세요.

이 조정을 통해 모델의 출력 배치 사이즈 문제를 해결할 수 있을 것입니다. 모델 학습에 성공하시길 바랍니다!