一個月暴力入門tensorflow
目錄
為什麼是tensorflow:
現在玩機器學習的人大概沒有不知道tensorflow大名的吧,但是與caffe,keras相比,這位“仁兄”確實不怎麼友好。即是這樣,在眾多開源的深度學習框架當中,tensorflow也是一枝獨秀。Google的大名和號召力當然是其中一方面原因,但是,tensorflow也具有眾多的優點。比如,網路結構程式碼十分簡潔,分散式深度學習演算法的執行效率等等。作為一個“菜雞”來看,最吸引我的地方就是tensorflow對於python介面的支援十分良好。畢竟沒有一個數據挖掘工作是單單定義網路就可以完成的。Python所擁有的Numpy, Scipy, Pandas等組建能大大提升工作的效率。
出來以上的優點以外,tensorflow對於網路結構的視覺化和訓練過程的視覺化也有非常優秀的地方,下面是兩個例子,第一個是tensorflow的tensorboard工具,第二個是tensorflow的playground。
說說目的:
寫這一系列博文的目的當然不是為了將深度學習,畢竟這是一個太寬泛,我的知識水平難以完全駕馭的領域。我只是提供一個途徑,一種入門的方式。在最初接觸一個領域的知識的時候如果單純看論文會非常枯燥,而且顧前不顧後,狗熊掰棒子。但是如果能從一開始就動手操作,再看論文,做理論推導,整個過程會像揭祕一樣有趣。我的目的就是把學習tensorflow這個“迷”給大家呈現出來。怎麼去理解,分析,就看個人的功夫了。
這一系列的文章會以一種:程式碼段->程式碼解釋->執行結果->除錯心得的形式展現我一個月以來的學習成果。也算是一種筆記。但是,鮮有涉及原理的部分。或者以後的文章會講到原理。但是作為一篇技術入門文章,我力圖使文章儘量簡潔,操作性強,而不是全面。
其中的程式碼大部分都是我從《Tensorflow實戰Google深度學習框架》,《Tensorflow實戰》還有Tensorflow的自帶例子裡面修改過來的。每一段都在自己的計算機上(ubuntu14.04+tensorflow 0.8.0)上實驗過。如果複製程式碼而不能執行多半是版本的問題,或者是有些路徑的問題。希望大家多加諒解。
文章結構
文章將會涉及以下內容:
- mnist手寫數字識別
- 從mnist例子看tensorflow基礎知識
- 來寫個Lenet5
- 經典卷積神經網路之AlexNet
- 經典卷積神經網路之VGG
- 嚇死人的Inception Net以及遷移學習
- Resnet和沒學會的tf.contrib.slim模組
- Word2Vec探祕
- 迴圈神經網路到底是什麼?
- 深度強化學習初探
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部分(其他當然也一樣)。圖片部分是將一幅
展示一張圖片:
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()
結果: