작성
·
5
0
안녕하세요 강사님
섹션 2의 CNN 실습(100_CIFAR10_CNN.ipynb) 관련하여 질문드립니다.
아래 코드에서는 train_loss에 배치별 loss를 누적한 뒤, for문이 끝나면 train_loss /= len(train_data) 로 평균을 계산하고 있습니다.
그런데 loss.item()은 이미 각 배치에서 평균이 적용된 스칼라 값입니다.
따라서 다시 전체 데이터 개수(len(train_data))로 나누면 이중으로 평균이 계산되는 것 같습니다.
그래서 저는 train_loss += loss.item() * x.size(0) 형태로 배치 손실의 합계를 누적한 뒤, 마지막에 전체 데이터 수로 나누는 방식이보다 정확하다고 생각하는데, 혹시 어떻게 생각하실까요?
좋은 강의 제공해주셔서 감사합니다.
for x, y in train_loader: # 훈련 데이터셋을 배치 단위로 순회
x, y = x.to(device), y.to(device) # 배치 데이터를 현재 디바이스로 이동
optimizer.zero_grad() # 이전 그라디언트를 초기화
z = model(x) # 모델을 통해 예측값 계산
loss = criterion(z, y) # 예측값과 실제 레이블 간의 손실 계산
train_loss += loss.item() # 손실 누적
y_pred = z.argmax(1) # 가장 높은 예측값의 인덱스를 정답으로 선택
train_acc += (y_pred == y).sum().item() # 정확히 예측된 개수 누적
loss.backward() # 손실에 대한 그라디언트 계산
optimizer.step() # 모델의 가중치 업데이트
train_loss /= len(train_data) # 평균 훈련 손실 계산
train_acc /= len(train_data) # 평균 훈련 정확도 계산
LOSS.append(train_loss)
ACC.append(train_acc)
답변 2
0
맞습니다. 현재 코드는 train_loss /= len(train_loader) 로 수정해서 batch 갯수로 나누어야 합니다. accuracy 는 현재 처럼 train_acc /= len(train_data) 나누면 됩니다.
batch size 가 다른 경우 제안하신 대로 코딩하는 것이 가장 정확한 방법이지만 손실값을 계산하는 목적은 그 값이 줄어들고 있는지 비교하는 목적이므로 매우 정확한 값을 계산하지 않아도 지장 없습니다.
교재에서도 train_loss /= len(train_loader) 로 수정해 놓았습니다.
좋은 지적 감사합니다.
0
안녕하세요, 인프런 AI 인턴입니다.
질문해 주신 내용은 딥러닝 모델 훈련 시 손실(loss)의 계산 방법에 관한 깊이 있는 논의로, 많은 학습자들이 헷갈려할 수 있는 부분입니다. loss.item()
메서드는 손실 값을 실제 값으로 반환하며, 각 배치에서의 평균 손실을 나타냅니다.
현재 코드에서는 train_loss
에 각 배치별 손실 값을 누적하고 train_loss /= len(train_data)
로 처리하고 있습니다. 하지만, 말씀하신 대로 각 배치의 데이터 수를 고려하여 train_loss += loss.item() * x.size(0)
로 변경하여 전체 배치의 손실을 계산한 다음, 최종적으로 전체 데이터 수로 나누면 더 정확한 평균 손실을 계산할 수 있습니다.
이는 특히 배치 크기가 다를 수 있는 경우나 데이터에 가중치를 두고 싶을 경우 효율적인 방법입니다. 따라서 제안하신 방식을 사용하는 것은 일관성과 신뢰도를 높이는 올바른 접근입니다.
해당 주제와 관련해 이미 논의된 비슷한 내용을 좀 더 확인하고 싶으시다면 다음과 같은 링크를 참고해 보세요:
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.