공기정화 식물-인공지능-IOT

공기정화식물 Multi Label Image Classification Keras 머신 러닝

coding art 2020. 8. 12. 14:37
728x90

다양한 종류의 실내 공지정화식물 중 몇 가지를 선택하여 구성하는 그린월에서 얻어지는 카메라 이미지를 대상으로 classification 코딩을 해 보자. 개별 식물 단위를 대상으로 하는 classification 작업은 그다지 문제 될 것이 없겠으나 하나의 이미지 내에 2개 이상의 클라스들이 섞여 있을 경우 정확하게 포함된 클라스들의 존재 여부를 머신 러닝에 의해 감지해 낼 수 있어야 할 것이다.

 

Multi-Label Classification을 위한 코드로서는 지금까지 상영된 수많은 7000 여개 이상의 영화 포스터를 대상으로 장르를 구별해 내는 Keras 오픈소스 예제 코드를 사용할 수 있다. 영화 포스터 한 장에는 영화 특성을 잘 표현할 수 있는 오브젝트들이 포함되어 있으며 장르별로 분석된 영화 특성 학습 데이터가 이미 주어져 있다. 마찬가지로 그린월을 구성하는 식물의 종류를 찾아내는 작업도 그 알고리듬이 영화 장르 분석과 다르지 않다. 충분한 수의 이미지를 준비하여 각 식물별로 학습시키면 된다. 아울러 2종류 또는 3종류의 식물이미지일 경우에도 이미지를 준비하여 학습과 테스트를 실행해 보도록 하자. 다음은 공기정화식물인 Diffenbachia, Scindapsus Spathy Filum 개별 이미지 사례들이다.

반면에 개별 이미지들이 2개 이상 함께 포함되어 있는 Multi-Label Image Classification 사례를 살펴보자. 이와같이 식물의 잎과 줄기들이 함께 포함되어 있는 이미지들을 머시러닝으로 처리해 보도록 하자.

Multi-Label 문제라고 해서 특별한 알고리듬이 있는 것은 아니다. 구글 GPU 서비스가 가능한 Colaboratory에서 코드를 작성해 보도록 하자. 준비한 이미지 데아타 폴더와 각 이미지별 라벨 값들이 정리되어 있는 train.csv 엑셀파일을 준비하wk. 이미지 데이터 폴더 이름은 편의 상 Images 로 설정하고 여기에 각 10개씩의 개별 이미지를 넣도록 한다. 추가로 2개 이상의 라벨 값을 가진 이미지들도 넣도록 하고 라벨 값 정보를 가지고 있는 train.csv 도 함께 저장한다.
영화포스터 사용하던 예제로부터 가져왔기에 라벨 값 컬럼에 장르라는 용어를 그대로 사용하고 있다. 즉 식물 명이 장르가 된다. 개별 이미지의 라벨 값에 따라 해당 식물의 장르 값을 ‘1’ 로 입력하고 나머지는 ‘0’ 으로 입력한다. 한편 2개 이상의 라벨 값을 가지는 이미지에 대해서는 해당 식물의 장르 값이 2개가 될것이며 각각 ‘1’을 입력하고 나머지는 ‘0’을 입력한다. 만약의 경우 3종류의 라벨 값이 포함된 경우라면 장르 값 모두를 ‘1’ 로 입력 한다.

 

구글 GPU 서비스가 가능한 Colaboratory에서 코드를 작성하자. 헤더 영역에서 시작하기 전에 구글 드라이브 마운트 작업을 실시한다.

불러올 데이터가 포함되어 있는 폴더로 Change Directory 명령을 실행한다. 이 폴더에 이미지 파일들과 train.csv 파일들이 포함되어 있다. Colaboratory에서 폴더 생성 및 파일 업로딩이 가능하지만 NDRIVE에서 하는 것이 훨씬 처리속도도 빠르고 쉽고 편하다.

헤더 영역에서 필요한 라이브러리들을 import 시킨다. Keras Sequential을 포함하여 Dense, Dropout, Flatten CNN을 위한 Conv3D, MaxPooling2D 들이며 Keras.utils를 사용하여 라벨 값을 categorical one hot code 로 변경한다. image 라이브러리를 import 하여 이미지 하나 하나씩을 image.load_image() 명려을 사용하여 읽어 들이게 될 것이다. 아울러 train.csv 파일을 읽을 수 있도록 pandas 도 필요하다. 한편 읽어들인 데이터를 대상으로 학습 데이터와 validation 데이터로의 분리는 sklear.model_selection에서 train_test_splitt을 사용한다. 현재의 코드는 CNN 네트워크 처리만 Keras로 하는 코드임에 유의하자. 물론 Keras에서 동일한 처리를 해주는 기능이 있지만 그 때에는 반드시 flow_from_directory() 명령을 사용해야 한다는 점을 참고하자. tqdm progrssive bar 처리 루틴이다. 데이터야이 클수록 필수적일 것이다.

pandas train.csv 파일을 읽어서 출력하여 확인해 보자.

Images 폴더에 저장된 이미지 파일들을 읽어 들이자. target_siz 는 이미지 파일의 원해상도를 약분하여 축약한 비율로서 640X480 또는 32X18 또는 128X72 비율 주에 하나를 선택하면 된다. 32X18을 사용해도 되지만 출력했을 때에 인간의 시각으로 정확하게 식별이 불가능할 수도 있으므로 픽셀을 좀 높여 잡을 필요가 있다. 읽어서 어레이로 저장 후 255 로 나누어 rescaling 하고 for looping 하여 모든 결과물을 train_image 에 저장한다. 작업이 완료되면 이 어레이들을 numpy 어레이 X로 두자.

라벨 값 데이터를 준비하도록 한다. train에서 맨 윗 줄의 문자열 데이터인 ‘Id’ “Genre’를 삭제하고 axis=1 에 해당하는 컬럼 데이터를 읽어 들인다.

학습용 데이터 X 와 라벨 값 데이터 y 가 준비되었으면 일정 비율test_size=0.2 로 나누도록 한다. 여기서 test 는 통계학적인 validation을 뜻한다. Sequential() 명령을 사용하여 CNN 레이어를 한번 사용하는 코드를 작성한다. CNN 레이어 이 후 마지막 라벨 별 확률 계산 단계의 활성화 함수 설정에서 Softmax 가 아닌 Sigmoid를 사용함에 유의하자. Sigmoid를 사용하게 되면 확률이 아닌 likelyhood 가 계산된다.

CNN 레이어가 하나만 사용되는 간단한 네트워크이다.

컴파일 단계에서 Adam 옵티마이저와 binary_crossentropy loss 함수를 설정하고 학습 횟수 epochs 는 9로 설정한다. 10회 학습을 하게 되면 오히려 accuracy 와 val_accuracy 가 떨어진다.

2개의 라벨 값을 가져야 하는 Unseen 이미지 데이터로서 Diffenbachia SpathyFilum 이 함께 포함된 multi-label 사례를 테스트해 보기로 한다.Spathy FilumDiffenbachia likelyhood 가 거의 1.0 으로 상당히 정확하게 예측된다. 하지만 촬영된 이미지 품질에 따라서 그 결과가 크게 엇갈리는 단점이 있음을 지적해 둔다.

Blog Reference

Build your First Multi-Label Image Classification Model in Python

https://www.analyticsvidhya.com/blog/2019/04/build-first-multi-label-image-classification-model-python/