머신러닝

PyTorch ResNet Semantic Segmentation 예제

coding art 2019. 11. 17. 23:27
728x90

리메이크:PyTorch ResNet Semantic Segmentation 예제

https://blog.daum.net/ejleep1/1201

본 블로그 내용이 구글 Colaboratory의 업그레이드 인해 다소 변경되어 최신 버전으로 리메이크 하였으니 같은 내용 일지라도 옮겨 가서 읽어보시기 바랍니다.

 

2012년 출현한 AlexNet 이후로 2016ILSVRC에서 최고로 높은 인식률을 보여준 ResNet 모델이 Transfer Learning 분야에서 많이 활용되고 있다. ResNet은 채용된 레이어 수에 따라 ResNet50, ResNet101, ResNet1523종류가 있는데 비록 학습된 결과라고 해도 그 크기가 상당히 큰 편이며 중간에 해당하는 ResNet101Semantic Segmentation 예제에서 Transfer Learning 이 가능하게끔 불러 쓸 수 있도록 사용되고 있다.

 

Semantic Segmentation은 이미지를 분석함에 있어서 포함되어 있는 각각의 오브젝트 성분들을 인식할 수 있어야 한다. 예를 들면 하나의 이미지를 구성하는 오브젝트들로서 사람, 포장도로, 차량, 가로수, 빌딩, 구름 및 하늘이 있다면 개개의 오브젝트를 나타내는 픽셀들의 라벨 값을 정확히 인식해 내야 한다.

 

여러 종류의 요소가 포함된 이미지를 대상으로 CNNFully Connected Layer 앞 단계 즉 Feature Extraction 단계까지만 적용하게 되면 원래의 이미지로부터 최소화된 크기의 특징벡터가 얻어진다. 일반 CNN에서는 ImageNet에서 설정되어 있는 1000개의 클라스에 맞출 수 있도록 Fully Connected Layer를 사용하여 최종 확률이 계산되어 인식 결과가 얻어진다. 하지만 Semantic Segmentation 에서는 원 이미지의 중요한 정보를 보존하고 있는 최소화 된 크기의 특징 벡터에서 출발하여 다시 원래 이미지 사이즈 크기까지의 출력을 얻어낼 수 있도록 CNN 과정을 역으로 디코딩 학습하게 된다. 물론 디코딩 과정에서의 학습을 위한 클라스의 수는 이미지 하나에 1000 종류가 다 들어갈 수는 없는 노릇이므로 ImageNet 1000 모두가 아니고 필요에 따라 20 종류 정도에 한한다.

 

한편 연산과정에서 픽셀 단위로 주어진 클라스 종류 수에 해당하는 라벨 값들을 인식해야 하므로 계산량이 어마어마하게 커짐으로 인해 반드시 GPU 연산이 필요하게 된다. 이래에 기술되는 예제도 구글 Colabo에서 GPU를 사용하여 처리하도록 한다. 한편 GPU 하드웨어가 지원되는 Jestson Nano 보드나 Google Coral 보드가 그래서 사용될 수도 있을 것이다.

 

PyTorch에서의 Transfer Learning 예제에 따르면 Fine Tuning Fixed Feature Extraction 두 종류 학습방법이 있는데 Semantic Segmentation에서는 더 이상 추가로 학습을 하지 않는 상태의 Fixed Feature Extraction을 사용하는 듯하다. Fixed Feature Extraction 기법을 사용한다함은 AlexNet 이나 ResNet과 같이 상당히 많은 시간이 소요되는 네트워크 학습 결과를 Transfer Learning 해온 상태에서 더 이상의 추가 학습을 시키지 않으면서 직접 Semantic Segmentation 작업을 실행한다는 의미이다.

 

ResNet101 학습결과를 사용하는 Segmentation 코드를 구글 Colabo에서 GPU를 사용하면서 고려해 보자. ResNet52 도 이미 PyTorch Transfer Learning 예제에서 사용한 적이 있으나 TorchVision을 라이브러리로 사용하는 Segmentation 작업에서는 101 만이 준비되어 있는듯하다. 이 예제 코드를 실행하기 위해서는 나무에 않아 있는 새의 이미지 파일을 구글 Colabo에 업로딩 후 첫 번째 [1] command line 명령들을 실행하자.

 

 

 

fcn-resnet101을 부른 후 이어서 bitd.png 이미지 파일을 열어서 출력해보자. 다음과 같이 새 이미지가 출력되면 PyTorch에 의한 Segmentation 작업을 시작할 준비가 되었다.

 

오픈한 이미지 파일을 PyTorch 가 처리할 수 있도록 transform 시키도록 하자. Resize, CenterCrop이 사용된다. 처리된 이미지는 Tensor TorchTensor 로 처리한다. 아울러 ImageNet에서 주어지는 평균값과 표준 편차를 사용하여 표준화 하도록 한다. 이와같이 처리한 결과물 inputshape를 살펴보면 TorchTensor로서 [3, 224,224] 임을 알 수 있다. 3RGB 컬러의 3을 뜻하면 224PyTorch 이미지 처리 시 표준 크기 이다. inputunsqueeze(0)시키면 shape 의 차원이 하나 늘어나는데 이 차원은 batch size가 된다. 현재는 하나의 이미지를 처리하므로 batch size = 1 인 셈이다.

 

inputfcn에 넘겨 출력[‘out’]처리하여 output으로 두고 shape 어떻게 변했는지 살펴보자. shape[1,21,224,224]로 바뀌었는데 1은 그대로 batch size 이고 21segmentation 작업에서 이미지를 구성하는 전체 Class 수를 뜻한다. 괄호 안의 output.squeeze().dim=0 처리 후 oi=torch.argmax 명령을 실행하게 되면 [224,224] TorchTensor가 얻어진다. om=oi.detatch().numpy() 명령 처리를 하면 shape(224,224) 어레이 형태가 된다.

 

마지막으로 om이 가지고 있는 unique 한 정보를 출력해 보면 [0 3]임을 알 수 있다. 아래의 segmap 루틴에 의하면 0은 배경을 뜻하며 3은 새를 의미한다. 즉 즉 21Class를 대상으로 한 Segmentation 확률이 얻어졌다는 뜻이다.

 

이와 같은 segmentation 작업은 이미지 파일에 오브젝트가 여러 종류 포함되었을 때도 가능하다. 다음의 예를 참조하자.

 

이 내용은 다음 url 주소의 내용과 코드를 참조하였으며 그림 읽어 들이는 부분과 shape 값을 조사하는 부분에 한해서 코드를 조금 수정하였다.

PyTorch for Beginners: Semantic Segmentation using torchvision

https://www.learnopencv.com/pytorch-for-beginners-semantic-segmentation-using-torchvision/