1. 程式人生 > >一個月暴力入門tensorflow

一個月暴力入門tensorflow

目錄

為什麼是tensorflow:

現在玩機器學習的人大概沒有不知道tensorflow大名的吧,但是與caffe,keras相比,這位“仁兄”確實不怎麼友好。即是這樣,在眾多開源的深度學習框架當中,tensorflow也是一枝獨秀。Google的大名和號召力當然是其中一方面原因,但是,tensorflow也具有眾多的優點。比如,網路結構程式碼十分簡潔,分散式深度學習演算法的執行效率等等。作為一個“菜雞”來看,最吸引我的地方就是tensorflow對於python介面的支援十分良好。畢竟沒有一個數據挖掘工作是單單定義網路就可以完成的。Python所擁有的Numpy, Scipy, Pandas等組建能大大提升工作的效率。

出來以上的優點以外,tensorflow對於網路結構的視覺化和訓練過程的視覺化也有非常優秀的地方,下面是兩個例子,第一個是tensorflow的tensorboard工具,第二個是tensorflow的playground。

這是訓練過程視覺化,使用的工具是tensorboard

這是網路結構視覺化,使用的工具是tensorboard

這裡寫圖片描述

說說目的:

寫這一系列博文的目的當然不是為了將深度學習,畢竟這是一個太寬泛,我的知識水平難以完全駕馭的領域。我只是提供一個途徑,一種入門的方式。在最初接觸一個領域的知識的時候如果單純看論文會非常枯燥,而且顧前不顧後,狗熊掰棒子。但是如果能從一開始就動手操作,再看論文,做理論推導,整個過程會像揭祕一樣有趣。我的目的就是把學習tensorflow這個“迷”給大家呈現出來。怎麼去理解,分析,就看個人的功夫了。

這一系列的文章會以一種:程式碼段->程式碼解釋->執行結果->除錯心得的形式展現我一個月以來的學習成果。也算是一種筆記。但是,鮮有涉及原理的部分。或者以後的文章會講到原理。但是作為一篇技術入門文章,我力圖使文章儘量簡潔,操作性強,而不是全面。

其中的程式碼大部分都是我從《Tensorflow實戰Google深度學習框架》,《Tensorflow實戰》還有Tensorflow的自帶例子裡面修改過來的。每一段都在自己的計算機上(ubuntu14.04+tensorflow 0.8.0)上實驗過。如果複製程式碼而不能執行多半是版本的問題,或者是有些路徑的問題。希望大家多加諒解。

文章結構

文章將會涉及以下內容:

  1. mnist手寫數字識別
  2. 從mnist例子看tensorflow基礎知識
  3. 來寫個Lenet5
  4. 經典卷積神經網路之AlexNet
  5. 經典卷積神經網路之VGG
  6. 嚇死人的Inception Net以及遷移學習
  7. Resnet和沒學會的tf.contrib.slim模組
  8. Word2Vec探祕
  9. 迴圈神經網路到底是什麼?
  10. 深度強化學習初探

mnist手寫數字識別

為了讓第一篇文章不要這麼水過去,就在這一篇文章當中介紹這個系列的第一個內容,mnist手寫數字識別。這幾乎是每一個學習神經網路的人遇到的第一個例子了。我不想介紹原理,直接從輸入輸出和網路結果來介紹吧:

  • 輸入:
from tensorflow.examples.tutorials.mnist import input_data 
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

這兩行程式碼是利用tensorflow裡面的python程式碼自動下載mnist資料集。其中,one_hot = True 是將圖片的標籤,也就是0-9這九個數字向量化,比如:4 就變成:
[0,0,0,0,1,0,0,0,0,0]。這樣才能可網路的輸出,也就是一個長度為10的向量匹配。

現在我們觀察一下資料集:
這裡寫圖片描述

程式碼中主要用到的是mnist.train, mnist.validation, mnist.test部分,分別用於訓練,訓練時驗證和最後檢驗模型。mnist.train又分為images和labels部分(其他當然也一樣)。圖片部分是將一幅28×28的圖片拉伸成784長,labels部分就是向量化的標籤。

展示一張圖片:

import numpy as np
import matplotlib.pyplot as plt

image = np.reshape(mnist.train.images[1],[28,28])
plt.imshow(image)
plt.show()
  • 定義網路結構:
import tensorflow as tf

#定義輸入輸出節點
INPUT_NODE = 784
OUTPUT_NODE = 10

#中間層節點
LAYER1_NODE = 500

#定義變數生成函式
def get_weight_variable(shape,regularizer):

    #tf.get_variable生成tf變數
    weights = tf.get_variable("weights",shape,
                              initializer=tf.truncated_normal_initializer(stddev=0.1))

#如果正則化,將正則化因子加入損失函式
    if regularizer !=None:
        tf.add_to_collection("losses",regularizer(weights))

    return weights

#定義網路結構
def inference(input_tensor,regularizer):

    #定義變數作用域
    with tf.variable_scope("layer1"):

        #定義網路權重
        weights = get_weight_variable([INPUT_NODE,LAYER1_NODE],regularizer)

        #定義偏置值
        biases = tf.get_variable("biases",[LAYER1_NODE],initializer=tf.constant_initializer(0.0))

        #第一層輸出
        layer1 = tf.nn.relu(tf.matmul(input_tensor,weights)+biases)
      #第二層類似  
    with tf.variable_scope("layer2"):
        weights = get_weight_variable([LAYER1_NODE,OUTPUT_NODE],regularizer)
        biases = tf.get_variable("biases",[OUTPUT_NODE],initializer=tf.constant_initializer(0.0))
        layer2 = tf.matmul(layer1,weights)+biases

    return layer2
  • 訓練網路mnist_train.py
import tensorflow as tf
import mnist_inference

from tensorflow.examples.tutorials.mnist import input_data

#set network parameters
BATCH_SIZE = 100

LEARNING_RATE_BASE = 0.8
LEARNING_RATE_DECAY = 0.99
REGULATION_RATE = 0.0001
TRAINING_STEPS = 30000
MOVING_AVERAGE_DECAY = 0.99



def train(mnist):
    #定義輸入輸出的容器
    x = tf.placeholder(tf.float32,[None,mnist_inference.INPUT_NODE],name='x-input')
    y_ = tf.placeholder(tf.float32,[None,mnist_inference.OUTPUT_NODE],name='y-input')
    #定義正則化方法
    regularizer = tf.contrib.layers.l2_regularizer(REGULATION_RATE)
    #定義輸出的運算
    y = mnist_inference.inference(x,regularizer)


    #定義滑動平均模型
    global_step = tf.Variable(0.0,trainable=False)
#訓練輪數不可訓練
    variable_averages = tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY,global_step)
    #滑動平均
    variable_averages_op = variable_averages.apply( tf.trainable_variables())#滑動平均運算operator

    #定義交叉熵
    cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(y,tf.argmax(y_,1))
    cross_entropy_mean = tf.reduce_mean(cross_entropy)
    loss = tf.add_n(tf.get_collection('losses')) + cross_entropy_mean #損失函式是交叉熵和正則化之和

    #定義學習率和訓練(梯度下降法)

    learning_rate = tf.train.exponential_decay(LEARNING_RATE_BASE,global_step, mnist.train.num_examples / BATCH_SIZE, LEARNING_RATE_DECAY)

    train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss,global_step = global_step)

     #定義訓練operator,同步梯度下降和滑動平均
     with tf.control_dependencies([train_step,variable_averages_op]):
            train_op = tf.no_op(name='train')

        #定義儲存函式
    saver = tf.train.Saver()

        #開始一個會話
    with tf.Session() as sess:
        #初始化所有變數
            tf.initialize_all_variables().run()

            for i in range(TRAINING_STEPS):
                #獲取每一個batch的資料
                xs, ys = mnist.train.next_batch(BATCH_SIZE)
                #訓練,得到損失和步驟,輸入為xs, ys
                _,loss_value,step = sess.run([train_op,loss,global_step],feed_dict={x:xs,y_:ys})
            if i % 1000 ==0:

                    print("After %d training step(s), loss on training batch is %g" % (step,loss_value))
                #儲存
                saver.save(sess,"model/model_mnist.ckpt",global_step)


def main(argv=None):
    #read data set
    mnist = input_data.read_data_sets("tmp/data",one_hot=True)

    train(mnist)



if __name__ == '__main__':
    tf.app.run()

訓練結果:
這裡寫圖片描述

-驗證:

import time
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

import mnist_inference
import mnist_train

#每10秒驗證一次
EVAL_INTERVAL_SECS = 10

def evalute(mnist):
    with tf.Graph().as_default() as g:
        #同樣的輸入輸出
        x = tf.placeholder(tf.float32,[None,mnist_inference.INPUT_NODE],name='x-input')
        y_ = tf.placeholder(tf.float32,[None,mnist_inference.OUTPUT_NODE],name='y-input')

        #驗證集
        validate_feed = {x:mnist.validation.images,y_:mnist.validation.labels}

        y = mnist_inference.inference(x,None)


       correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
        accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))

        #通過重新命名的方式載入模型,這樣就可以載入mnist_inferece.py中的向前傳播模型
        variable_averages = tf.train.ExponentialMovingAverage(mnist_train.MOVING_AVERAGE_DECAY)
        variable_to_restore = variable_averages.variables_to_restore()
        saver = tf.train.Saver(variable_to_restore)


        with tf.Session() as sess:
            #讀取模型,計算儲存了幾個模型
            ckpt = tf.train.get_checkpoint_state(
"model/")
            length = len(ckpt.all_model_checkpoint_paths)

            for i in range(length):
                #讀取模型
                saver.restore(sess,ckpt.all_model_checkpoint_paths[i])
                #讀取時哪一個步驟的
                global_step = ckpt.all_model_checkpoint_paths[i].split('/')[-1].split('/')[-1]
                accuracy_score = sess.run(accuracy,feed_dict=validate_feed)
                print ("After %s training step(s),validation accuracy=%g" % (global_step,accuracy_score))
                time.sleep(EVAL_INTERVAL_SECS)

def main(argv=None):
    mnist = input_data.readd sets("tmp/data",one_hot=True)
    evalute(mnist)

if __name__ == '__main__':
    tf.app.run()  

結果:
這裡寫圖片描述