파이토치를 이용해 학습을 하려는 도중에 아래와 같은 오류가 발생했다.
오류메세지:
AttributeError: 'tuple' object has no attribute 'size'
나는 현재 BCEWithLogitsLoss 손실함수를 사용하며 이진분류를 진행하고 있다.
이 에러는 input과 target의 크기가 다른 것으로, 둘 중 하나가 튜플(tuple) 형태로 되어있어 .size() 메소드를 호출할 수 없다는 것을 의미한다.
for epoch in range(1, args['epoch'] + 1):
model.train()
running_corrects = 0
for videos, labels in tqdm(iter(train_loader), leave=False, desc='Train', ascii=' ='):
videos = videos.to(device)
labels = labels.unsqueeze(1).float().to(device)
print('videos.shape: ', videos.shape)
print('labels.shape: ', labels.shape)
optimizer.zero_grad()
output = model(videos)
위 코드에서 output = model(videos) 부분에서 output의 shape이 [배치크기, 1]로 나와야 하는데 그렇지 않을 것으로 예상되었다.
그래서 네트워크를 구성하는 코드를 살펴보았다.
def forward(self, x):
x = self.conv1(x)
x = self.bn1(x)
x = self.relu(x)
x = self.dropout(x)
if not self.no_max_pool:
x = self.maxpool(x)
x = self.layer1(x)
x = self.dropout(x)
x = self.layer2(x)
x = self.dropout(x)
x = self.layer3(x)
x = self.dropout(x)
x_conv = self.layer4(x)
x = self.dropout(x_conv)
x = self.avgpool(x)
x = x.view(x.size(0), -1)
x = self.fc(x)
return x, x_conv
역시나 forward 함수에서 x와 x_conv를 모두 return 받고 있었다. 이로 인해 output의 shape이 예상과 달랐다.
그래서 내가 원하는 x만 return 받게 return x로 바꿔주었다.