DAY 6 : Error Fix

20210828

Facenet을 하고나서부터 학습을 할 수가 없었다. 계속 이유를 알 수 없는 에러가 발생했기 때문.

Error #1 Creating Images

처음 발생했던 문제는 다음과 같다.

next(iter(train_loader))[0].shape

기대했던 출력 결과

Tensor([30, 3, 280, 210)]

실제 출력 결과

Tensor([30])

두 가지 상황이 이어졌는데, 하나는 위 처럼 30개의 텐서만 반환되거나 아니면 에러가 나는 경우였다.

  • 텐서 반환 : 30개의 배치 이미지를 뽑았지만, 어느 이미지도 얻지 못했음

  • 에러 발생 : 30개의 배치 이미지를 뽑았는데, 몇개의 이미지만 뽑았음. 그래서 데이터로더에 입력된 텐서간 크기가 달라서 에러 발생

알고보니, 기존 이미지에서 특정 부분을 Crop하고 재생성하는 과정에서 plt.imsave 의 위치가 잘못되어있었다.

코드 크기 상 모두 담지는 못했지만 위 코드는 이중 반복문 형태로 이루어져있는데, 이미지 저장코드가 두번째 반복문 안에 있지 않고 첫번째 반복문에만 속해있어서, 폴더 당 한개의 이미지만 생성되었다. 왼쪽 코드로 작성해서 해결하였다.

Error #2 Dimesion

Dataloader에서 발생한 에러지만, 이러한 에러의 종류가 상당히 많았다. torchvision.transform 에서 많이 발생했고, 그 외에도 학습 도중에 또는, 단순히 next(iter()) 구문에서도 발생하였다.

이 문제는 무려 이틀동안 나를 괴롭힌 문제이다.

이틀동안 몇시간을 고생했는데 해결법은 바로 작성한다는 것이 너무 아깝다. 이걸 보는 여러분들도 이틀을 기다리시길 농담입니다

데이터셋에서 골치아픈 점이 있다면 각 파일마다 확장자가 다르다는 점이다.

  • jpg

  • jpeg

  • png

보통 이미지 파일은 RGB의 세 채널을 가지는데, 이 중 png파일은 투명도라는 정보를 가져서 RGBA라는 네 채널을 가지게 된다. 위의 오류의 마지막 줄을 보면 이 증상에 대해 이해할 수 있다. 그렇다보니 배치로 가져올 때 크기가 통일되지 못했고, 또, transform할 때에도 정규화 등에 기능에서 오류가 났던 것.

그래서, 고민한 방법은 다음과 같다.

  • 모든 파일을 jpg로 저장하자

  • 불러오고 3차원으로 변경하자

단순히 확장자만을 변경하는 것은 정보의 손실 우려가 있어서 후자를 적용하기로 했다.

image = Image.open(self.path.iloc[index])[3:, :, :]

물론, 쉽게 해결되지는 않았다. jpeg 이미지는 subscriptable 하지 못해서 오류가 발생했다, ToTensor() 이후에는 이러한 슬라이싱이 가능했지만, 애초에 transform에서 오류가 발생하기 때문에 그러지 못했다.

  • ToTensor() 보다 transform 함수들을 먼저 거치는 것이 순서인 것 같다.

이후, Image 라이브러리로 불러온 이미지는 convert 함수가 있다는 것을 알았다.

image = Image.open(self.path.iloc[index])
image = image.convert('RGB')

그러나, 아무 소용이 없음. 동일한 에러가 발생하는 것을 보니 RGB 변경이 안되었는데, 이를 찾아보니 open 을 하는 라인에서 같이 해주면 된다고 한다.

  • 도대체 왜?

image = Image.open(self.path.iloc[index]).convert('RGB')

결국 성공!

이게 얼마만에 학습인가... ㅠㅠ

Last updated

Was this helpful?