이제 마지막 단계이다.

학습된 데이터를 기반으로 Object Detection API를 활용하여 test디렉토리에 있는 학습하지 않은 새로운 이미지를 인풋으로 주어 학습 데이터의 정확도를 검증할 차례이다. 그 과정은 아래와 같다.


8. Detect custom objects in real time


Welcome to part 6 of the TensorFlow Object Detection API tutorial series. In this part of the tutorial, we are going to test our model and see if it does what we had hoped. In order to do this, we need to export the inference graph.

Luckily for us, in the models/object_detection directory, there is a script that does this for us: export_inference_graph.py

To run this, you just need to pass in your checkpoint and your pipeline config, then wherever you want the inference graph to be placed. For example:




python3 export_inference_graph.py \
    --input_type image_tensor \
    --pipeline_config_path training/ssd_mobilenet_v1_pets.config \
    --trained_checkpoint_prefix training/model.ckpt-10856 \
    --output_directory mac_n_cheese_inference_graph
cs


Your checkpoint files should be in the training directory. Just look for the one with the largest step (the largest number after the dash), and that's the one you want to use. Next, make sure the pipeline_config_path is set to whatever config file you chose, and then finally choose the name for the output directory, I went with mac_n_cheese_inference_graph

Run the above command from models/object_detection


나의 경우에는 아래와 같이 설정을 했다.

TODO 각각의 파라미터들에 대해서 정리하자.



python3 export_inference_graph.py \
    --input_type image_tensor \
    --pipeline_config_path TELCO_OBJ_DETECTION/training/ssd_mobilenet_v1_pets.config \
    --trained_checkpoint_prefix TELCO_OBJ_DETECTION/training/model.ckpt-33354 \
    --output_directory mac_n_cheese_inference_graph
cs


Otherwise, you should have a new directory, in my case, mine is mac_n_cheese_inference_graph, inside it, I have new checkpoint data, a saved_model directory, and, most importantly, the forzen_inference_graph.pb file.


TODO mac_ncheese_inference_graph에 생성된 각각의 파일들에 대해서 정리하자.


Now, we're just going to use the sample notebook, edit it, and see how our model does on some testing images. I copied some of my models/object_detection/images/test images into the models/object_detection/test_images directory, and renamed them to be image3.jpg, image4.jpg...etc.


Object Detection API에서 제공하는 object_detection_tutorial.ipynb를 활용하여 images/test에 있는 시험용 이미지들을 object_detection/test_images 디렉토리에 옮겨 학습이 제대로 이루어졌는지 정확도를 측정해 볼 차례이다.

Object Detection API를 사용하는 방법은 [API] Object Detection API를 이용한 오브젝트 인식하기 Part 1. - 설정 [펌] 포스팅을 참조하면 된다.


추가적으로, 우리가 만든 모델을 적용하기위해서 몇 가지 정보를 수정해주어야 한다.

Booting up jupyter notebook and opening the object_detection_tutorial.ipynb, let's make a few changes. First, head to the Variables section, and let's change the model name, and the paths to the checkpoint and the labels:


# What model to download.
MODEL_NAME
= 'mac_n_cheese_inference_graph'

# Path to frozen detection graph. This is the actual model that is used for the object detection.
PATH_TO_CKPT
= MODEL_NAME + '/frozen_inference_graph.pb'

# List of the strings that is used to add correct label for each box.
PATH_TO_LABELS
= os.path.join('training', 'object-detection.pbtxt')

NUM_CLASSES
= 1
cs


Next, we can just delete the entire Download Model section, since we don't need to download anymore.




opener = urllib.request.URLopener()
opener.retrieve(DOWNLOAD_BASE + MODEL_FILE, MODEL_FILE)
tar_file = tarfile.open(MODEL_FILE)
for file in tar_file.getmembers():
    file_name = os.path.basename(file.name)
    if 'frozen_inference_graph.pb' in file_name:
        tar_file.extract(file, os.getcwd())

cs


Finally, in the Detection section, change the TEST_IMAGE_PATHS var to:




PATH_TO_TEST_IMAGES_DIR = 'test_images'
TEST_IMAGE_PATHS = [ os.path.join(PATH_TO_TEST_IMAGES_DIR, 'image{}.jpg'.format(i)) for i in range(1, 8) ]
# Size, in inches, of the output images.
IMAGE_SIZE = (12, 8)

cs


Here are a few of my results:


Tensorflow Object Detection API tutorial


Tensorflow Object Detection API tutorial


Tensorflow Object Detection API tutorial


나는 GPU를 이용하여 약 35,000번의 학습단계를 거쳐서 로스가 약 0.8정도까지 내려가도록 학습하였다. 학습을 하면서 느낀거지만 35,000번을 수행하는동안 체감상 약 3시간 정도 걸린것 같다. 로스가 0에 가까워지는 수치가 되었다는것은 아주 훌륭하게 학습이 되었다는것을 의미하기도 하다.

100개의 이미지를 가지고 학습을 진행하였는데 생각보다 더 훌륭한 결과를 보여주고 있는게 아닌가 싶다.


Tensorflow에서 제공하는 Object Detection API덕분에 내가 AI를 통해서 해볼 수 있는 것들을 아주 쉽고 편하게 사용을 해본것 같다.(이것은 생각 이상으로 결과를 빨리 얻었다고 생각한다) 지금까지 해본 것들을 정리해 보면 아래와 같다.

- 나만의 이미지를 학습시키는 방법,

- 학습된 이미지를 사용해보는 방법

- 다양한 모델을 적용해보는 방법

- 이미지에서 특정 오브젝트들을 탐지하는 방법

- 실시간/비실시간 영상에서 특정 오브젝트들을 탐지하는 방법


여기까지 진행해온 동안, 여러 가지 결과를 빨리 보고 싶어서 중간중간 알아야할 것들을 그냥 지나쳐왔다. 이제부터는 지나쳤던 정보들을 하나하나 정리해가는 시간을 가져야겠다.

Posted by 이성윤

머신러닝을 시작하면서 "데이터가 가장 중요하다.", "데이터가 돈이 된다" 이런 말들을 들었었다.


저런 말들을 들었을때, 그럴 수 있겠구나 싶었지만 와닿지는 않았다.

이번 과정을 통해서 왜 알바를 써서 이미지를 레이블링하는지, 왜 데이터가 중요하는지 등을 느낄 수 있었다.


1. 학습시킬 이미지 준비

sentdex로 부터 제공받은 macaroni and cheese를 사용하겠다. 이미지는 Google, Bing, ImageNet에서 수집했으며 이미지의 크기는 대부분 800x600 이다.

어떤 이미지이든지 100개 이상의 이미지를 확보해야 하며, 이미지가 확보 되면 레이블링 처리하는 Annotation을 수행해야 한다.

TODO 구글에서 내가 원하는 이미지를 확보할 수 있는 도구 찾아보기

TODO 구글에서 내가 원하는 이미지를 쉽게 확보 할 수 있는 도구 만들어보기


2. Annotate/label

이미지 레이블링은 labelImg 도구를 사용한다.

labelImg: https://github.com/tzutalin/labelImg


labelImg 설치는 다음을 참조한다.

[설치] image annotation tool

http://cafe.naver.com/telcosn/661


labelImg를 설치하고나서 데스크탑 모드에서 실행을 한다.

$ python labelImg.py


실행을 하고나면, GUI Window가 실행된다.

python tutorials


- 이미지가 저장되어 있는 디렉토리를 오픈한다.

- Create RectBox 버튼을 클릭하여 사진에서 Object를 드래그하여 레이블링을 한다.

- ctrl+s 로 저장을 하면 이미지와 같은 이름으로 xml 파일이 생성된다. 일반적으로 ANNOTATION이라는 디렉토리에 저장하는것이 관례인듯하다.

 ※ TODO XML파일을 열어보니 각각의 의미하는 내용을 정리해야 할 것 같다.



<annotation>
    <folder>images</folder>
    <filename>velveetashellsandcheese.jpg</filename>
    <path>/home/paperspace/Desktop/images/velveetashellsandcheese.jpg</path>
    <source>
        <database>Unknown</database>
    </source>
    <size>
        <width>900</width>
        <height>602</height>
        <depth>3</depth>
    </size>
    <segmented>0</segmented>
    <object>
        <name>macncheese</name>
        <pose>Unspecified</pose>
        <truncated>0</truncated>
        <difficult>0</difficult>
        <bndbox>
            <xmin>167</xmin>
            <ymin>169</ymin>
            <xmax>795</xmax>
            <ymax>527</ymax>
        </bndbox>
    </object>
</annotation>
cs


- 보유하고 있는 모든 이미지를 위의 방법으로 반복해서 작업한다.


3. 보유하고 있는 데이터를 train/test sample로 나누기

아래의 디렉토리 구조를 생성하고, 보유하고 있는 데이터를 train/test를 나눈다.



Object-Detection
-images/
--test/
---testingimages.jpg
--train/
---testingimages.jpg
--...yourimages.jpg
--...yourimages.xml
cs


4. 학습을 위한 TF Records 변환

참고: [TFRecord] 텐서플로우 트레이닝 데이타 포맷인 *.tfrecord 파일 읽고 쓰기 [펌]

TFRecord 파일 포맷이란

TFRecord 파일은 텐서플로우의 학습 데이타 등을 저장하기 위한 바이너리 데이타 포맷으로, 구글의 Protocol Buffer 포맷으로 데이타를 파일에 Serialize 하여 저장한다.

CSV 파일에서와 같이 숫자나 텍스트 데이타를 읽을때는 크게 지장이 없지만, 이미지를 데이타를 읽을 경우 이미지는 JPEG나 PNG 형태의 파일로 저장되어 있고 이에 대한 메타 데이타와 라벨은 별도의 파일에 저장되어 있기 때문에, 학습 데이타를 읽을때 메타데이타나 라벨용 파일 하나만 읽는 것이 아니라 이미지 파일도 별도로 읽어야 하기 때문에, 코드가 복잡해진다.


또한 이미지를 JPG나 PNG 포맷으로 읽어서 매번 디코딩을 하게 되면, 그 성능이 저하되서 학습단계에서 데이타를 읽는 부분에서 많은 성능 저하가 발생한다.


이와 같이 성능과 개발의 편의성을 이유로 TFRecord 파일 포맷을 이용하는 것이 좋다.


위와 같은 이유로 TFRecord 파일로 변환하기 위해서 labelImg를 통해 생성한 xml 파일을 먼저 CSV 파일로 변환해야 한다.


① xml 파일을 csv 파일로 변환하기 위해 Dat Tran 블로거가 작성한 xml_to_csv.py 스크립트를 사용한다.

github: https://github.com/datitran/raccoon_dataset

raccoon_dataset 의 xml_to_csv.py 스크립트를 수정하여 사용한다.


Within the xml_to_csv script, I changed:



def main():
    image_path
= os.path.join(os.getcwd(), 'annotations')
    xml_df
= xml_to_csv(image_path)
    xml_df
.to_csv('raccoon_labels.csv', index=None)
   
print('Successfully converted xml to csv.')
cs

To:



def main():
   
for directory in ['train','test']:
        image_path
= os.path.join(os.getcwd(), 'images/{}'.format(directory))
        xml_df
= xml_to_csv(image_path)
        xml_df
.to_csv('data/{}_labels.csv'.format(directory), index=None)
       
print('Successfully converted xml to csv.')
cs


 

생성된 CSV 파일을 Object-Detection 디렉토리에 data 디렉토리를 생성하고, data 디렉토리로 csv 파일을 옮긴다. 그리고 Object-Detection 디렉토리에 training 디렉토리를 생성한다. 지금까지의 디렉토리 구조는 아래와 같다.

Object-Detection
-data/
--test_labels.csv
--train_labels.csv
-images/
--test/
---testingimages.jpg
--train/
---testingimages.jpg
--...yourimages.jpg
-training
-xml_to_csv.py
cs


② 이제 CSV 파일을 TFRecord파일로 변환하기 위해 Dat Tran 블로거가 작성한 generate_tfrecord.py 스크립트를 사용한다.

Within the generate_tfrecord script, I changed:



# TO-DO replace this with label map
def class_text_to_int(row_label):
    if row_label == 'raccoon':
        return 1
    else:
        None

cs

To:



# TO-DO replace this with label map
def class_text_to_int(row_label):
    if row_label == 'macncheese':
        return 1
    else:
        None
cs


TODO 현재 Class가 macncheese 한 종류이기 때문에 하나만 작성한다. 만약 여러개의 클래스가 있다면 이부분을 수정해야 한다.


이제 generate_tfrecord.py 스크립트를 수행한다. train TFRecord와 test TFRecord를 위해 두번 수행하게 된다.

train TFRecord:



python generate_tfrecord.py --csv_input=data/train_labels.csv  --output_path=data/train.record
cs

test TFRecord:



python generate_tfrecord.py --csv_input=data/test_labels.csv  --output_path=data/test.record
cs


Next up, we need to setup a configuration file and then either train a new model or start from a checkpoint with a pre-trained model, which is what we'll be covering in the next tutorial.

Posted by 이성윤