TF Boys (TensorFlow Boys ) 養成記(六): CIFAR10 Train 和 TensorBoard 簡介

聖誕節玩的有點嗨,差點忘記更新。祝你們昨天聖誕節快樂,再過幾天元旦節快樂。git

來繼續學習,在/home/your_name/TensorFlow/cifar10/ 下新建文件夾cifar10_train,用來保存訓練時的日誌logs,繼續在/home/your_name/TensorFlow/cifar10/ cifar10.py中輸入以下代碼:github

def train():
    # global_step
    global_step = tf.Variable(0, name = 'global_step', trainable=False)
    # cifar10 數據文件夾
    data_dir = '/home/your_name/TensorFlow/cifar10/data/cifar-10-batches-bin/'
    # 訓練時的日誌logs文件,沒有這個目錄要先建一個
    train_dir = '/home/your_name/TensorFlow/cifar10/cifar10_train/'
    # 加載 images,labels
    images, labels = my_cifar10_input.inputs(data_dir, BATCH_SIZE)

    # 求 loss
    loss = losses(inference(images), labels)
    # 設置優化算法,這裏用 SGD 隨機梯度降低法,恆定學習率
    optimizer = tf.train.GradientDescentOptimizer(LEARNING_RATE)
    # global_step 用來設置初始化
    train_op = optimizer.minimize(loss, global_step = global_step)
    # 保存操做
    saver = tf.train.Saver(tf.all_variables())
    # 彙總操做
    summary_op = tf.merge_all_summaries()
    # 初始化方式是初始化全部變量
    init = tf.initialize_all_variables()

    os.environ['CUDA_VISIBLE_DEVICES'] = str(0)
    config = tf.ConfigProto()
    # 佔用 GPU 的 20% 資源
    config.gpu_options.per_process_gpu_memory_fraction = 0.2
    # 設置會話模式,用 InteractiveSession 可交互的會話,逼格高
    sess = tf.InteractiveSession(config=config)
    # 運行初始化
    sess.run(init)

    # 設置多線程協調器
    coord = tf.train.Coordinator()       
    # 開始 Queue Runners (隊列運行器)
    threads = tf.train.start_queue_runners(sess = sess, coord = coord)
    # 把彙總寫進 train_dir,注意此處尚未運行
    summary_writer = tf.train.SummaryWriter(train_dir, sess.graph)

    # 開始訓練過程
    try:        
        for step in xrange(MAX_STEP):
            if coord.should_stop():
                break
            start_time = time.time()
            # 在會話中運行 loss
            _, loss_value = sess.run([train_op, loss])
            duration = time.time() - start_time
            # 確認收斂
            assert not np.isnan(loss_value), 'Model diverged with loss = NaN'                
            if step % 30 == 0:
                # 本小節代碼設置一些花哨的打印格式,能夠不用管
                num_examples_per_step = BATCH_SIZE
                examples_per_sec = num_examples_per_step / duration
                sec_per_batch = float(duration)                    
                format_str = ('%s: step %d, loss = %.2f (%.1f examples/sec; %.3f '
                              'sec/batch)')
                print (format_str % (datetime.now(), step, loss_value, 
                                     examples_per_sec, sec_per_batch))
            
            if step % 100 == 0:
                # 運行彙總操做, 寫入彙總
                summary_str = sess.run(summary_op)
                summary_writer.add_summary(summary_str, step)                

            if step % 1000 == 0 or (step + 1) == MAX_STEP:
                # 保存當前的模型和權重到 train_dir,global_step 爲當前的迭代次數
                checkpoint_path = os.path.join(train_dir, 'model.ckpt')
                saver.save(sess, checkpoint_path, global_step=step)

    except Exception, e:
        coord.request_stop(e)
    finally:
        coord.request_stop()
        coord.join(threads)
        
    sess.close()
        

def evaluate():

    data_dir = '/home/your_name/TensorFlow/cifar10/data/cifar-10-batches-bin/'
    train_dir = '/home/your_name/TensorFlow/cifar10/cifar10_train/'
    images, labels = my_cifar10_input.inputs(data_dir, BATCH_SIZE, train = False)

    logits = inference(images) 
    saver = tf.train.Saver(tf.all_variables())        
    
    os.environ['CUDA_VISIBLE_DEVICES'] = str(0)
    config = tf.ConfigProto()
    config.gpu_options.per_process_gpu_memory_fraction = 0.2
    sess = tf.InteractiveSession(config=config)
    coord = tf.train.Coordinator()       
    threads = tf.train.start_queue_runners(sess = sess, coord = coord)
    
    # 加載模型參數
    print("Reading checkpoints...")
    ckpt = tf.train.get_checkpoint_state(train_dir)
    if ckpt and ckpt.model_checkpoint_path:
        ckpt_name = os.path.basename(ckpt.model_checkpoint_path)
        global_step = ckpt.model_checkpoint_path.split('/')[-1].split('-')[-1]         
        saver.restore(sess, os.path.join(train_dir, ckpt_name))
        print('Loading success, global_step is %s' % global_step)
        
        
    try:
        # 對比分類結果,至於爲何用這個函數,後面詳談       
        top_k_op = tf.nn.in_top_k(logits, labels, 1)
        true_count = 0
        step = 0
        while step < 157:
            if coord.should_stop():
                break
            predictions = sess.run(top_k_op)
            true_count += np.sum(predictions)
            step += 1
            
        precision = true_count / 10000
        print('%s: precision @ 1 = %.3f' % (datetime.now(), precision))
    except tf.errors.OutOfRangeError:
        coord.request_stop()
    finally:
        coord.request_stop()
        coord.join(threads)
        
    sess.close()
        
if __name__ == '__main__':
    
    if TRAIN:
        train ()
    else:
        evaluate()

如今說明一下 in_top_k 這個函數的做用,官方文檔介紹中: tf.nn.in_top_k(predictions, targets, k, name=None)這個函數返回一個 batch_size 大小的布爾矩陣 array,predictions 是一個 batch_size*classes 大小的矩陣,targets 是一個 batch_size 大小的類別 index 矩陣,這個函數的做用是,若是 targets[i] 是 predictions[i][:] 的前 k 個最大值,則返回的 array[i] = True, 不然,返回的 array[i] = False。能夠看到,在上述評估程序 evaluate 中,這個函數沒有用 softmax 的結果進行計算,而是用 inference 最後的輸出結果(一個全鏈接層)進行計算。算法

寫完以後,點擊運行,能夠看到,訓練的 loss 值,從剛開始的 2.31 左右,降低到最終的 0.00 左右,在訓練的過程當中,/home/your_name/TensorFlow/cifar10/cifar10_train/ 文件夾下會出現12個文件,其中有 5 個 model.ckpt-0000 文件,這個是訓練過程當中保存的模型,後面的數字表示迭代次數,5 個 model.ckpt-0000.meta 文件,這個是訓練過程當中保存的元數據(暫時不清楚功能),TensorFlow 默認只保存近期的幾個模型和幾個元數據,刪除前面沒用的模型和元數據。還有個 checkpoint 的文本文檔,和一個 out.tfevents 形式的文件,是summary 的日誌文件。若是不想用 tensorboard 看網絡結構和訓練過程當中的權重分佈,損失狀況等等,在程序中能夠不寫 summary 語句。瀏覽器

訓練完成以後,咱們用 tensorboard 進行可視化(事實上在訓練的過程當中,隨時能夠可視化)。在任意位置打開命令行終端,輸入:網絡

tensorboard --logdir=/home/your_name/TensorFlow/cifar10/cifar10_train/

會出現以下指示:多線程

根據指示,打開瀏覽器,輸入 http://127.0.1.1:6006(有的瀏覽器可能不支持,建議多換幾個瀏覽器試試)會看到可視化的界面,有六個選項卡:函數

EVENTS 對話框裏面有兩個圖,一個是訓練過程當中的 loss 圖,一個是隊列 queue 的圖;因爲沒有 image_summary() 和 audio_summary() 語句,因此,IMAGES 和 AUDIO 選項卡都沒有內容;GRAPHS 選項卡包含了整個模型的流程圖,以下圖,能夠展開和移動選定的 namespace;DISTRBUTIONS 和 HISTOGRAMS 包含了訓練時的各類彙總的分佈和柱狀圖。學習

 

 

訓練完以後,設置 TRAIN = False,進行測試,獲得以下結果:測試

 

 

 能夠看到,測試的精度只有 76%,測試結果不夠高的緣由多是,測試的時候沒有通過 softmax 層,直接用全鏈接層的權重(存疑?),另外官方的代碼也給出了官方的運行結果,以下:優化

能夠看到,通過 10 萬次迭代,官方給出的正確率達到 83%,咱們只進行了 5 萬次,達到 76% 的正確率,相對來講,還算能夠,效果沒有官方好的緣由多是:

1. 官方使用了非固定的學習率;

2. 官方迭代比本代碼迭代次數多一倍;

 

 

參考文獻:

1. https://github.com/tensorflow/models/tree/master/tutorials/image/cifar10

相關文章
相關標籤/搜索