-
[Pytorch] multiple forward process머신러닝 2020. 6. 12. 01:36
데이터를 학습하는 과정에서 같은 모델에서 학습을 하지만, 다른 인풋데이터를 동시에 사용하는 경우가 종종있다.
(나는 지금
Unsupervised Out-of-Distribution Detection by Maximum Classifier Discrepancy(2019)를 재현하고 있는데, 이 모델에서도 label이 있는 데이터와 label이 없는 데이터를 같이 모델에서 학습한다.)
이러한 상황에서 내가 모델을 구현한 방법은
model.train() for i, sup_data in enumerate(dataloaders['sup_train']): unsup_data = dataloaders['unsup_train'][i % len(dataloaders['unsup_train'])] sup_inputs = sup_data[0] sup_labels = sup_data[1].cuda() unsup_inputs = unsup_data[0] data_inputs=torch.cat((sup_inputs,unsup_inputs),axis=0).cuda() # unsup_labels = unsup_data[1].cuda() iters += 1 optimizer.zero_grad() out_1, out_2 = model(data_inputs) sup_out_1,sup_out_2=out_1[:sup_inputs.shape[0]],out_2[:sup_inputs.shape[0]] unsup_out_1,unsup_out_2=out_1[sup_inputs.shape[0]:],out_2[sup_inputs.shape[0]:] loss_sup = criterions['sup'](sup_out_1, sup_labels) + criterions['sup'](sup_out_2, sup_labels) # Step A loss_unsup = criterions['unsup'](unsup_out_1, unsup_out_2) # Step B loss = loss_unsup + loss_sup loss.backward() optimizer.step()
요로케..!
sup_data ==> label data / loss = criterions['sup'] (CE)
unsup_data ==> unlabel data / loss = criterions['unsup'] (거리차이)
하나의 model(computational graph)이 생성이 되고, 이 model이 backward된다고 생각했기때문에
sup_data + unsup_data를 한번에 concat한뒤 모델을 통과하고, 가장 밑단에서 나눠서 total loss를 구했다.
이렇게 한 이유는
만약 sup_data를 먼저 학습하고, unsup_data를 넣는 순간 sup_data는 overwritten 되버리니까, sup_data로 학습은 아예 안됐을것이라 생각했다. 그래서 2타입의 input data를 한번에 넣고, 계산하고자했다.
그.런.데!
오늘 알게된 사실 Pytorch multiple forward process
(사실 내가 안건 아닌..)간단히 말하면, 모델에대해 input이다르면, 그것을 각각의 computation graph 가 생성된다는것..
고러니까 input이 다른 데이터에 의해 overwritten될일이 없다는 것이다.
그리고, backward과정에서 각 graph들에 대해 gradient계산하여 적용이 된다.
엄청 거창하게 써보려했지만.. 이게 끝..ㅎㅎ
고러니까
model.train() for i, sup_data in enumerate(dataloaders['sup_train']): unsup_data = dataloaders['unsup_train'][i % len(dataloaders['unsup_train'])] sup_inputs = sup_data[0].cuda() sup_labels = sup_data[1].cuda() unsup_inputs = unsup_data[0].cuda() iters += 1 optimizer.zero_grad() out_1, out_2 = model(sup_inputs) loss_sup = criterions['sup'](out_1, sup_labels) + criterions['sup'](out_2, sup_labels) out_1, out_2 = model(unsup_inputs) loss_unsup = criterions['unsup'](out_1, out_2) loss = loss_unsup + loss_sup loss.backward()
굳이 아까 코드처럼 sup_data와 unsup_data를 미리 concat한뒤 한번에 model에 넣고, 계산할 필요없이
sup_data, unsup_data를 따로 model에 넣어도,
sup_data에 대한 computation graph와 unsup_data에 대한 computation graph가 따로 생긴다.
그리고 구한 loss가 각각의 computation graph에대해 gradient를 계산한다.
엄청 직관적으로 모델을 짜도 된다는 것~!
설명 너무 어렵다.. 같은말만 반복한것 같아..흑흑 나날이 발전하기르을참고 |
https://discuss.pytorch.org/t/multiple-model-forward-followed-by-one-loss-backward/20868/5
Multiple model.forward followed by one loss.backward
In my experiments, the results were similar. There might be slight differences though. The difference in your case might be due to batch size: the effective batch size might be larger in multiple forward passes.
discuss.pytorch.org
Mephisto405/Unsupervised-Out-of-Distribution-Detection-by-Maximum-Classifier-Discrepancy
Reproducing experimental results of OOD-by-MCD [Yu and Aizawa et al. ICCV 2019] - Mephisto405/Unsupervised-Out-of-Distribution-Detection-by-Maximum-Classifier-Discrepancy
github.com
'머신러닝' 카테고리의 다른 글
[ML] GBM (Gradient Boosting machine) (0) 2021.05.19 [부캠] Python 특징에 대한 개념 정리 (0) 2021.01.18 앙상블 기법 배깅 vs 부스팅 vs 스태킹 (0) 2021.01.15 [머신러닝]샘플링 기법 (0) 2020.12.07 CV 이미지 전처리 -Image thresholding (ft.tesseract) (1) 2020.06.10