Hello, WORLD!
지난 학기 지지고 볶았던 나의 첫 번째 자식....에 대해 종강까지 하고나서야, 글을 쓰려고 앉았다.
-
이번 글의 주제 요약: 데이터는 fabric 데이터. 이미지 데이터를 어떻게 로딩할 것인가? 주제는 1. 적은 양의 데이터로 어떻게 좋은 성능을 낼 것인지 2. 정상만으로 결함을 감지할 수 있을지.
-
지난 글에서 소개했듯, 우리 팀이 다룰 데이터셋은 fabric 데이터다. 굳이 따지면, 제조업 데이터. (처음부터 제조업 데이터에 관심을 갖고 찾은 데이터는 아니고, defect detection을 주제로 잡고 탐색했다.)
이미지 데이터의 출처는 AITEX사다. 아마도... 스페인의 섬유회사로 추정된다. 회사에 대해 자세히 알아보지는 않았기에..
중요한 건 데이터지!!!
데이터로는 AITEX사의 FABRIC IMAGE DATABASE를 활용했다. 링크를 타고 들어가면, 데이터에 대한 간략한 설명이 적혀있다.
The textile fabric database consists of 245 images of 7 different fabrics. There are 140 defect-free images, 20 for each type of fabric. With different types of defects, there are 105 images. Images have a size of 4096×256 pixels. Defective images have been denominated as follows: nnnn_ddd_ff.png, where nnnn is the image number, ddd is the defect code, and ff is the fabric code. There is a mask of defect, denominated as: nnnn_ddd_ff_mask.png, where white pixels represent the defect area of the defective image. Defect free images have been denominated as follows: nnnn_000_ff.png, where defect code has been replaced by 0000 code.
- fabric 종류: 7개.
- 총 이미지 개수: 245개
결함없는 이미지 140(7개의 종류마다 20개의 정상이미지)
결함 이미지 105개(다양한 유형의 결함)
- size: 4096*256(고해상도 이미지로, 분석을 위해서는 조절이 필요)
- 이미지 이름: nnnn_ddd_ff.png. (nnnn: 이미지 번호, ddd: 결함코드, ff: fabric 코드)
결함 코드>
Broken end |
2 |
Broken yarn |
6 |
Broken pick |
10 |
Weft curling |
16 |
Fuzzyball |
19 |
Cut selvage |
22 |
Crease |
23 |
Warp ball |
25 |
knots |
27 |
Contamination |
29 |
Nep |
30 |
Weft crack |
36 |
의류학을 반 년이나마 공부했던 나라지만.. 저게 대체 무슨 결함인지는 사진보고 식별이 되지않는다... 도메인 놀로지가 필요한 순간..^^.. 대충 defect 이미지가 가장 많았던 nep은 원단 올 뭉침, fuzzyball이 뭉친 보풀?정도라는 것만 알겠다.
-
이제, 이미지셋을 직접 탐색해보자.
이미지는 이렇게 생겼다. 스캔 뜬 이미지처럼, 왼쪽에 하얀 부분이 .... 등장한다. 매우 거슬림.
이미지 사이즈가 4096 * 256.. 아주 길-쭉하다. 통째로 모델에 넣고 돌렸다간, 거의 뭐...^^.. 사실 cuda에서 out of memory가 나서 애초에 돌아가지도 않을 것이다. 고해상도 이미지를 어떻게 코랩에 로드하고, 어떻게 모델링을 할 것인지에 대해서는 차차 이야기하도록하겠다.
-
데이터에 대해 대충 파악했으니, 데이터를 코랩에 로딩하고 직접 탐색해 볼 단계다.
이미지 로딩은 처음해봐서, 픽셀값이 로딩되는 것도 와닿지않고 추상적이었다. 제대로 로딩이 된 건지도 모르겠고, 채널별로 로딩이 되어 3* 4096 * 256 사이즈가 되어야하는데, 이게 안되고...또...하여튼 삽질을 정말 많이 했다. 팀원들이랑 화상 회의를 새벽 1시까지... 했던 슬픈 기억...
1. Google drive 연동
우선 이미지를 로컬에서 불러와도 좋지만, 구글은 google drive라는 어마무시한 클라우드를 갖추고있으니 코랩과 gdrive를 직접 연동해서 이미지를 불러오고자한다. (팀 프로젝트였기에, 로컬에 각자 두고 업로드하기보다는, 공유드라이브에 이미지셋을 업로드해서 로딩하는 방안을 선택했다.)
from google.colab import drive
drive.mount('/content/drive')
URL타고 들어가서, 인증 번호를 복사해온 후 하단의 박스에 붙여넣기+enter하면 연동 완료!
2. 데이터 로딩
torch, transforms, ImageFolder모듈을 활용해서 이미지를 로딩했다. 사실 맨 처음에는 cv2.imread로 읽어왔는데, 이런 저런 노력끝에 우리에게 가장 적절한 방법으로 선택했다.
import torch
import torchvision.transforms as transforms
from torchvision.datasets import ImageFolder
# data load
transform = transforms.Compose([transforms.ToTensor()])
nodefect_dataset = ImageFolder(root= "/content/drive/Shared drives/NoDefect/", transform=transform)
nodefect_loader = torch.utils.data.DataLoader(nodefect_dataset)
defect_dataset = ImageFolder(root= "/content/drive/Shared drives/Defect/", transform=transform)
defect_loader = torch.utils.data.DataLoader(defect_dataset)
-
Transforms: 이미지를 처리하기 위한 모듈. Transforms로 crop, resize, data augmentation 등을 할 수 있다! (해당 프로젝트의 경우에는 주제의 결과를 더욱 확고하게 보여주기 위해 진행하지 않았다.) ToTensor()는 numpy 이미지에서 torch 이미지로 변경해주는 것이다.
-
ImageFolder: 계층적인 폴더 구조를 갖고있는 데이터셋을 로딩할때 사용한다. 폴더 이름이 레이블로 처리된다.
-
DataLoader: 데이터로더는 batch size 등의 파라미터를 지정하여, enumerate를 활용해 iterative하게 이미지 데이터들을 반환해주는 역할을 한다. 이미지 로딩단계에서는 shape나 pixel값들을 확인해볼 수 있는 장점이 있다. 직접 확인해보는 코드는 하단에 작성해두었다.
for idx, (data,label) in enumerate(nodefect_loader):
print(idx, data.shape)
print(idx, data)
사이즈가 조금 마음에 안들지만, 추후에 reshape를 하든 어쩌든 우선 데이터 로딩은 완성했다! 뿌-듯. (아 참고로, 1.0000 값이 계속 나오는 건, 위에서 보았듯 이미지 왼쪽에 하얀....부분 때문이다. ) 다음은 우리 프로젝트의 주제를 어떻게 풀어나가는 지를 살펴보겠다!
see you soon!