검색결과 리스트
글
TensorFlow 를 이용한 CNN
TensorFlow 와 같은 딥러닝을 위한 프레임워크를 사용하면, 손쉽게 개발을 할 수 있습니다.
하지만 각종 matrix 연산을 편하게 해 줄 뿐 - 물론 편의를 위한 util 들도 있습니다만, - NN 에 해당하는 것들은 직접 개발해 주어야 하죠. 그래서 contrib 에 해당하는 코드들도 많은 것이고요.
나만의 CNN 전용 스크립트
CNN 을 개발하다보면, 하이퍼 파라미터를 바꿔야 하는 일이 빈번합니다.
그리고 Network(Graph) 도 자주 바꿔야 하죠.
그때마다 일일이 스크립트를 수정하는 일은 매우 소모적이고 지루한 일이 아닐 수 없습니다.
작업을 하다가 Rollback 하는것도 쉽지 않고요.
그렇다고 매번 스크립트를 새로 만드는 것도 유지보수 차원에서 힘이 듧니다.
개발자가 가장 싫어하는 일명 '노가다'
제가 만들어 사용하고 있는 스크립트를 공개합니다. :)
배포용으로 만든것이 아니라, 어디까지나 제가 실제로 쓰고있는 것이라 네이밍이라든지, 코드라든지
깔끔하지 않은 부분들이 있다는점 미리 말씀드립니다.
TensorFlow 의 FLAG 를 사용했기에, 정리가 안되서 help 가 좀 복잡한데요.
먼저 help 를 통해 전체 옵션을 보면 아래와 같습니다.
참고로, mandatory 인지 optional 인지 표기는 신경쓰지 마세요.(잘못 된거에요 ㅎ)
$ python ./runner.py --hel
p
usage: runner.py [-h] [--mode MODE] [--data_dir DATA_DIR] [--ckpt CKPT]
[--network NETWORK] [--pb PB] [--map MAP]
[--out_node OUT_NODE] [--event_dir EVENT_DIR]
[--out_dir OUT_DIR] [--model_version MODEL_VERSION]
[--image IMAGE] [--num_of_classes NUM_OF_CLASSES]
[--title TITLE] [--scaling [SCALING]] [--noscaling]
[--image_size IMAGE_SIZE] [--image_crop_size IMAGE_CROP_SIZE]
[--log_input [LOG_INPUT]] [--nolog_input]
[--grayscale [GRAYSCALE]] [--nograyscale]
[--log_feature [LOG_FEATURE]] [--nolog_feature]
[--use_fp16 [USE_FP16]] [--nouse_fp16]
[--max_steps MAX_STEPS] [--save_steps SAVE_STEPS]
[--batch_size BATCH_SIZE] [--continue_train [CONTINUE_TRAIN]]
[--nocontinue_train] [--log_frequency LOG_FREQUENCY]
[--log_device_placement [LOG_DEVICE_PLACEMENT]]
[--nolog_device_placement] [--error_dir ERROR_DIR]
[--learning_rate LEARNING_RATE]
optional arguments:
-h, --help show this help message and exit
--mode MODE Mode {train | eval | export | single | resize | pb |
map-export | map-inference} DEFAULT=eval
--data_dir DATA_DIR Path to data.
--ckpt CKPT The directory where checkpoint file is.
--network NETWORK File Path to network.
--pb PB pb File.
--map MAP Map File Path.
--out_node OUT_NODE Name of out node. DEFAULT=softmax_linear/softmax
--event_dir EVENT_DIR
Path to events.
--out_dir OUT_DIR Path to data output(for resize mode).
--model_version MODEL_VERSION
Model version for Tensorflow Serving.
--image IMAGE Image file for single evaluation.
--num_of_classes NUM_OF_CLASSES
Number of classes.
--title TITLE Name of network. DEFAULT=unknown
--scaling [SCALING] Scaling Input Images. DEFAULT=True
--noscaling
--image_size IMAGE_SIZE
Image size(width == height) DEFAULT=100
--image_crop_size IMAGE_CROP_SIZE
Image crop size(width == height) DEFAULT=80
--log_input [LOG_INPUT]
Log input image. DEFAULT=True
--nolog_input
--grayscale [GRAYSCALE]
Make input images to grayscale. DEFAULT=True
--nograyscale
--log_feature [LOG_FEATURE]
Log feature maps. DEFAULT=False
--nolog_feature
--use_fp16 [USE_FP16]
Use float16. DEFAULT=False
--nouse_fp16
--max_steps MAX_STEPS
Max steps for training. DEFAULT=20000
--save_steps SAVE_STEPS
How often to save steps. DEFAULT=100
--batch_size BATCH_SIZE
Max steps for training. DEFAULT=64
--continue_train [CONTINUE_TRAIN]
Training continued. DEFAULT=True
--nocontinue_train
--log_frequency LOG_FREQUENCY
How often to log result to the console. DEFAULT=100
--log_device_placement [LOG_DEVICE_PLACEMENT]
Where to log device placement. DEFAULT=False
--nolog_device_placement
--error_dir ERROR_DIR
Path to copy errors.
--learning_rate LEARNING_RATE
Learning rate. DEFAULT = 0.005
0. 사전에 알아둘 것
해당 스크립트는 Classification 을 위한 것입니다.
그리고 데이터는 별도 라벨링을 하지 않습니다.
폴더 명으로 자동 라벨링 됩니다.
그리고 폴더명은 0부터 시작하여 숫자로 되어 있어야 합니다.
예를들어 사탕, 사과, 딸기 라는 세개의 Class 가 있다면, 폴더의 구조는
이런형태가 되어야 합니다.
0 이 사탕, 1 이 사과, 2 가 딸기라는 정보는 따로 받지 않습니다.
index 와 string map 을 만들면 되긴 하는데, 저는 그냥 쓰고 있습니다. :)
Eval 과 Train 으로 폴더 구분한건, 필수사항이 아닙니다.
저는 그냥 저렇게 나눠놓는게 편하더라고요.
1. 학습
학습을 위한 커맨드는 다음과 같습니다.
python ./runner.py --mode=train --ckpt=/tmp/MyClassifier --data_dir=/DataSet/Object
/Train
사용 가능한 모든 파라메타는 다음과 같습니다.
python ./runner.py --mode=train --ckpt=/tmp/MyClassifier --data_dir=/DataSet/Object
/Train --network=nn_default --max_steps=10000 --image_size=100 --image_crop_size=80 --continue_train=False --grayscale=False --scaling=True --log_feature=True --use_fp16=True --batch_size=64 --learning_rate=0.01
대충 파라미터를 보면 아실거라고 생각되니, 모든것에 대해서 자세한 설명은 따로 하지 않겠습니다.
알아둬야 할 점 몇 가지를 말씀 드립니다.
기본적으로 scaling 값은 True 입니다.
내부적으로 학습에 정사각형 형태의 이미지를 사용하는데요.
직사각형을 넣게 되더라도 내부적으로 정사각형 이미지로 바꿔 줍니다.
그래서 학습하거나 검증할때, 이미지를 사전에 정사각형으로 만들어서 넣어 줄 필요가 없죠.
이때 True 값이면, 입력한 이미지를 정사각형 형태로 Scaling(크기는 image_size 파라미터 값) 해 줍니다.
만약 False 값이면, 입력한 이미지를 크기 조절없이 image_crop 값으로 Cropping 해 버립니다.
더불어 True 더라도, 이미지를 정사각형 형태로 먼저 scaling 하고, 이후에 image_crop 사이즈로 cropping 하는것은 마찬가지 입니다.
image_size 와 image_crop_size 가 동일하고, scaling 이 True 라면, cropping 은 무시되는 셈이죠. :)
그리고 network=nn_default 라는 부분이 있는데요.
매번 CNN 을 개발하다보면, 수시로 graph 구성을 바꾸게 됩니다. 이게 워낙 귀찮은 일이 아닐 수 없지요.
그래서 저는 network 부분만 독립된 파일로 구성하게 하였습니다.
소스를 열어보시면 아시겠지만,
def crop_image(images):
def inference(images, keep_prob, batch_size, image_crop_size, input_channels, num_of_classes, variable_with_weight_decay, variable_on_cpu, activation_summary, log_input, log_feature):
이렇게 2개의 메소드만 들어있는 python 파일입니다.
crop_image 는 학습/검증 이전에 input 으로 들어가는 이미지를 수정할때 사용됩니다.
참, mode 값이 train 일때는 자동으로 입력된 이미지에 대해서 distortion 을 합니다.
밝기라든지, 색조라든지, 랜덤 크로핑이라든지..(랜던 크로핑은 image_size 와 image_crop_size 의 차이)..
이 이외의 작업을 하고 싶을때 crop_image() 메소드 부분에서 처리할 수 있습니다.
참고로 이미지를 입력 받고, 가장 먼저 호출되는 부분입니다.
grayscale 은 input 이미지를 1채널 흑백으로 할거냐, 3채널 그대로 쓸거냐의 옵션입니다.
기본값은 True 입니다. 그러니 3 채널 이미지를 그대로 쓰고 싶다면 옵션을 False 로 넣어주어야 합니다.
log_feature 는 graph 에서 각 conv 맵을 tensorboard 에서 확인 할 수 있도록, summary 에 넣을지 말지에 대한 옵션입니다.
기본값은 False 입니다.
2. 검증
검증을 위한 커맨드는 다음과 같습니다.
python ./runner.py --mode=eval --ckpt=/tmp/MyClassifier --data_dir=/DataSet/
Object/Eval --event_dir=/tmp/MyClassifier/Eval
ckpt 는 앞서 학습할때 넣었던 경로 그대로 넣어줍니다.
data_dir 은 검증에 사용할 파일들이 있는 디렉토리고요. 마찬가지로 0, 1, 2, 3... 형태의 폴더들이 있습니다.
event_dir 은 evalutation 의 summary 를 저장할 경로입니다. TensorBoard 를 위한 것이죠.
이때, image_size 라든지 grayscale 이라든지 Train 할때 사용했던 하이퍼 파라미터는 내부적으로 불러와서 사용됩니다.
그러니 직접 입력할 필요가 없습니다.(물론 다르게 입력해도 안 됩니다.)
3. 단일파일 검증
폴더 통째로 Evaluation 하는것 이외에, 한 개의 이미지 파일을 넣어 어떤 Class 로 분류되었는지 확인할 수 있습니다.
python ./runner.py --mode=single --ckpt=/tmp/MyClassifier --image=/DataSet/Object/Apple.jpg
4. *.pb 파일로 export 하기
학습된 Graph, 와 Weight 를 포함한 모델파일을 export 할 수 있습니다.
python ./runner.py --mode=export --ckpt=/tmp/MyClassifier
이렇게 하고나면, frozon.pb 와 optimized.pb 파일 두 개가 나옵니다.
optimized.pb 를 사용하시면 됩니다.
5. *.pb 파일로 단일파일 검증
TensorFlow 의 ckpt 의 파일이 아닌, export 한 *.pb 파일로 검증할 수도 있습니다.
python ./runner.py --mode=pb --pb=/tmp/MyClassifier/optimized.pb --image=/DataSet/Object/Eval/0/Apple.jpg
7. Weight Map 추출하기
CNN 의 특정 Layer 의 Weights 들을 추출해서 파일로 저장할 수 있습니다.
이 weights 들은 다양한 곳에 쓰일 수 있습니다. :)
python ./runner.py --mode=map-export --pb=/tmp/MyClassifier/optimized.pb --data_dir=/DataSet/Object/Eval --map=/tmp/map.txt
이렇게 하면, Eval 안에 있는 모든 이미지 파일들을 찾아서, 지정한 layer 의 weight 값을 모두 map.txt 파일에 저장해 줍니다.
layer 이름은 --out_node 로 지정해 줄 수 있습니다. 기본값은 softmax_linear/softmax_linear:0 입니다.
8. Weight Map 을 가지고 단일파일의 weight distance 구하기
자세한 설명은 생략합니다. 설명하기가 복잡하네요.
단일 파일을 넣었을때, map 을 export 했던 Layer 의 weight 값이 distance 가 얼마나 차이가 나냐를 구하는 것입니다. -_-;
설명을 잘 못하겠네요.
아무튼 사용방법은 다음과 같습니다
python ./runner.py --mode=map-inference --pb=/tmp/MyClassifier/optimized.pb --map=/tmp/map.txt --image=/DataSet/mypic.jpg
이외에도 내부적으로 사용하는 하이퍼 파라메터들이 있는데, 옵션으로 빼도 좋을 것 같습니다.
새로운 graph(network)를 테스트 하려면, nn_default.py 를 복사해서 자신에게 맞게 수정해서 사용하시면 됩니다.
당연히 --network= 파라미터의 값으로 넣어주어야 하고요.
파일: CNN.zip
Git 로 올려두면, 관리하기가 귀찮고 배포용도 아니므로 그냥 파일첨부 합니다 :)
'딥러닝(DeepLearning)' 카테고리의 다른 글
RedHat 에 Tensorflow GPU 모드로 설치하기 (3) | 2017.10.25 |
---|---|
CNN 을 이용하여, 얼굴을 분류해보자 (31) | 2017.06.30 |
Perceptual Losses for Real-Time Style Transfer (0) | 2017.06.09 |
[CentOS 7] TensforFlow 설치 (0) | 2017.06.09 |
TensorFlow 를 Windows 에서 빌드하기 (0) | 2017.02.14 |
RECENT COMMENT