테스트에 필요한 파일들은 ILSVRC2012_img_train_t3.tar와 ILSVRC2012_img_val.tar, 그리고 bounding_box를 위한 xml 파일들을 담은 Annotation.tar.gz 입니다.
[user1@ac922 raw-data]$ pwd
/home/user1/ilsvrc2012/raw-data
[user1@ac922 raw-data]$ ls -l ../../files/IL*.tar
-rw-rw-r--. 1 user1 user1 762460160 Jul 4 2012 ../../files/ILSVRC2012_img_train_t3.tar
-rw-rw-r--. 1 user1 user1 6744924160 Jun 15 2012 ../../files/ILSVRC2012_img_val.tar
[user1@ac922 raw-data]$ wget http://image-net.org/Annotation/Annotation.tar.gz
다음과 같이 ILSVRC2012_img_train_t3.tar을 train directory에 풀어놓습니다. n02085620 등의 이름으로 된 sub-directory별로 사진들이 들어 있습니다.
[user1@ac922 raw-data]$ cd train
[user1@ac922 train]$ tar -xf ../../../files/ILSVRC2012_img_train_t3.tar
[user1@ac922 train]$ for i in `ls n*.tar | cut -d. -f1`
> do
> mkdir ${i}
> tar -xf ${i}.tar -C ${i}
> rm ${i}.tar
> done
원래의 ILSVRC2012_img_train.tar라면 총 1000개의 directory가 생기겠으나, 이 ILSVRC2012_img_train_t3.tar는 120개입니다.
[user1@ac922 train]$ ls -1 | wc -l
120
[user1@ac922 train]$ ls | head
n02085620
n02085782
n02085936
n02086079
n02086240
n02086646
n02086910
n02087046
n02087394
n02088094
[user1@ac922 train]$ du -sm .
753 .
6GB 정도되는 ILSVRC2012_img_val.tar는 일단 validation directory에 그냥 풀어넣습니다. 이건 총 50000장의 사진입니다.
[user1@ac922 validation]$ tar -xf ../../../files/ILSVRC2012_img_val.tar
[user1@ac922 validation]$ ls | head
ILSVRC2012_val_00000001.JPEG
ILSVRC2012_val_00000002.JPEG
ILSVRC2012_val_00000003.JPEG
ILSVRC2012_val_00000004.JPEG
ILSVRC2012_val_00000005.JPEG
ILSVRC2012_val_00000006.JPEG
ILSVRC2012_val_00000007.JPEG
ILSVRC2012_val_00000008.JPEG
ILSVRC2012_val_00000009.JPEG
ILSVRC2012_val_00000010.JPEG
[user1@ac922 validation]$ ls | wc -l
50000
[user1@ac922 validation]$ du -sm .
6496 .
이제 bounding_boxes를 위해 Annotation.tar.gz을 풀어놓습니다. 이 속에도 directory별로 tar.gz 파일들이 들어있습니다.
[user1@ac922 validation]$ cd ..
[user1@ac922 raw-data]$ tar -zxf ./Annotation.tar.gz
[user1@ac922 raw-data]$ for i in `ls n*.tar.gz`
> do
> tar -zxf ${i}
> rm ${i}
> done
이제 이 Annotation이라는 이름의 directory를 bounding_boxes라는 이름으로 바꿉니다.
[user1@ac922 raw-data]$ mv Annotation bounding_boxes
[user1@ac922 bounding_boxes]$ ls | head
n00007846
n00015388
n00017222
n00021265
n00439826
n00440039
n00440941
n00441824
n00443692
n00445351
이 속에는 총 3627개의 directory가 있으며, 그 각각마다 xml 파일들이 들어있습니다.
[user1@ac922 bounding_boxes]$ ls | wc -l
3627
[user1@ac922 bounding_boxes]$ ls n00007846 | head
n00007846_103856.xml
n00007846_104163.xml
n00007846_104414.xml
n00007846_105689.xml
n00007846_106069.xml
n00007846_107024.xml
n00007846_109518.xml
n00007846_109796.xml
n00007846_110945.xml
n00007846_111865.xml
이 xml 파일들과 raw image들을 TFRecord 포맷으로 변환하겠습니다. 거기에는 아래 github에서 제공되는 script tool과 label 들을 사용합니다.
[user1@ac922 ~]$ git clone https://github.com/tensorflow/models.git
[user1@ac922 ~]$ cd ~/models/research/inception/inception/data
이 속에 들어있는 imagenet_metadata.txt 등의 각종 label 파일들은 모두 ILSVRC2012_img_train_t3.tar가 아니라 ILSVRC2012_img_train.tar를 기준으로 만들어진 것입니다. 이것을 그대로 사용하면 TFRecord로 변환할 때 error가 생길 것이므로, 이 중에서 ILSVRC2012_img_train_t3.tar에 들어있는 label들만 골라내어 새로 만드는 작업을 해야 합니다.
먼저 backup을 떠놓습니다.
[user1@ac922 data]$ cp imagenet_metadata.txt imagenet_metadata.txt.org
[user1@ac922 data]$ head imagenet_metadata.txt
n00004475 organism, being
n00005787 benthos
n00006024 heterotroph
n00006484 cell
n00007846 person, individual, someone, somebody, mortal, soul
n00015388 animal, animate being, beast, brute, creature, fauna
n00017222 plant, flora, plant life
n00021265 food, nutrient
n00021939 artifact, artefact
n00120010 hop
[user1@ac922 data]$ wc -l imagenet_metadata.txt
21842 imagenet_metadata.txt
다음과 같이 실제로 ~/ilsvrc2012/raw-data/train directory 속에 들어있는 이름들만 골라서 새로 imagenet_metadata.txt.new를 만든 뒤, 그것을 imagenet_metadata.txt에 overwrite합니다.
[user1@ac922 data]$ for i in `ls ~/ilsvrc2012/raw-data/train`
> do
> grep $i imagenet_metadata.txt >> imagenet_metadata.txt.new
> done
총 120개만 골라진 것을 볼 수 있고, 또 거기 들어간 이름들은 모두 멍멍이 종류인 것을 볼 수 있습니다.
[user1@ac922 data]$ wc -l imagenet_metadata.txt.new
120 imagenet_metadata.txt.new
[user1@ac922 data]$ head imagenet_metadata.txt.new
n02085620 Chihuahua
n02085782 Japanese spaniel
n02085936 Maltese dog, Maltese terrier, Maltese
n02086079 Pekinese, Pekingese, Peke
n02086240 Shih-Tzu
n02086646 Blenheim spaniel
n02086910 papillon
n02087046 toy terrier
n02087394 Rhodesian ridgeback
n02088094 Afghan hound, Afghan
imagenet_lsvrc_2015_synsets.txt에 대해서도 동일한 작업을 해줍니다.
[user1@ac922 data]$ wc -l imagenet_lsvrc_2015_synsets.txt
1000 imagenet_lsvrc_2015_synsets.txt.org
[user1@ac922 data]$ cp imagenet_lsvrc_2015_synsets.txt imagenet_lsvrc_2015_synsets.txt.org
[user1@ac922 data]$ head imagenet_lsvrc_2015_synsets.txt
n01440764
n01443537
n01484850
n01491361
n01494475
n01496331
n01498041
n01514668
n01514859
n01518878
[user1@ac922 data]$ for i in `ls ~/ilsvrc2012/raw-data/train`
> do
> grep $i imagenet_lsvrc_2015_synsets.txt >> imagenet_lsvrc_2015_synsets.txt.new
> done
[user1@ac922 data]$ wc -l imagenet_lsvrc_2015_synsets.txt.new
120 imagenet_lsvrc_2015_synsets.txt.new
[user1@ac922 data]$ cp imagenet_lsvrc_2015_synsets.txt.new imagenet_lsvrc_2015_synsets.txt
[user1@ac922 data]$ head imagenet_lsvrc_2015_synsets.txt
n02085620
n02085782
n02085936
n02086079
n02086240
n02086646
n02086910
n02087046
n02087394
n02088094
[user1@ac922 data]$ wc -l imagenet_lsvrc_2015_synsets.txt
120 imagenet_lsvrc_2015_synsets.txt
그리고 validation용 label인 imagenet_2012_validation_synset_labels.txt에 대해서도 비슷한 작업을 해줍니다.
[user1@ac922 data]$ wc -l imagenet_2012_validation_synset_labels.txt
50000 imagenet_2012_validation_synset_labels.txt
[user1@ac922 data]$ cp imagenet_2012_validation_synset_labels.txt imagenet_2012_validation_synset_labels.txt.org
[user1@ac922 data]$ head imagenet_2012_validation_synset_labels.txt
n01751748
n09193705
n02105855
n04263257
n03125729
n01735189
n02346627
n02776631
n03794056
n02328150
[user1@ac922 data]$ for i in `ls ~/ilsvrc2012/raw-data/train`
> do
> grep $i imagenet_2012_validation_synset_labels.txt >> imagenet_2012_validation_synset_labels.txt.new
> done
이 작업을 통해 총 5만장이던 validation용 이미지가 이제 6천장으로 줄어든 것을 보실 수 있습니다.
[user1@ac922 data]$ wc -l imagenet_2012_validation_synset_labels.txt.new
6000 imagenet_2012_validation_synset_labels.txt.new
이제 bounding_boxes에 들어있는 것들도 비슷한 작업을 통해 개수를 줄여줍니다.
[user1@ac922 data]$ for i in `ls ~/ilsvrc2012/raw-data/bounding_boxes`
> do
> grep ${i} imagenet_lsvrc_2015_synsets.txt
> if [[ $? -ne 0 ]]
> then
> rm -rf ~/ilsvrc2012/raw-data/bounding_boxes/${i}
> fi
> done
다음과 같이 120개 directory만 남은 것을 보실 수 있습니다.
[user1@ac922 data]$ ls ~/ilsvrc2012/raw-data/bounding_boxes | wc -l
120
이제 TFRecord 파일들을 담을 directory를 만들어 줍니다.
[user1@ac922 data]$ mkdir ~/ilsvrc2012/tfrecord
원래 github에서 제공되는 download_and_preprocess_imagenet.sh를 수행하면 download 부터 TFRecord로의 변환까지 일괄적으로 수행됩니다만, 여기서는 138GB의 data를 download 받을 수도 없고 또 이런저런 환경이 다르므로, 아래와 같이 그 핵심부분만 따와서 새로 tf_preprocess.sh라는 script를 만들었습니다.
[user1@ac922 data]$ vi tf_preprocess.sh
#!/bin/bash
DATA_DIR="${1%/}"
SCRATCH_DIR="${DATA_DIR}/raw-data/"
WORK_DIR="$HOME/models/research/inception/inception"
TRAIN_DIRECTORY="${SCRATCH_DIR}train/"
VALIDATION_DIRECTORY="${SCRATCH_DIR}validation/"
BOUNDING_BOX_SCRIPT="${WORK_DIR}/data/process_bounding_boxes.py"
BOUNDING_BOX_FILE="${SCRATCH_DIR}/imagenet_2012_bounding_boxes.csv"
BOUNDING_BOX_DIR="${SCRATCH_DIR}bounding_boxes/"
# Preprocess the validation data by moving the images into the appropriate
# sub-directory based on the label (synset) of the image.
echo "Organizing the validation data into sub-directories."
PREPROCESS_VAL_SCRIPT="${WORK_DIR}/data/preprocess_imagenet_validation_data.py"
VAL_LABELS_FILE="${WORK_DIR}/data/imagenet_2012_validation_synset_labels.txt"
"${PREPROCESS_VAL_SCRIPT}" "${VALIDATION_DIRECTORY}" "${VAL_LABELS_FILE}"
# Convert the XML files for bounding box annotations into a single CSV.
echo "Extracting bounding box information from XML."
BOUNDING_BOX_SCRIPT="${WORK_DIR}/data/process_bounding_boxes.py"
BOUNDING_BOX_FILE="${SCRATCH_DIR}/imagenet_2012_bounding_boxes.csv"
BOUNDING_BOX_DIR="${SCRATCH_DIR}bounding_boxes/"
LABELS_FILE="${WORK_DIR}/data/imagenet_lsvrc_2015_synsets.txt"
"${BOUNDING_BOX_SCRIPT}" "${BOUNDING_BOX_DIR}" "${LABELS_FILE}" \
| sort > "${BOUNDING_BOX_FILE}"
echo "Finished downloading and preprocessing the ImageNet data."
# Build the TFRecords version of the ImageNet data.
BUILD_SCRIPT="/usr/bin/python ${WORK_DIR}/data/build_imagenet_data.py"
OUTPUT_DIRECTORY="${DATA_DIR}/tfrecord"
IMAGENET_METADATA_FILE="${WORK_DIR}/data/imagenet_metadata.txt"
python $HOME/models/research/inception/inception/data/build_imagenet_data.py \
--train_directory="${TRAIN_DIRECTORY}" \
--validation_directory="${VALIDATION_DIRECTORY}" \
--output_directory="${OUTPUT_DIRECTORY}" \
--imagenet_metadata_file="${IMAGENET_METADATA_FILE}" \
--labels_file="${LABELS_FILE}" \
--bounding_box_file="${BOUNDING_BOX_FILE}"
이 tf_preprocess.sh는 그 속에서 build_imagenet_data.py를 불러 TFRecord로의 변환을 수행합니다. 이 script는 총 1000개의 shard에 training data를 넣는데, 이 숫자를 120으로 줄이겠습니다. validation shard는 32개로 줄이겠습니다.
[user1@ac922 data]$ vi build_imagenet_data.py
...
#tf.app.flags.DEFINE_integer('train_shards', 1024,
tf.app.flags.DEFINE_integer('train_shards', 120,
'Number of shards in training TFRecord files.')
#tf.app.flags.DEFINE_integer('validation_shards', 128,
tf.app.flags.DEFINE_integer('validation_shards', 32,
'Number of shards in validation TFRecord files.')
...
이제 tf_preprocess.sh script에 실행 permission을 주고 실행하면 TFRecord로의 변환이 시작됩니다.
[user1@ac922 data]$ chmod a+x tf_preprocess.sh
[user1@ac922 data]$ ./tf_preprocess.sh ~/ilsvrc2012
...
2018-04-11 19:22:21.150944 [thread 2]: Wrote 2572 images to 2572 shards.
2018-04-11 19:22:21.151077 [thread 6]: Wrote 172 images to /home/user1/ilsvrc2012/tfrecord/train-00104-of-00120
2018-04-11 19:22:21.151131 [thread 6]: Wrote 2572 images to 2572 shards.
2018-04-11 19:22:21.247600 [thread 7]: Wrote 172 images to /home/user1/ilsvrc2012/tfrecord/train-00119-of-00120
2018-04-11 19:22:21.247631 [thread 7]: Wrote 2573 images to 2573 shards.
2018-04-11 19:22:21.506394: Finished writing all 20580 images in data set.
이렇게 멍멍이 사진 20580장의 변환이 완료되었습니다.
[user1@ac922 data]$ cd ~/ilsvrc2012/tfrecord/
[user1@ac922 tfrecord]$ ls train-* | wc -l
120
[user1@ac922 tfrecord]$ ls validation-* | wc -l
32
[user1@ac922 tfrecord]$ du -sm .
1475 .
이렇게 만들어진 ~/ilsvrc2012/tfrecord 디렉토리 밑의 file들을 다음 명령어로 뭉쳐서 아래 URL에 올려두었습니다.
[user1@ac922 ilsvrc2012]$ tar -zcvf tfrecord.tgz tfrecord
https://drive.google.com/open?id=1rQcxAWeNbByy0Yooj6IbROyVRsdQPn5-
댓글 없음:
댓글 쓰기