일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 가운데 글자 가져오기 python
- 프로그래머스 나누어 떨어지는 숫자 배열 자바
- 코드업 1020 java
- 가운데 글자 가져오기 자바
- 트리의 지름 자바
- 트리의 지름 java
- docker 삭제
- 빅분기실기
- 프로그래머스 가운데 글자 가져오기 python
- 가운데 글자 가져오기 파이썬
- 최소 스패닝 트리 자바
- 프로그래머스 나누어 떨어지는 숫자 배열 파이썬
- 청년 Ai Big Data 아카데미
- docker remove
- codeup 1020 자바
- 코드업 1020 자바
- codeup 1020 java
- 프로그래머스 가운데 글자 가져오기 자바
- docker 완전 삭제
- 가운데 글자 가져오기 java
- 핸즈온 머신러닝
- 나누어 떨어지는 숫자 배열 java
- 최단 경로 알고리즘
- m1 docker install
- 최소 스패닝 트리
- m1 docker
- 빅데이터분석기사
- 나누어 떨어지는 숫자 배열 python
- 청년 AI Big Data 아카데미 13기
- 프로그래머스 가운데 글자 가져오기 파이썬
- Today
- Total
NineTwo meet you
SSD Mobilenet 환경 세팅 및 데이터 학습 진행 튜토리얼 본문
0. 기본 환경
- Ubuntu 18.04
- Nvidia-driver 450
- cuda 10.2
- cudnn 8.2
1. 가상환경 세팅
$ conda create -n tSSD
$ conda activate
의존성 패키지 설치
$ pip install tensorflow
// Tensorflow와 함께 사용할 수 있는 GPU가 있는 경우
$ pip install tensorflow-gpu
$ pip install pillow Cython lxml jupyter matplotlib
2. Tensorflow model repository clone
~/anaconda/envs/<your_env_name>/lib/python3.6/site-packages/tensorflow로 이동한다.
해당 위치는 설치한 가상환경에 따라 조금씩 다를것이라 예상된다.
$ cd ~/anaconda/envs/tSSD/lib/python3.6/site-packages/tensorflow
$ git clone https://github.com/tensorflow/models.git
3. 환경 세팅
매번 새 터미널을 실행할때마다 다음 명령어를 수행해야 한다.
아니면 다음 ModuleNotFoundError: No module named 'object_detection'라는 에러가 발생한다.
$ cd <경로_to_your_tensorflow_installation>/models/research/
$ protoc object_detection/protos/*.proto --python_out=.
$ export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim
다음 명령어를 실행했을때 별다른 오류없이 잘 됐다는 메세지가 뜨면 잘 설치된 것을 확인할 수 있다.
$ python object_detection/builders/model_builder_test.py
4. 폴더 구조화
다음은 권장하는 models 폴더의 structure 입니다.
annotations, images등 폴더를 생성합니다.
annotations/xmls에 데이터 라벨링한 xml 파일을 저장하고, images 아래 train 과 test에는 jpg 파일을 적당한 비율(7:3)로 나누어 저장합니다.
models
- annotations
-- xmls
- images
-- train
-- test
- checkpoints
- tf_record
- research
- ...
5. label_map.pbtxt 생성 & trainval.txt 생성
5-1)
label_map.pbtxt 파일을 annotations디렉토리 안에 생성합니다.
예를 들어, 사과과 바나나라는 클래스가 있다면 아래와 같이 작성합니다.
이때 id 0값은 예약되어 있기 때문에 주의해야 할 점은 id값은 1부터 시작해야 합니다.
item {
id: 1
name: 'apple'
}
item {
id: 2
name: 'banana'
}
5-2)
trainval.txt 파일을 annotations디렉토리 안에 생성합니다.
아래와 같이 이미지 이름을 확장자없이 나열합니다.
apple1
apple2
banana1
apple3
banana2
:
6. XML 파일-> CSV 파일
XML 파일을 CSV 파일로 전환해야 합니다.
첨부된 링크의 코드를 참고해 XML파일을 CSV파일로 변환할 수 있습니다.
다만 가지고 있는 이미지 파일명이 순차적이지 않았기 때문에 아래 예시처럼 train과 test별로 나눠 python코드를 실행했습니다. 수행하고 나면 data 폴더 안에 train_labels.csv와 test_labels.csv가 저장됩니다.
test_xml_csv.py
import os
import glob
import pandas as pd
import xml.etree.ElementTree as ET
test_dir = '/home/XXX/anaconda3/envs/tSSD/lib/python3.6/site-packages/tensorflow/models/images/test'
test_list = os.listdir(test_dir)
def test_xml_to_csv():
xml_list = []
for f in test_list:
xml_file = '/home/XXX/anaconda3/envs/tSSD/lib/python3.6/site-packages/tensorflow/models/annotations/xmls/'+f[:-4]+'.xml'
tree = ET.parse(xml_file)
root = tree.getroot()
for member in root.findall('object'):
value = (root.find('filename').text,
int(root.find('size')[0].text),
int(root.find('size')[1].text),
member[0].text,
int(member[4][0].text),
int(member[4][1].text),
int(member[4][2].text),
int(member[4][3].text)
)
xml_list.append(value)
column_name = ['filename', 'width', 'height', 'class', 'xmin', 'ymin', 'xmax', 'ymax']
xml_df = pd.DataFrame(xml_list, columns=column_name)
return xml_df
def main():
xml_df = test_xml_to_csv()
xml_df.to_csv('data/test_labels.csv', index=None)
main()
train_xml_csv.py
import os
import glob
import pandas as pd
import xml.etree.ElementTree as ET
train_dir = '/home/XXX/anaconda3/envs/tSSD/lib/python3.6/site-packages/tensorflow/models/images/train'
train_list = os.listdir(train_dir)
def train_xml_to_csv():
xml_list = []
for f in train_list:
xml_file = '/home/XXX/anaconda3/envs/tSSD/lib/python3.6/site-packages/tensorflow/models/annotations/xmls/'+f[:-4]+'.xml'
tree = ET.parse(xml_file)
root = tree.getroot()
for member in root.findall('object'):
value = (root.find('filename').text,
int(root.find('size')[0].text),
int(root.find('size')[1].text),
member[0].text,
int(member[4][0].text),
int(member[4][1].text),
int(member[4][2].text),
int(member[4][3].text)
)
xml_list.append(value)
column_name = ['filename', 'width', 'height', 'class', 'xmin', 'ymin', 'xmax', 'ymax']
xml_df = pd.DataFrame(xml_list, columns=column_name)
return xml_df
def main():
xml_df = train_xml_to_csv()
xml_df.to_csv('data/train_labels.csv', index=None)
main()
7. TFRecord 생성 및 config 파일 수정
generate_tfrecord.py를 자기 클래스에 맞춰서 수정해 models/research/object_detection/dataset_tools/ 에 저장합니다.
코드의 TO-DO부분을 수정합니다.
앞서 생성한 label_map.pbtxt의 id가 여기서 return 값이 되고 row_label은 name값이 됩니다.
# TO-DO replace this with label map
def class_text_to_int(row_label):
if row_label == 'apple':
return 1
if row_label == 'banana':
return 2
else:
None
/models에서 다음과 같이 코드를 train과 test 두 번 수행하고 나면 train.record와 test.record 파일이 생성됩니다.
# train
$ python research/object_detection/dataset_tools/generate_tfrecord.py --csv_input=data/train_labels.csv --output_path=train.record --image_dir=images/train
# test
$ python research/object_detection/dataset_tools/generate_tfrecord.py --csv_input=data/test_labels.csv --output_path=test.record --image_dir=images/test
AttributeError: module 'tensorflow' has no attribute 'app' 에러 발생시 generate_tfrecord.py 에서
import tensorflow as tf -> import tensorflow.compat.v1 as tf 로 바꾸면 해결됩니다.
8. pre-trained model 다운로드
pre-trainde된 model을 다운받고 /models/checkpoints경로 아래 다음 3가지의 파일을 저장합니다.
/tensorflow 폴더에서 다음 명령어를 실행해 ssd_mobilenet_v2_ coco.config파일을 models/ 로 복사합니다.
$ cp models/research/object_detection/samples/configs/ssd_mobilenet_v2_ coco.config models/
ssd_mobilenet_v2_ coco 파일에서 3가지 사항을 수정합니다.
1. num_classes 변경
ssd {
num_classes: 2 # 자기 클래스 개수로 변경
box_coder {
faster_rcnn_box_coder {
y_scale: 10.0
x_scale: 10.0
height_scale: 5.0
width_scale: 5.0
}
}
2. fine_tune_checkpoint 변경
fine_tune_checkpoint: "checkpoints/model.ckpt" # model.ckpt 경로 입력
3. train, eval input reader 변경
train_input_reader: {
tf_record_input_reader {
input_path: "train.record" # train.record 경로 입력
}
label_map_path: "annotations/label_map.pbtxt" # label_map.pbtxt 경로 입력
}
eval_input_reader: {
tf_record_input_reader {
input_path: "test.record" # test.record 경로 입력
}
label_map_path: "annotations/label_map.pbtxt" # label_map.pbtxt 경로 입력
shuffle : false
num_readers : 1
}
해당 파일을 수정하다 google.protobuf.text_format.ParseError 오류가 발생하면 해당 config 파일에 오타가 발생했다는 의미이므로 다시 잘 살펴봐야 한다.
9. Train
models디렉토리에서 train, eval 디렉토리를 만들고 train.py를 실행합니다.
train.py가 research/object_detection에 없으면 찾아봐야 합니다. 찾은 경로의 파일을 실행합니다.
교육 시간은 컴퓨터의 컴퓨팅 성능에 따라 다릅니다. 보통 200000번이 돌아가게 되는데 train.py가 돌아가는 도중 마감해도 됩니다.
# 모델 디렉토리로 변경
$ cd tensorflow/models
# 학습 진행 상황을 저장할 디렉토리를 만듭니다.
$ mkdir train
# 유효성 검사 결과를 저장할 디렉토리를 만듭니다.
$ mkdir eval
# 훈련 시작
$ python research/object_detection/legacy/train.py \
--logtostderr \
--train_dir=train \
--pipeline_config_path=ssd_mobilenet_v2_coco.config
ValueError: ssd_mobilenet_v2 is not supported. See `model_builder.py` for features extractors compatible with different versions of Tensorflow 에러가 발생하는 경우 tensorflow 1.15.0버전을 설치해줍니다.
$ !pip install tensorflow==1.15.0
10. Evaluation
models디렉토리에서 eval.py를 실행합니다. train.py와 병행하여 실행할 수 있습니다.
train.py와 마찬가지로 research/object_detection에 없으면 찾아봐야 합니다. 찾은 경로의 파일을 실행합니다.
$ python research/object_detection/lecacy/eval.py
\--logtostderr
\--pipeline_config_path=ssd_mobilenet_v2_coco.config
\--checkpoint_dir=train
\--eval_dir=eval
"tensorflow.python.framework.errors_impl.FailedPreconditionError: ." 간혹 이런 에러가 발생하는 경우 명령어에 잘못된 tab이나 공백을 포함했다는 의미로 명령어를 하나씩 쳐서 다시 실행해야 합니다.
11. Model Export
train을 마치고 /train을 살펴보면 많은 파일이 생긴것을 확인할 수 있다.
/models 디렉토리에서 fine_tuned_model디렉토리를 생성하고 다음 명령어를 입력한다.
이때 <the_highest_checkpoint_number>에는 가장 높은 숫자를 작성하면 된다.
또한 파일명 뒤에 .meta .index .data 등은 입력하지 않습니다.
$ mkdir fine_tuned_model
$ python research/object_detection/export_inference_graph.py \
--input_type image_tensor \
--pipeline_config_path ssd_mobilenet_v2_coco.config \
--trained_checkpoint_prefix train/model.ckpt-<the_highest_checkpoint_number> \
--output_directory fine_tuned_model
12. Object Detection
models/research/colab_tutorials/object_detection_tutorial.ipynb 파일이 존재합니다. jupyter notebook을 열어서 다음코드를 순서대로 노트북으로 실행하면 됩니다. 다음 블로그의 .py와 .ipynb 파일을 섞어서 사용했습니다. Here 경로를 환경에 맞춰 설정해 사용해야 합니다. 가지고 있던 데이터가 (XXX, XXX) 형태와 (XXX, XXX, 3) 두가지 형태로 되어있어 tensor를 load_image_into_numpy_array에서 tensor를 맞춰주는 return 값을 2개로 수정했습니다.
!pip3 install --upgrade pip
!pip3 install -U --pre tensorflow=="2.*"
!pip3 install tf_slim
!pip install pathlib
import os
import pathlib
if "models" in pathlib.Path.cwd().parts:
while "models" in pathlib.Path.cwd().parts:
os.chdir('..')
elif not pathlib.Path('models').exists():
!git clone --depth 1 https://github.com/tensorflow/models
%%bash
cd /home/piai/anaconda3/envs/tSSD/lib/python3.6/site-packages/tensorflow/models/research/
protoc object_detection/protos/*.proto --python_out=.
export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim
%cd ./models/research
import numpy as np
import os
import six.moves.urllib as urllib
import sys
import tarfile
import tensorflow as tf
import zipfile
from collections import defaultdict
from io import StringIO
from matplotlib import pyplot as plt
from PIL import Image
from object_detection.utils import ops as utils_ops
if tf.__version__ < '1.4.0':
raise ImportError('Please upgrade your tensorflow installation to v1.4.* or later!')
from object_detection.utils import label_map_util
from object_detection.utils import visualization_utils as vis_util
# What model to download.
MODEL_NAME = 'ssd_mobilenet_v2_coco_2018_03_29'
MODEL_FILE = MODEL_NAME + '.tar.gz'
DOWNLOAD_BASE = 'http://download.tensorflow.org/models/object_detection/'
# Path to frozen detection graph. This is the actual model that is used for the object detection.
PATH_TO_CKPT = '/home/XXX/anaconda3/envs/tSSD/lib/python3.6/site-packages/tensorflow/models/fine_tuned_model/frozen_inference_graph.pb' # Here
# List of the strings that is used to add correct label for each box.
PATH_TO_LABELS = '/home/XXX/anaconda3/envs/tSSD/lib/python3.6/site-packages/tensorflow/models/annotations/label_map.pbtxt' # Here
NUM_CLASSES = 2 # Here
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())
detection_graph = tf.Graph()
with detection_graph.as_default():
od_graph_def = tf.compat.v1.GraphDef()
with tf.compat.v2.io.gfile.GFile(PATH_TO_CKPT, 'rb') as fid:
serialized_graph = fid.read()
od_graph_def.ParseFromString(serialized_graph)
tf.import_graph_def(od_graph_def, name='')
label_map = label_map_util.load_labelmap(PATH_TO_LABELS)
categories = label_map_util.convert_label_map_to_categories(label_map, max_num_classes=NUM_CLASSES, use_display_name=True)
category_index = label_map_util.create_category_index(categories)
def load_image_into_numpy_array(image):
# return tf.image.grayscale_to_rgb(tf.convert_to_tensor(np.array(image))[...,tf.newaxis]).numpy() # if image shape is (XXX, XXX)
return np.array(image) # if image shape is (XXX, XXX, 3)
# TEST_IMAGES PATH
PATH_TO_TEST_IMAGES_DIR = pathlib.Path('/home/XXX/anaconda3/envs/tSSD/lib/python3.6/site-packages/tensorflow/models/images/test') # Here
TEST_IMAGE_PATHS = sorted(list(PATH_TO_TEST_IMAGES_DIR.glob("*.jpg")))
# Size, in inches, of the output images.
IMAGE_SIZE = (120, 80)
def run_inference_for_single_image(image, graph):
with graph.as_default():
with tf.compat.v1.Session() as sess:
# Get handles to input and output tensors
ops = tf.compat.v1.get_default_graph().get_operations()
all_tensor_names = {output.name for op in ops for output in op.outputs}
tensor_dict = {}
for key in [
'num_detections', 'detection_boxes', 'detection_scores',
'detection_classes', 'detection_masks'
]:
tensor_name = key + ':0'
if tensor_name in all_tensor_names:
tensor_dict[key] = tf.compat.v1.get_default_graph().get_tensor_by_name(tensor_name)
if 'detection_masks' in tensor_dict:
# The following processing is only for single image
detection_boxes = tf.squeeze(tensor_dict['detection_boxes'], [0])
detection_masks = tf.squeeze(tensor_dict['detection_masks'], [0])
# Reframe is required to translate mask from box coordinates to image coordinates and fit the image size.
real_num_detection = tf.cast(tensor_dict['num_detections'][0], tf.int32)
detection_boxes = tf.slice(detection_boxes, [0, 0], [real_num_detection, -1])
detection_masks = tf.slice(detection_masks, [0, 0, 0], [real_num_detection, -1, -1])
detection_masks_reframed = utils_ops.reframe_box_masks_to_image_masks(
detection_masks, detection_boxes, image.shape[0], image.shape[1])
detection_masks_reframed = tf.cast(
tf.greater(detection_masks_reframed, 0.5), tf.uint8)
# Follow the convention by adding back the batch dimension
tensor_dict['detection_masks'] = tf.expand_dims(
detection_masks_reframed, 0)
image_tensor = tf.compat.v1.get_default_graph().get_tensor_by_name('image_tensor:0')
# Run inference
output_dict = sess.run(tensor_dict,
feed_dict={image_tensor: np.expand_dims(image, 0)})
# all outputs are float32 numpy arrays, so convert types as appropriate
#output_dict['num_detections'] = int(output_dict['num_detections'][0])
output_dict['num_detections'] = int(tf.get_static_value(output_dict.pop('num_detections'))[0])
output_dict['detection_classes'] = output_dict[
'detection_classes'][0].astype(np.uint8)
output_dict['detection_boxes'] = output_dict['detection_boxes'][0]
output_dict['detection_scores'] = output_dict['detection_scores'][0]
if 'detection_masks' in output_dict:
output_dict['detection_masks'] = output_dict['detection_masks'][0]
return output_dict
for image_path in TEST_IMAGE_PATHS:
image = Image.open(image_path)
# the array based representation of the image will be used later in order to prepare the
# result image with boxes and labels on it.
image_np = load_image_into_numpy_array(image)
# Expand dimensions since the model expects images to have shape: [1, None, None, 3]
# Actual detection.
output_dict = run_inference_for_single_image(image_np, detection_graph)
# Visualization of the results of a detection.
vis_util.visualize_boxes_and_labels_on_image_array(
image_np,
output_dict['detection_boxes'],
output_dict['detection_classes'],
output_dict['detection_scores'],
category_index,
instance_masks=output_dict.get('detection_masks'),
use_normalized_coordinates=True,
line_thickness=8)
plt.figure(figsize=IMAGE_SIZE)
plt.imshow(image_np)
print ('img',image_path)
plt.savefig(str(image_path)[:-3]+'png')
참고자료
https://seoftware.tistory.com/108
https://towardsdatascience.com/custom-object-detection-using-tensorflow-from-scratch-e61da2e10087
https://github.com/tensorflow/models/issues?q=
'기타' 카테고리의 다른 글
이클립스 깃허브 연동 (0) | 2021.08.11 |
---|---|
Yolov3 환경 세팅 및 데이터 학습 진행 튜토리얼 (0) | 2021.08.10 |
Yolo v5 환경 세팅 및 데이터 학습 진행 튜토리얼 (0) | 2021.07.21 |
[GitHub] Github README로 Profile 꾸미기(4) (1) | 2021.07.18 |
Ubuntu 18.04 openCV 설치 및 완전 삭제 (0) | 2021.07.12 |