Broccoli's House

#6-(1) 훈련 데이터 불러오기 본문

공부/캡스톤 디자인

#6-(1) 훈련 데이터 불러오기

김콜리 2018. 3. 22. 01:30

6회차 - (1) 훈련 데이터 수집 완료



  • 텍스트 파일 불러오기


 - 훈련 데이터를 수집할 때 로지텍 G27로부터 파이썬 라이브러리 Pygame을 이용하여 조향 데이터와 브레이크 데이터, 스로틀 데이터를 받아와 텍스트 파일로 저장하였다. 이 데이터들은 각 이미지에 대한 레이블(label)이 된다. 학습을 위해 텍스트 파일로부터 각 데이터들을 리스트의 형태로 받아온다.



path = '~/Training Data/' # 훈련 데이터가 저장된 경로 선언

Text_steering = open("%sSteering_Data.txt" % path, 'r') # 조향 데이터 텍스트 파일 오픈
Text_throttle = open("%sThrottle_Data.txt" % path, 'r') # 스로틀 데이터 텍스트 파일 오픈
Text_Brake = open("%sBrake_Data.txt" % path, 'r') # 브레이크 데이터 텍스트 파일 오픈

Steering_label = Text_steering.read().splitlines() # 줄바꿈을 기준으로 데이터 구분
Throttle_label = Text_throttle.read().splitlines()
Brake_label = Text_Brake.read().splitlines() 


 - 먼저 훈련 데이터가 저장된 경로를 지정한 후, open() 명령을 사용하여 텍스트 파일을 읽기 전용으로 받아온다. 각 데이터들은 \n을 통해 줄바꿈으로 구분되어 있다. readlines() 명령을 사용하면 줄바꿈을 기준으로 각 데이터들을 구분하여 리스트에 저장할 수 있으나, 이렇게 하면 각 데이터 뒤에 \n이 붙어서 나오기 때문에 추가적인 작업을 해주어야만 한다. 그보다 간단하게 read() 명령을 사용하여 모든 데이터를 한 줄로 받아온 후, splitlines() 명령을 통해 줄바꿈을 기준으로 데이터를 받아오면서 \n은 제거하도록 한다. 이렇게 하면 어렵지 않게 레이블을 각각의 리스트에 저장할 수 있다.




  • 이미지 파일 불러오기


 - 텍스트 파일을 불러오는 것에 비해 이미지 파일을 불러오는 것은 매우 까다롭다. 조향이나 스로틀, 브레이크 데이터는 하나의 텍스트 파일 안에 데이터 전체가 들어있지만 이미지는 각각 하나가 파일이기 때문이다. 또한 이미지는 텍스트 파일에 비해 크기가 크기 때문에 불러오는데 많은 메모리 공간을 차지한다. 즉, 레이블이 되는 텍스트 데이터들은 한 번에 18만개의 데이터를 리스트에 저장할 수 있지만, 이미지는 그렇게 할 수 없다. 따라서 배치 크기만큼의 이미지만 불러와서 리스트에 저장하는 방식을 사용한다.


import os
from PIL import Image

path = '~/Training Data/' # 훈련 데이터가 저장된 경로
file_list = os.listdir(path) # 훈련 데이터 폴더의 전체 목록
img_list = [] # 이미지 데이터 목록
batch_size = 100 # 배치 크기

for item in file_list :
if item.find('.PNG') is not -1 :
img_list.append(item)
# 훈련 데이터의 전체 목록에서 PNG의 이름이 들어간 목록만 남겨둔다.
# 즉, 이미지 데이터의 목록만 받아온다.

total_img = len(img_list) # 전체 훈련 이미지 개수
total_batch = int(total_img / batch_size) # 학습 시 불러야하는 배치의 수

for batch_count in range(total_batch) :

images = [] # 이미지가 들어갈 리스트, 다음 배치 때 초기화된다.
batch_index = batch_count * batch_size # 배치 순서 계산

for name in img_list[batch_index : (batch_index + batch_size)] :
# 0~99, 100~199, 200~299, 300~399...
# 이미지 데이터 목록에서 해당 배치 순서의 이미지 이름을 받아옴

img = Image.open('%s%s'%(path, name)) # 해당 배치 순서에서 해당 이름의 이미지 오픈
images.append(img) # 이미지 리스트에다 이미지를 추가 


 - 각 이미지를 불러오기 위해서는 이미지의 이름을 알고 있어야 한다. 이미지 이름을 지정한 포맷이 시간이라 이미지를 숫자 인덱스로는 불러올 수 없기 때문에, 먼저 훈련 데이터가 저장된 폴더에서 listdir() 명령을 사용하여 이미지의 목록을 받아온다. 훈련 데이터 폴더 안에는 이미지 뿐만 아니라 텍스트 파일도 같이 들어있으므로 PNG 확장자를 가진(이름을 가진) 이미지만을 리스트에다 추가해준다.

 - 메모리 용량 초과로 인해 전체 이미지를 하나의 리스트에 저장하는 것은 불가능하므로 배치 크기인 100개의 이미지만 불러와 리스트에 저장한다. 이렇게 하기 위해서는 180,900개의 전체 데이터에서 배치(batch)의 순서, 해당 배치에서 개개의 이미지의 순서 이 두가지가 필요하다. 전체 이미지 개수를 배치 크기로 나누어 배치(batch)의 전체 개수를 구하고, 그 배치의 전체 개수(total_batch)내에서 반복문을 통해 해당 배치의 순서, 인덱스(batch_index)를 알게 한다. 그 다음, 이미지 목록에서 배치 인덱스에서 다음 인덱스 직전까지의 이미지 100개의 이름을 받아와 해당 이미지를 오픈하고, 이미지 리스트에다 추가해준다.


Comments