深度學習(六):煉數成金的Tensorflow教程學習筆記(含代碼)

由於自己的研究方向主要是文本處理、分類、預測。在學習了深度學習的基本代碼後,最近實踐文本相似度的相關深度模型的過程中,由於對Tensorflow框架的瞭解太少,在看別人寫的代碼的過程中,有些困惑,所以就抽出點時間學了一下Tensorflow框架。這裏主要講解學習煉數成金的Tensorflow視頻教程的學習筆記。

此視頻課程的課程大綱如下:
第一課 Tensorflow簡介,Anaconda安裝,Tensorflow的CPU版本安裝。
第二課 Tensorflow的基礎使用,包括對圖(graphs),會話(session),張量(tensor),變量(Variable)的一些解釋和操作。
第三課 Tensorflow線性迴歸以及分類的簡單使用,softmax介紹。
第四課 交叉熵(cross-entropy),過擬合,dropout以及Tensorflow中各種優化器的介紹。
第五課 使用Tensorboard進行結構可視化,以及網絡運算過程可視化。
第六課 卷積神經網絡CNN的講解,以及用CNN解決MNIST分類問題。
第七課 遞歸神經網絡LSTM的講解,以及LSTM網絡的使用。
第八課 保存和載入模型,使用Google的圖像識別網絡inception-v3進行圖像識別。
第九課 Tensorflow的GPU版本安裝。設計自己的網絡模型,並訓練自己的網絡模型進行圖像識別。
第十課 多任務學習以及驗證碼識別。
第十一課 word2vec講解和使用,cnn解決文本分類問題。
第十二課 語音處理以及使用LSTM構建語音分類模型。

由於我有一定的基礎了,所以我是選擇性的學習的。

第四課:Tensorflow中各種優化介紹(學習率更改、權重w的初始化、優化器Optimizer的選擇、激活函數的選擇、Dropout的使用、代價函數的選擇)

1. 學習率的更改,僞代碼如下:

lr = tf.Variable(0.001, dtype=tf.float32)
# ...
train_step = tf.train.AdamOptimizer(lr).minimize(loss)
# ...
for step in range(100):
    sess.run(tf.assign(lr, 0.001 * (0.95 ** step)))
    for batch in batches:
        # train
    learning_rate = sess.run(lr)
    # 輸出準確率

2. 權重w的初始化

w = tf.Variable(tf.truncated_normal([diminput, dimhidden], stddev=0.1))

3. 優化器Optimizer的選擇

標準梯度下降法:計算所有樣本彙總誤差,根據總誤差來更新權值;缺點:太慢;
隨機梯度下降法:隨機抽取一個樣本來計算誤差,然後更新權值;缺點:對噪聲過於敏感
批量梯度下降法:算是一種折中方案,從總樣本中選取一個批次,計算該批次數據誤差,來更新權值;

Tensorflow中的優化器:

各種優化器的實驗效果比較一:

排名:Adadelta、Adagrade、Rmsprop、NAG、Momentum、SGD

各種優化器的實驗效果比較二:鞍點問題


排名:
Adadelta以很快的速度衝下來;
NAG在最初的迷茫之後快速走下鞍點,速度很快;
Momentum也在迷茫之後走下鞍點,但是沒有NAG;
Rmsprop沒有迷茫,但是下降速度有點慢;
Adagrad 也沒有迷茫,但是速度更慢;
SGD,直接在鞍點下不來了。

總結:

優化器各有優缺點,別的優化器收斂速度會比較快,但是SGD最後的結果一般來說很好。
以下網址有不錯的優化器的總結,可以參考:

https://blog.csdn.net/g11d111/article/details/76639460

4. Dropout的使用

dropout主要是解決過擬合問題

過擬合的解決方法有三種:增加數據集、正則化方法、Dropout

Dropout的實現方式如下:

Layer1_y = tf.nn.softmax(x)
Layer1_drop = tf.nn.dropout(Layer1_y, keep_prob)

5.代價函數的選擇

一般訓練都是以梯度下降來實現的。

代價函數用來計算損失,Tensorflow中主要用三種代價函數:

總的來說:輸出神經元是線性的,用二次代價函數;輸出神經元是S型的函數,如果用的sigmoid激活函數,使用交叉熵代價函數;如果用的softmax激活函數,使用對數似然代價函數。

(1)二次代價函數:

loss = tf.reduce_mean(tf.square(y - y_pred))

二次代價函數在梯度下降時與激活函數的導數有關係,就會導致問題。

(2)交叉熵:解決了二次代價函數的問題

loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y, logits=y_pred))   
# y_pred是用softmax激活函數
loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(labels=y, logits=y_pred))   
# y_pred是用sigmoid激活函數

第五課 使用Tensorboard進行結構可視化。查看網絡結構、查看網絡運行數據、以手寫字分類爲例實現訓練的可視化。

1. 查看網絡結構

# 一般寫神經網絡都會寫
with tf.name_scope("***"):
    W = tf.Variable("***", name="W")  
    b = tf.Variable("***", name="b")  
# ...
writer = tf.summary.FileWriter(FLAGS.data_dir, graph=sess.graph)
# 運行就ok了,然後在cmd中切換到相應保存的磁盤中,輸入:tensorboard --logdir=(writer保存的路徑)
# 會出現一個網址,複製,在瀏覽器中打開

大致效果如下:

2.查看網絡運行數據

# 1.定義一個方法
def variable_summaries(var):
    with tf.name_scope('summaries'):
        mean = tf.reduce_mean(var)
        tf.summary.scalar('mean', mean)     # 平均值
        with tf.name_scope('stddev'):
            stddev = tf.sqrt(tf.reduce_mean(tf.square(var - mean)))
        tf.summary.scalar('stddev', stddev)     # 標準差
        tf.summary.scalar("max", tf.reduce_max(var))    # 最大值
        tf.summary.scalar('min', tf.reduce_min(var))    # 最小值
        tf.summary.histogram('histogram', var)      # 直方圖
#
# 2. 使用方法,如w的數據變化:一般查看loss,w,b,accuracy
# W值的查看
W = tf.Variable("***", name="W")
variable_summaries(W)
# loss值的查看
loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(labels=y, logits=y_pred))
tf.summary.scalar('loss', loss)
# accuracy值的查看
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
tf.summary.scalar('accuracy', accuracy)

# 3. 合併所有的summary
merged = tf.summary.merge_all()

# 4. 在運行的代碼加上merged
summary, _ = sess.run([merged, train_step], feed_dict={x:batch_x, y:batch_y})

# 5. 把summary添加至writer中
writer.add_summary(summary, step)

# 注意:一般我們訓練時使用的是如下格式:
for step in range(100):
    for batch in batches:
         summary, _ = sess.run([merged, train_step], feed_dict={x:batch_x, y:batch_y})
    writer.add_summary(summary, step)

# 這一格式會使得樣本點比較少,畫出的圖形不夠平滑,想要使得樣本點多,可以採用如下形式:
for step in range(100):
    batch_x, batch_y = mnist.train_next_batch(100)
    summary, _ = sess.run([merged, train_step], feed_dict={x: batch_x, y: batch_y})
    writer.add_summary(summary, step)

# 6.最後在網頁上瀏覽就有圖像顯示
# 如果loss的生成圖上下跳動很厲害的話,說明learning_rate設置大了。

大致效果如下:

3. 以手寫字分類爲例實現訓練的可視化。

具體實現我沒看,主要自己不做圖像處理這塊,所以就只瞭解了哈,這裏截了一下最終的效果圖:

訓練前數據分佈:

訓練後數據分佈:

第八課 主要講解:保存和載入模型,使用Google的圖像識別網絡inception-v3進行圖像識別。

1. 保存模型

saver = tf.train.Saver()
with tf.Session() as sess:
    sess.run(init)
    for epoch in range(21):
        for batch in range(n_batch):
            # train
        acc = sess.run(accuracy, feed_dict={x: mnist.test.images, y: mnist.test.labels})
        print("Iter " + str(epoch) + " Testing Accuracy: " + str(acc))
    saver.save(sess, model_dir + '/test_net.ckpt')

2.載入模型

saver = tf.train.Saver()
with tf.Session() as sess:
    sess.run(init)
    acc1 = sess.run(accuracy, feed_dict={x:mnist.test.images, y:mnist.test.labels})
    saver.restore(sess, model_dir + '/test_net.ckpt')
    acc2 = sess.run(accuracy, feed_dict={x:mnist.test.images,y:mnist.test.labels})
    print(" Init Accuracy" + str(acc1))
    print(" Restore Accuracy: " + str(acc2))

3. 使用inception-v3進行圖像識別

這裏我也沒看,主要自己不做圖像處理這塊。以後用到的話可以補一下。

第九課 Tensorflow的GPU版本安裝。設計自己的網絡模型,並訓練自己的網絡模型進行圖像識別。

這節主要講解如何訓練自己的模型代碼,主要有三種方法:

1. 自己寫自己從頭構建網絡,從頭訓練;

2. 用一個現成的質量比較好的模型,固定前面參數,在後面添加幾層,訓練後面的參數;

3. 改造現成的質量比較好的模型,訓練整個網絡的模型(初始層的學習率比較低);也就是對已有模型的權重參數做微調,重點訓練最後幾層自己寫的模型的權重參數,但總體來說所有的權重參數都有改變。

第十一課 word2vec講解和使用,cnn解決文本分類問題。

對於這一節課的內容,我在後邊有一節專門講解word2vec預訓練的時候着重講解。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章