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:0with 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.metasaver = tf.train.Saver()saver.restore(sess, "/tmp/model")#恢復模型變數saver.restore(sess, "/tmp/model")

在複雜的深度學習模型中,存在大量的模型變數,並且期望能夠一次性地初始化這些變數。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])

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)

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) #從https://github.com/tensorflow/tensorflow/blob/r0.12/tensorflow/examples/tutorials/mnist/mnist_with_summaries.py下載示例code,並執行模型訓練 python mnist_with_summaries.py#啟動TensorBoard,TensorBoard的UI地址為http://ip_address:6006tensorboard --logdir=/path/to/log-directory

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)

本實驗環境下只有一個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:0b: (Const): /job:localhost/replica:0/task:0/gpu:0(MatMul)/job:localhost/replica:0/task:0/gpu:0

默認配置下,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.4session = tf.Session(config=config, ...)

TensorFlow與HDFS集成使用

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

#配置JAVA和HADOOP環境變數source $HADOOP_HOME/libexec/hadoop-config.shexport 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)

推薦閱讀:

Tensorflow op放置策略
Win10 Tensorflow
如何使用最流行框架Tensorflow進行時序預測和時間序列分析
官方 | 谷歌 AI 中國中心成立

TAG:TensorFlow | 深度學習DeepLearning |