深度學習利器:TensorFlow實戰

SteSeekamp 7年前發布 | 60K 次閱讀 機器學習 TensorFlow

深度學習及TensorFlow簡介

深度學習目前已經被應用到圖像識別,語音識別,自然語言處理,機器翻譯等場景并取得了很好的行業應用效果。至今已有數種深度學習框架,如TensorFlow、Caffe、Theano、Torch、MXNet,這些框架都能夠支持深度神經網絡、卷積神經網絡、深度信念網絡和遞歸神經網絡等模型。TensorFlow最初由Google Brain團隊的研究員和工程師研發,目前已成為GitHub上最受歡迎的機器學習項目。

TensorFlow開源一周年以來,已有500+contributors,以及11000+個commits。目前采用TensorFlow平臺,在生產環境下進行深度學習的公司有ARM、Google、UBER、DeepMind、京東等公司。目前谷歌已把TensorFlow應用到很多內部項目,如谷歌語音識別,GMail,谷歌圖片搜索等。TensorFlow主要特性有:

使用靈活:TensorFlow是一個靈活的神經網絡學習平臺,采用圖計算模型,支持High-Level的API,支持Python、C++、Go、Java接口。

跨平臺:TensorFlow支持CPU和GPU的運算,支持臺式機、服務器、移動平臺的計算。并從r0.12版本支持Windows平臺。

產品化:TensorFlow支持從研究團隊快速遷移學習模型到生產團隊。實現了研究團隊發布模型,生產團隊驗證模型,構建起了模型研究到生產實踐的橋梁。

高性能:TensorFlow中采用了多線程,隊列技術以及分布式訓練模型,實現了在多CPU、多GPU的環境下分布式訓練模型。

本文主要介紹TensorFlow一些關鍵技術的使用實踐,包括TensorFlow變量、TensorFlow應用架構、TensorFlow可視化技術、GPU使用,以及HDFS集成使用。

TensorFlow變量

TensorFlow中的變量在使用前需要被初始化,在模型訓練中或訓練完成后可以保存或恢復這些變量值。下面介紹如何創建變量,初始化變量,保存變量,恢復變量以及共享變量。

#創建模型的權重及偏置

weights = tf.Variable(tf.random_normal([784, 200], stddev=0.35), name="weights")

biases = tf.Variable(tf.zeros([200]), name="biases")

指定變量所在設備為CPU:0

with tf.device("/cpu:0"):

v = tf.Variable(...)

初始化模型變量

init_op = tf.global_variables_initializer()

sess=tf.Session()

sess.run(init_op)

保存模型變量,由三個文件組成model.data,model.index,model.meta

saver = tf.train.Saver()

saver.restore(sess, "/tmp/model")

恢復模型變量

saver.restore(sess, "/tmp/model")</code></pre>

在復雜的深度學習模型中,存在大量的模型變量,并且期望能夠一次性地初始化這些變量。TensorFlow提供了tf.variable_scope和tf.get_variable兩個API,實現了共享模型變量。tf.get_variable(<name>, <shape>, <initializer>):表示創建或返回指定名稱的模型變量,其中name表示變量名稱,shape表示變量的維度信息,initializer表示變量的初始化方法。tf.variable_scope(<scope_name>):表示變量所在的命名空間,其中scope_name表示命名空間的名稱。共享模型變量使用示例如下:

#定義卷積神經網絡運算規則,其中weights和biases為共享變量

def conv_relu(input, kernel_shape, bias_shape):

# 創建變量"weights".

weights = tf.get_variable("weights", kernel_shape, initializer=tf.random_normal_initializer())

# 創建變量 "biases".

biases = tf.get_variable("biases", bias_shape, initializer=tf.constant_initializer(0.0))

conv = tf.nn.conv2d(input, weights, strides=[1, 1, 1, 1], padding='SAME')

return tf.nn.relu(conv + biases)



定義卷積層,conv1和conv2為變量命名空間

with tf.variable_scope("conv1"):

# 創建變量 "conv1/weights", "conv1/biases".

relu1 = conv_relu(input_images, [5, 5, 32, 32], [32])

with tf.variable_scope("conv2"):

# 創建變量 "conv2/weights", "conv2/biases".

relu1 = conv_relu(relu1, [5, 5, 32, 32], [32])</code></pre> 

TensorFlow應用架構

TensorFlow的應用架構主要包括模型構建,模型訓練,及模型評估三個方面。模型構建主要指構建深度學習神經網絡,模型訓練主要指在TensorFlow會話中對訓練數據執行神經網絡運算,模型評估主要指根據測試數據評估模型精確度。如下圖所示:

網絡模型,損失方程,模型訓練操作定義示例如下:

#兩個隱藏層,一個logits輸出層

hidden1 = tf.nn.relu(tf.matmul(images, weights) + biases)

hidden2 = tf.nn.relu(tf.matmul(hidden1, weights) + biases)

logits = tf.matmul(hidden2, weights) + biases

損失方程,采用softmax交叉熵算法

cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits( logits, labels, name='xentropy')

loss = tf.reduce_mean(cross_entropy, name='xentropy_mean')

選定優化算法及定義訓練操作

optimizer = tf.train.GradientDescentOptimizer(learning_rate)

global_step = tf.Variable(0, name='global_step', trainable=False)

train_op = optimizer.minimize(loss, global_step=global_step)

模型訓練及模型驗證示例如下:

加載訓練數據,并執行網絡訓練

for step in xrange(FLAGS.max_steps):

feed_dict = fill_feed_dict(data_sets.train, images_placeholder, labels_placeholder)

_, loss_value = sess.run([train_op, loss], feed_dict=feed_dict)



加載測試數據,計算模型精確度

for step in xrange(steps_per_epoch):

feed_dict = fill_feed_dict(data_set, images_placeholder, labels_placeholder)

true_count += sess.run(eval_correct, feed_dict=feed_dict)</code></pre> 

TensorFlow可視化技術

大規模的深度神經網絡運算模型是非常復雜的,并且不容易理解運算過程。為了易于理解、調試及優化神經網絡運算模型,數據科學家及應用開發人員可以使用TensorFlow可視化組件:TensorBoard。TensorBoard主要支持TensorFlow模型可視化展示及統計信息的圖表展示。TensorBoard應用架構如下:

TensorFlow可視化技術主要分為兩部分:TensorFlow摘要模型及TensorBoard可視化組件。在摘要模型中,需要把模型變量或樣本數據轉換為TensorFlow summary操作,然后合并summary操作,最后通過Summary Writer操作寫入TensorFlow的事件日志。TensorBoard通過讀取事件日志,進行相關摘要信息的可視化展示,主要包括:Scalar圖、圖片數據可視化、聲音數據展示、圖模型可視化,以及變量數據的直方圖和概率分布圖。TensorFlow可視化技術的關鍵流程如下所示:

#定義變量及訓練數據的摘要操作

tf.summary.scalar('max', tf.reduce_max(var))

tf.summary.histogram('histogram', var)

tf.summary.image('input', image_shaped_input, 10)

定義合并變量操作,一次性生成所有摘要數據

merged = tf.summary.merge_all()

定義寫入摘要數據到事件日志的操作

train_writer = tf.train.SummaryWriter(FLAGS.log_dir + '/train', sess.graph)

test_writer = tf.train.SummaryWriter(FLAGS.log_dir + '/test')

執行訓練操作,并把摘要信息寫入到事件日志

summary, _ = sess.run([merged, train_step], feed_dict=feed_dict(True))

train_writer.add_summary(summary, i)

下載示例code,并執行模型訓練

python mnist_with_summaries.py

啟動TensorBoard,TensorBoard的UI地址為http://ip_address:6006

tensorboard --logdir=/path/to/log-directory</code></pre>

TensorBoard Scalar圖如下所示,其中橫坐標表示模型訓練的迭代次數,縱坐標表示該標量值,例如模型精確度,熵值等。TensorBoard支持這些統計值的下載。

TensorFlow Image摘要信息如下圖所示,該示例中顯示了測試數據和訓練數據中的手寫數字圖片。

TensorFlow圖模型如下圖所示,可清晰地展示模型的訓練流程,其中的每個方框表示變量所在的命名空間。包含的命名空間有input(輸入數據),input_reshape(矩陣變換,用于圖形化手寫數字), layer1(隱含層1), layer2(隱含層2), dropout(丟棄一些神經元,防止過擬合), accuracy(模型精確度), cross_entropy(目標函數值,交叉熵), train(訓練模型)。例如,input命名空間操作后的tensor數據會傳遞給input_reshape,train,accuracy,layer1,cross_entropy命名空間中的操作。

TensorFlow變量的概率分布如下圖所示,其中橫坐標為迭代次數,縱坐標為變量取值范圍。圖表中的線表示概率百分比,從高到底為[maximum, 93%, 84%, 69%, 50%, 31%, 16%, 7%, minimum]。例如,圖表中從高到底的第二條線為93%,對應該迭代下有93%的變量權重值小于該線對應的目標值。

上述TensorFlow變量概率分布對應的直方圖如下圖所示:

TensorFlow GPU使用

GPU設備已經廣泛地應用于圖像分類,語音識別,自然語言處理,機器翻譯等深度學習領域,并實現了開創性的性能改進。與單純使用CPU相比,GPU 具有數以千計的計算核心,可實現 10-100 倍的性能提升。TensorFlow支持GPU運算的版本為tensorflow-gpu,并且需要先安裝相關軟件:GPU運算平臺CUDA和用于深度神經網絡運算的GPU加速庫CuDNN。在TensorFlow中,CPU或GPU的表示方式如下所示:

"/cpu:0":表示機器中第一個CPU。

"/gpu:0":表示機器中第一個GPU卡。

"/gpu:1":表示機器中第二個GPU卡。

TensorFlow中所有操作都有CPU和GPU運算的實現,默認情況下GPU運算的優先級比CPU高。如果TensorFlow操作沒有指定在哪個設備上進行運算,默認會優選采用GPU進行運算。下面介紹如何在TensorFlow使用GPU:

# 定義使用gpu0執行a*b的矩陣運算,其中a,b,c都在gpu0上執行

with tf.device('/gpu:0'):

a = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[2, 3], name='a')

b = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[3, 2], name='b')

c = tf.matmul(a, b)

通過log_device_placement指定在日志中輸出變量和操作所在的設備

sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))

print sess.run(c)</code></pre>

本實驗環境下只有一個GPU卡,設備的Device Mapping及變量操作所在設備位置如下:

#設備的Device Mapping

/job:localhost/replica:0/task:0/gpu:0 -> device: 0, name: Tesla K20c, pci bus id: 0000:81:00.0

變量操作所在設備位置

a: (Const): /job:localhost/replica:0/task:0/gpu:0

b: (Const): /job:localhost/replica:0/task:0/gpu:0

(MatMul)/job:localhost/replica:0/task:0/gpu:0</code></pre>

默認配置下,TensorFlow Session會占用GPU卡上所有內存。但TesnorFlow提供了兩個GPU內存優化配置選項。config.gpu_options.allow_growth:根據程序運行情況,分配GPU內存。程序開始的時候分配比較少的內存,隨著程序的運行,增加內存的分配,但不會釋放已經分配的內存。config.gpu_options.per_process_gpu_memory_fraction:表示按照百分比分配GPU內存,例如0.4表示分配40%的GPU內存。示例代碼如下:

#定義TensorFlow配置

config = tf.ConfigProto()

配置GPU內存分配方式

config.gpu_options.allow_growth = True

config.gpu_options.per_process_gpu_memory_fraction = 0.4

session = tf.Session(config=config, ...)</code></pre>

TensorFlow與HDFS集成使用

HDFS是一個高度容錯性的分布式系統,能提供高吞吐量的數據訪問,非常適合大規模數據集上的應用。TensorFlow與HDFS集成示例如下:

#配置JAVA和HADOOP環境變量

source $HADOOP_HOME/libexec/hadoop-config.sh

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$JAVA_HOME/jre/lib/amd64/server

執行TensorFlow運行模型

CLASSPATH=$($HADOOP_HDFS_HOME/bin/hadoop classpath --glob) python tensorflow_model.py

在TensorFlow模型中定義文件的讀取隊列

filename_queue = tf.train.string_input_producer(["hdfs://namenode:8020/path/to/file1.csv", "hdfs://namenode:8020/path/to/file2.csv"])

從文件中讀取一行數據,value為所對應的行數據

reader = tf.TextLineReader()

key, value = reader.read(filename_queue)

把讀取到的value值解碼成特征向量,record_defaults定義解碼格式及對應的數據類型

record_defaults = [[1], [1], [1], [1], [1]]

col1, col2, col3, col4, col5 = tf.decode_csv(value, record_defaults=record_defaults)

features = tf.pack([col1, col2, col3, col4])

with tf.Session() as sess:

定義同步對象,并啟動相應線程把HDFS文件名插入到隊列

coord = tf.train.Coordinator()

threads = tf.train.start_queue_runners(coord=coord)

for i in range(1200):

# 從文件隊列中讀取一行數據

example, label = sess.run([features, col5])



請求停止隊列的相關線程(包括進隊及出隊線程)

coord.request_stop()

等待隊列中相關線程結束(包括進隊及出隊線程)

coord.join(threads)</code></pre>

參考文獻

[1] http://www.tensorflow.org

[2] 深度學習利器:分布式TensorFlow及實例分析

 

 

來自:http://www.infoq.com/cn/articles/deeplearning-tensorflow-actual-combat

 

 本文由用戶 SteSeekamp 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!