至此一周伊始,用了周一來學了tensorflow中的slim部分,主要學習了用自己的數據集進行fine-tuning及其實際的應用。

首先,祭出原始代碼的鏈接地址:

tensorflow/models?

github.com
圖標

slim模塊是一個做分類的模塊,那麼下面就通過今天的學習簡單的介紹一下該模塊的使用。

  1. 首先當然是從github上將代碼push下來,於此同時,可wget下載它其中的一個最小的flowers數據集,查看它的文件結構。

wget http://download.tensorflow.org/example_images/flower_photos.tgz

從解壓來看,其文件結構為一個種類一個文件夾,如下圖所示:

在準備自己數據的時候也可以根據上述文件結構進行分類,這樣就能利用其給出的框架快速訓練了。

2. 首先,我們根據說明進行數據集的下載,解壓及其轉換成tfRecord格式,執行:

DATA_DIR=/tmp/data/flowers # 數據集存放的地址
python download_and_convert_data.py
--dataset_name=flowers # 下載的數據集的名字(四選一)
--dataset_dir="${DATA_DIR}"

此處建議寫成bash腳本,這樣方便多次運行。

通過上面一步,我們就將數據集轉換為了tfRecord格式,具體為:

flowers_train-00000-of-00005.tfrecord
...
flowers_train-00004-of-00005.tfrecord
flowers_validation-00000-of-00005.tfrecord
...
flowers_validation-00004-of-00005.tfrecord
labels.txt

3. 在上面一步中,由於我們使用自己的數據集,因此只需要進行格式的轉換即可,並且在轉換過程中,不希望出現flowers的前綴,因此,修改部分代碼:

--- a/research/slim/datasets/flowers.py
+++ b/research/slim/datasets/flowers.py
-_FILE_PATTERN = flowers_%s_*.tfrecord
+_FILE_PATTERN = %s-*.tfrecord

--- a/research/slim/datasets/download_and_convert_flowers.py
+++ b/research/slim/datasets/download_and_convert_flowers.py

- flower_root = os.path.join(dataset_dir, flower_photos)
+ file_root = os.path.join(dataset_dir)
directories = []
class_names = []
- for filename in os.listdir(flower_root):
- path = os.path.join(flower_root, filename)
+ for filename in os.listdir(file_root):
+ path = os.path.join(file_root, filename)

def _get_dataset_filename(dataset_dir, split_name, shard_id):
- output_filename = flowers_%s_%05d-of-%05d.tfrecord % (
+ output_filename = %s-%05d-of-%05d.tfrecord % (

主要就是去掉了一些跟flowers有關的東西,並且將DATA_DIR直接設置為分類目錄一級,有利於代碼的遷移,至此,我們可以使用自己的數據進行tfRecord的生成。

4. 接下來就是要根據tfRecord進行網路的fine-tuning了,原文給出的方案是:

DATASET_DIR=/tmp/flowers # tfRecord所在目錄
TRAIN_DIR=/tmp/flowers-models/inception_v3 # 需要存儲的fine-tuning model
CHECKPOINT_PATH=/tmp/my_checkpoints/inception_v3.ckpt # 下載的模型基礎
python train_image_classifier.py
--train_dir=${TRAIN_DIR}
--dataset_dir=${DATASET_DIR}
--dataset_name=flowers # 這個需要特別注意,稍後會講
--dataset_split_name=train
--model_name=inception_v3
--checkpoint_path=${CHECKPOINT_PATH}
--checkpoint_exclude_scopes=InceptionV3/Logits,InceptionV3/AuxLogits
--trainable_scopes=InceptionV3/Logits,InceptionV3/AuxLogits

上述有一個要注意的地方就是dataset_name=flowers,之前已經說了為了該代碼的泛化,我們已經將flowers的標誌給去掉了,但是此處需要用flowers的標誌說明他的num_classes類別,以此訓練5個分類類別的網路,但是由於我們的tfRecord已經沒有了flowers的標識,如果採用默認方式會尋找不到相應的tfRecord,因此,修改代碼如下:

--- a/research/slim/datasets/flowers.py
+++ b/research/slim/datasets/flowers.py
-_FILE_PATTERN = flowers_%s_*.tfrecord
+_FILE_PATTERN = %s-*.tfrecord

這樣,就不會出問題了,曬一波我自己的fine-tuning代碼:

python train_image_classifier.py
--train_dir="/home/autolab/dataset/Yongchao/train_logs"
--dataset_dir="/home/autolab/dataset/Yongchao/flower_tfrecord"
--dataset_split_name=train
--dataset_name=flowers
--model_name=inception_v3
--checkpoint_path="/home/autolab/dataset/Yongchao/slimModels/inception_v3.ckpt"
--checkpoint_exclude_scopes=InceptionV3/Logits,InceptionV3/AuxLogits
--trainable_scopes=InceptionV3/Logits,InceptionV3/AuxLogits
--max_number_of_steps=5000

checkpoint_exclude_scopes 表示需要重新訓練的層,具體如何選擇下次再說唄。由此fine-tuning過程結束了,存儲在TRAIN_DIR下面的東西應該為:

checkpoint
graph.pbtxt
model.ckpt-0.data-00000-of-00001
model.ckpt-0.index
model.ckpt-0.meta
model.ckpt-5000.data-00000-of-00001
model.ckpt-5000.index
model.ckpt-5000.meta

這就是你自己的新模型啊!棒吧!

5. 我們需要對自己的模型進行評測,同樣先曬出官方給的評測例子:

CHECKPOINT_FILE = ${CHECKPOINT_DIR}/inception_v3.ckpt # Example
$ python eval_image_classifier.py
--alsologtostderr
--checkpoint_path=${CHECKPOINT_FILE} # 感覺這裡用的是原始模型
--dataset_dir=${DATASET_DIR}
--dataset_name=imagenet # 在我們這裡需要改為flowers
--dataset_split_name=validation
--model_name=inception_v3

這裡主要為checkpoint_path的設定,如果按照我們第五步的走法,這個地方應該是我們訓練保存模型的文件夾位置。下面給我的bash文件:

python eval_image_classifier.py
--alsologtostderr
--dataset_name=flowers
--checkpoint_path="/home/autolab/dataset/Yongchao/train_logs" # fine-tuning位置
--dataset_dir="/home/autolab/dataset/Yongchao/flower_tfrecord"
--dataset_split_name=validation
--model_name=inception_v3

在祭出咱的運行結果,上面的各種信息忽略,最終顯示:

INFO:tensorflow:Evaluation [1/4]
INFO:tensorflow:Evaluation [2/4]
INFO:tensorflow:Evaluation [3/4]
INFO:tensorflow:Evaluation [4/4]
2018-04-23 22:25:00.880033: I tensorflow/core/kernels/logging_ops.cc:79] eval/Accuracy[0.9225]
2018-04-23 22:25:00.880633: I tensorflow/core/kernels/logging_ops.cc:79] eval/Recall_5[1]

6. 到了這一步,咱的模型建立和檢驗都搞好了,那麼我們是不是得實際用一用呢,之前的模型數據來源都是tfRecord,但是在實際使用中,我們得到的是一張圖片數據,如果先轉為tfRecord是不是小夥伴們感覺有點麻煩啊,那麼能不能讓圖片直接進行做分類呢,答案是必須可以的,先貼一段關鍵的代碼:

with tf.Session() as sess:
image = open(FLAGS.test_path, rb).read()
image = tf.image.decode_jpeg(image, channels=3)
processed_image = image_preprocessing_fn(image, test_image_size, test_image_size)
processed_images = tf.expand_dims(processed_image, 0)
logits, _ = network_fn(processed_images)
predictions = tf.argmax(logits, 1)
saver = tf.train.Saver()
saver.restore(sess, checkpoint_path)
np_image, network_input, predictions = sess.run([image, processed_image, predictions])
print({} {}.format(FLAGS.test_path, predictions[0]))

到時候代碼全部整理好之後會放到github上的,這裡貼上我參考的文章,大家也可以直接從那邊進行copy代碼:

使用TensorFlow-Slim進行圖像分類 - CSDN博客?

blog.csdn.net

然後附上我運行上述代碼時的bash腳本:

python test_single_image_classifier.py
--checkpoint_path="/home/autolab/dataset/Yongchao/train_logs" # 我們自己訓練的網路
--test_path="/home/autolab/dataset/Yongchao/flower_photos/dandelion/9965757055_ff01b5ee6f_n.jpg" # 需要識別的照片
--model_name=inception_v3

至此,該代碼將能被順利調用去識別一張或者大家也可以寫個循環去調用識別多張照片。

就這樣,周一結束了,很晚了,得回去看《三體》了,晚安,各位!


推薦閱讀:
查看原文 >>
相关文章