DAY 6 : Error Fix
20210828
Last updated
Was this helpful?
20210828
Last updated
Was this helpful?
Facenet을 하고나서부터 학습을 할 수가 없었다. 계속 이유를 알 수 없는 에러가 발생했기 때문.
처음 발생했던 문제는 다음과 같다.
기대했던 출력 결과
실제 출력 결과
두 가지 상황이 이어졌는데, 하나는 위 처럼 30개의 텐서만 반환되거나 아니면 에러가 나는 경우였다.
텐서 반환 : 30개의 배치 이미지를 뽑았지만, 어느 이미지도 얻지 못했음
에러 발생 : 30개의 배치 이미지를 뽑았는데, 몇개의 이미지만 뽑았음. 그래서 데이터로더에 입력된 텐서간 크기가 달라서 에러 발생
알고보니, 기존 이미지에서 특정 부분을 Crop하고 재생성하는 과정에서 plt.imsave
의 위치가 잘못되어있었다.
코드 크기 상 모두 담지는 못했지만 위 코드는 이중 반복문 형태로 이루어져있는데, 이미지 저장코드가 두번째 반복문 안에 있지 않고 첫번째 반복문에만 속해있어서, 폴더 당 한개의 이미지만 생성되었다. 왼쪽 코드로 작성해서 해결하였다.
Dataloader에서 발생한 에러지만, 이러한 에러의 종류가 상당히 많았다. torchvision.transform
에서 많이 발생했고, 그 외에도 학습 도중에 또는, 단순히 next(iter())
구문에서도 발생하였다.
이 문제는 무려 이틀동안 나를 괴롭힌 문제이다.
이틀동안 몇시간을 고생했는데 해결법은 바로 작성한다는 것이 너무 아깝다. 이걸 보는 여러분들도 이틀을 기다리시길 농담입니다
데이터셋에서 골치아픈 점이 있다면 각 파일마다 확장자가 다르다는 점이다.
jpg
jpeg
png
보통 이미지 파일은 RGB의 세 채널을 가지는데, 이 중 png파일은 투명도라는 정보를 가져서 RGBA라는 네 채널을 가지게 된다. 위의 오류의 마지막 줄을 보면 이 증상에 대해 이해할 수 있다. 그렇다보니 배치로 가져올 때 크기가 통일되지 못했고, 또, transform할 때에도 정규화 등에 기능에서 오류가 났던 것.
그래서, 고민한 방법은 다음과 같다.
모든 파일을 jpg로 저장하자
불러오고 3차원으로 변경하자
단순히 확장자만을 변경하는 것은 정보의 손실 우려가 있어서 후자를 적용하기로 했다.
물론, 쉽게 해결되지는 않았다. jpeg 이미지는 subscriptable 하지 못해서 오류가 발생했다, ToTensor()
이후에는 이러한 슬라이싱이 가능했지만, 애초에 transform에서 오류가 발생하기 때문에 그러지 못했다.
ToTensor()
보다 transform 함수들을 먼저 거치는 것이 순서인 것 같다.
이후, Image 라이브러리로 불러온 이미지는 convert
함수가 있다는 것을 알았다.
그러나, 아무 소용이 없음. 동일한 에러가 발생하는 것을 보니 RGB 변경이 안되었는데, 이를 찾아보니 open
을 하는 라인에서 같이 해주면 된다고 한다.
도대체 왜?
결국 성공!
이게 얼마만에 학습인가... ㅠㅠ