본문 바로가기
Study/Error

[Deep Learning] [Pytorch] ValueError: Expected more than 1 value per channel when training, got input size torch.Size([1, 512, 1, 1]) - model.eval()로 해결 !

by 후이 (hui) 2022. 3. 8.
728x90
반응형

 

에러 발생 상황 : 

 

 

1) Resnet 에 배치사이즈 100으로 이미지 데이터를 학습 시켰다. 

2) 모델 학습이 완료된 후 학습한 모델에 1개의 테스트 인풋을 넣고 예측값을 확인하려했다.

3) 에러가 발생했다. ValueError: Expected more than 1 value per channel when training, got input size torch.Size([1, 512, 1, 1])

 

즉, 모델에 입력된 토치 텐서 사이즈가 1개 이상이길 바라는데, 입력 토치 텐서는 1개라서 문제가 생긴거다. 

 

 

해결 방법 : batchsize 무시한채 데이터 1개를 test 할꺼면, model.eval() 을 선언해야한다. 

model.train() 으로 되어있을 땐 애초에 설정한 모델의 배치사이즈와 맞지 않으면 위와 같은 에러가 발생한다. 

따라서 앞서 1번처럼 배치사이즈가 아니라 1개의 테스트 인풋을 넣고 추론 결과를 보고싶을 때는 model.eval()을 써야한다. 

 

(document)

model.eval() will notify all your layers that you are in eval mode, that way, batchnorm or dropout layers will work in eval mode instead of training mode.

 

즉, eval() 메소드는 모델의 학습과정에서 등장하는 batchnorm, dropout 을 비활성화 시켜서

평가/추론에 적합한 모델 상태로 만든다. 

 

def visualize_one_sample(test_data, model):
    print("\n\n 5. VISUALIZATION TEST DATA")
    with torch.no_grad(): # torch.no_grad()를 하면 gradient 계산을 수행하지 않는다.
        model.eval() ##### one sample 로 test 할때는 모델 eval 을 넣어줘야함 (아니면 배치 사이즈에 안맞다고 에러뜸)
        r = random.randint(0, len(test_data) - 1)
        X_single_data = torch.FloatTensor(test_data.data[r:r + 1].reshape(-1,3,32,32)).to(device)
        Y_single_data = torch.FloatTensor(test_data.targets[r:r + 1]).to(device)

        print('Label: ', Y_single_data.item())
        single_prediction = model(X_single_data)
        print('Prediction: ', torch.argmax(single_prediction, 1).item())

        plt.imshow(test_data.data[r:r + 1].reshape(32,32,3), interpolation='nearest')
        plt.show()

 

 

 

Q. 그렇다면, torch.no_grad() 와 model.eval() 은 무슨 차이인가? 

torch.no_grad()는 말그대로 gradient 계산을 비활성화 시켜주는 것

 - pytorch의 autograd 를 비활성화 시켜 메모리를 줄여주고 연산속도를 증가시키는 역할 

 - 모델 테스트, 검증에서 활용하면 됨 

 - 그러나 model 테스트 과정에서 dropout, batchnorm을 비활성화 시키진 못함 

 

model.eval()은 dropout, batchnorm을 비활성화 

 

 

 

결론 : 테스트 할 때는 torch.no_grad, model.eval() 둘다 써야함. 

 

 

 

참고 link : 

https://discuss.pytorch.org/t/error-expected-more-than-1-value-per-channel-when-training/26274

https://discuss.pytorch.org/t/model-eval-vs-with-torch-no-grad/19615

https://yuevelyne.tistory.com/10 

 

728x90
반응형

댓글