一篇文章掌握TensorFlow深度學習

作者: 陳迪豪困鸥,就職小米科技嗅蔬,深度學習工程師,TensorFlow代碼提交者疾就。

TensorFlow深度學習框架

image.png

Google不僅是大數(shù)據(jù)和云計算的領(lǐng)導(dǎo)者澜术,在機器學習和深度學習上也有很好的實踐和積累,在2015年年底開源了內(nèi)部使用的深度學習框架TensorFlow猬腰。

與Caffe鸟废、Theano、Torch姑荷、MXNet等框架相比盒延,TensorFlow在Github上Fork數(shù)和Star數(shù)都是最多的,而且在圖形分類鼠冕、音頻處理添寺、推薦系統(tǒng)和自然語言處理等場景下都有豐富的應(yīng)用。最近流行的Keras框架底層默認使用TensorFlow懈费,著名的斯坦福CS231n課程使用TensorFlow作為授課和作業(yè)的編程語言计露,國內(nèi)外多本TensorFlow書籍已經(jīng)在籌備或者發(fā)售中,AlphaGo開發(fā)團隊Deepmind也計劃將神經(jīng)網(wǎng)絡(luò)應(yīng)用遷移到TensorFlow中憎乙,這無不印證了TensorFlow在業(yè)界的流行程度薄坏。

TensorFlow不僅在Github開放了源代碼,在《TensorFlow: Large-Scale Machine Learning on Heterogeneous Distributed Systems》論文中也介紹了系統(tǒng)框架的設(shè)計與實現(xiàn)寨闹,其中測試過200節(jié)點規(guī)模的訓(xùn)練集群也是其他分布式深度學習框架所不能媲美的胶坠。Google還在《Wide & Deep Learning for Recommender Systems》和《The YouTube Video Recommendation System》論文中介紹了Google Play應(yīng)用商店和YouTube視頻推薦的算法模型,還提供了基于TensorFlow的代碼實例繁堡,使用TensorFlow任何人都可以在ImageNet或Kaggle競賽中得到接近State of the art的好成績沈善。

TensorFlow從入門到應(yīng)用

毫不夸張得說,TensorFlow的流行讓深度學習門檻變得越來越低椭蹄,只要你有Python和機器學習基礎(chǔ)闻牡,入門和使用神經(jīng)網(wǎng)絡(luò)模型變得非常簡單。TensorFlow支持Python和C++兩種編程語言绳矩,再復(fù)雜的多層神經(jīng)網(wǎng)絡(luò)模型都可以用Python來實現(xiàn)罩润,如果業(yè)務(wù)使用其他編程也不用擔心,使用跨語言的gRPC或者HTTP服務(wù)也可以訪問使用TensorFlow訓(xùn)練好的智能模型翼馆。

那使用Python如何編寫TensorFlow應(yīng)用呢割以?從入門到應(yīng)用究竟有多難呢金度?

下面我們編寫了一個Hello world應(yīng)用,輸出字符串和進行簡單的運算严沥。

# Import the library
import tensorflow as tf

# Define the graph
hello_op = tf.constant('Hello, TensorFlow!')
a = tf.constant(10)
b = tf.constant(32)
compute_op = tf.add(a, b)

# Define the session to run graph
with tf.Session() as sess:
    print(sess.run(hello_op))
    print(sess.run(compute_op))

從這段簡單的代碼可以了解到TensorFlow的使用非常方便猜极,通過Python標準庫的形式導(dǎo)入,不需要啟動額外的服務(wù)消玄。第一次接觸TensorFlow可能比較疑惑跟伏,這段邏輯Python也可以實現(xiàn),為什么要使用tf.constant()和tf.Session()呢翩瓜?其實TensorFlow通過Graph和Session來定義運行的模型和訓(xùn)練受扳,這在復(fù)雜的模型和分布式訓(xùn)練上有非常大好處,將在文章的后續(xù)部分介紹到兔跌。

前面的Hello world應(yīng)用并沒有訓(xùn)練模型辞色,接下來介紹一個邏輯回歸問題與模型。我們使用numpy構(gòu)建一組線性關(guān)系的數(shù)據(jù)浮定,通過TensorFlow實現(xiàn)的隨機梯度算法相满,在訓(xùn)練足夠長的時間后可以自動求解函數(shù)中的斜率和截距。

import tensorflow as tf
import numpy as np

# Prepare train data
train_X = np.linspace(-1, 1, 100)
train_Y = 2 * train_X + np.random.randn(*train_X.shape) * 0.33 + 10

# Define the model
X = tf.placeholder(tf.float32)
Y = tf.placeholder(tf.float32)
w = tf.Variable(0.0, name="weight")
b = tf.Variable(0.0, name="bias")
loss = tf.square(Y - tf.matmul(X, w) - b)
train_op = tf.train.GradientDescentOptimizer(0.01).minimize(loss)

# Create session to run
with tf.Session() as sess:
    sess.run(tf.initialize_all_variables())
    epoch = 1
    for i in range(10):
        for (x, y) in zip(train_X, train_Y):
            _, w_value, b_value = sess.run([train_op, w, b], 
                                           feed_dict={X: x, Y: y})
        print("Epoch: {}桦卒, w: {}, b: {}".format(epoch, w_value, b_value))
        epoch += 1

上面的代碼可以在tensorflow_examples項目中找到立美,經(jīng)過訓(xùn)練,我們看到輸出的斜率w約為2方灾,截距b約為10建蹄,與我們構(gòu)建的數(shù)據(jù)之間的關(guān)聯(lián)關(guān)系十分吻合!注意在TensorFlow代碼中并沒有實現(xiàn)最小二乘法等算法裕偿,也沒有if-else來控制代碼邏輯洞慎,完全是由數(shù)據(jù)驅(qū)動并且根據(jù)梯度下降算法動態(tài)調(diào)整Loss值學習出來的。這樣我們即使換了其他數(shù)據(jù)集嘿棘,甚至換成圖像分類等其他領(lǐng)域的問題劲腿,無需修改代碼也可以由機器自動學習,這也是神經(jīng)網(wǎng)絡(luò)和TensorFlow強大的地方鸟妙。

Epoch: 1焦人, w: -0.909195065498352, b: 9.612462043762207
Epoch: 2, w: 0.296161413192749, b: 10.418954849243164
Epoch: 3重父, w: 1.108984351158142, b: 10.283171653747559
Epoch: 4花椭, w: 1.5482335090637207, b: 10.143315315246582
Epoch: 5, w: 1.7749555110931396, b: 10.063009262084961
Epoch: 6房午, w: 1.8906776905059814, b: 10.020986557006836
Epoch: 7矿辽, w: 1.9495772123336792, b: 9.999467849731445
Epoch: 8, w: 1.9795364141464233, b: 9.988500595092773
Epoch: 9, w: 1.994771122932434, b: 9.982922554016113
Epoch: 10袋倔, w: 2.0025179386138916, b: 9.980087280273438

前面的模型只有w和b兩個變量雕蔽,如果數(shù)據(jù)處于非線性關(guān)系就難以得到很好的結(jié)果,因此我們建議使用深層神經(jīng)網(wǎng)絡(luò)奕污,這也是TensorFlow設(shè)計重點就要解決的深度學習模型萎羔。我們知道Google在2014年憑借Inception模型贏下了ImageNet全球競賽液走,里面代碼就是基于TensorFlow實現(xiàn)的碳默,下面是較為復(fù)雜的模型定義代碼。

with tf.op_scope([inputs], scope, 'inception_v3'):
    with scopes.arg_scope([ops.conv2d, ops.fc, ops.batch_norm, ops.dropout], is_training=is_training):
        with scopes.arg_scope([ops.conv2d, ops.max_pool, ops.avg_pool], stride=1, padding='VALID'):
            
            # 299 x 299 x 3
            end_points['conv0'] = ops.conv2d(inputs, 32, [3, 3], stride=2, scope='conv0')
            
            # 149 x 149 x 32
            end_points['conv1'] = ops.conv2d(end_points['conv0'], 32, [3, 3], scope='conv1')
            
            # 147 x 147 x 32
            end_points['conv2'] = ops.conv2d(end_points['conv1'], 64, [3, 3], padding='SAME', scope='conv2')
            
            # 147 x 147 x 64
            end_points['pool1'] = ops.max_pool(end_points['conv2'], [3, 3], stride=2, scope='pool1')
            
            # 73 x 73 x 64
            end_points['conv3'] = ops.conv2d(end_points['pool1'], 80, [1, 1], scope='conv3')
            
            # 73 x 73 x 80
            end_points['conv4'] = ops.conv2d(end_points['conv3'], 192, [3, 3], scope='conv4')
            
            # 71 x 71 x 192
            end_points['pool2'] = ops.max_pool(end_points['conv4'], [3, 3], stride=2, scope='pool2')
            
            # 35 x 35 x 192
            net = end_points['pool2']
            

使用TensorFlow已經(jīng)封裝好的全連接網(wǎng)絡(luò)缘眶、卷積神經(jīng)網(wǎng)絡(luò)嘱根、RNN和LSTM,我們已經(jīng)可以組合出各種網(wǎng)絡(luò)模型巷懈,實現(xiàn)Inception這樣的多層神經(jīng)網(wǎng)絡(luò)如拼湊Lego一樣簡單该抒。但在選擇優(yōu)化算法、生成TFRecords顶燕、導(dǎo)出模型文件和支持分布式訓(xùn)練上凑保,這里有比較多的細節(jié),接下來我們將在一篇文章的篇幅內(nèi)介紹所有TensorFlow相關(guān)的核心使用技巧涌攻。

TensorFlow核心使用技巧

為了介紹TensorFlow的各種用法欧引,我們將使用deep_recommend_system(https://github.com/tobegit3hub/deep_recommend_system)
這個開源項目,它實現(xiàn)了TFRecords恳谎、QueueRunner芝此、Checkpoint、TensorBoard因痛、Inference婚苹、GPU支持、分布式訓(xùn)練和多層神經(jīng)網(wǎng)絡(luò)模型等特性鸵膏,而且可以輕易拓展實現(xiàn)Wide and deep等模型膊升,在實際的項目開發(fā)中可以直接下載使用。

1. 準備訓(xùn)練數(shù)據(jù)

一般TensorFlow應(yīng)用代碼包含Graph的定義和Session的運行谭企,代碼量不大可以封裝到一個文件中用僧,如cancer_classifier.py文件。訓(xùn)練前需要準備樣本數(shù)據(jù)和測試數(shù)據(jù)赞咙,一般數(shù)據(jù)文件是空格或者逗號分隔的CSV文件责循,但TensorFlow建議使用二進制的TFRecords格式,這樣可以支持QueuRunner和Coordinator進行多線程數(shù)據(jù)讀取攀操,并且可以通過batch size和epoch參數(shù)來控制訓(xùn)練時單次batch的大小和對樣本文件迭代訓(xùn)練多少輪院仿。如果直接讀取CSV文件,需要在代碼中記錄下一次讀取數(shù)據(jù)的指針,而且在樣本無法全部加載到內(nèi)存時使用非常不便歹垫。

在data目錄剥汤,項目已經(jīng)提供了CSV與TFRecords格式轉(zhuǎn)換工具generate_csv_tfrecords.py,參考這個腳本你就可以parse任意格式的CSV文件排惨,轉(zhuǎn)成TensorFlow支持的TFRecords格式吭敢。無論是大數(shù)據(jù)還是小數(shù)據(jù),通過簡單的腳本工具就可以直接對接TensorFlow暮芭,項目中還提供print_csv_tfrecords.py腳本來調(diào)用API直接讀取TFRecords文件的內(nèi)容鹿驼。

def generate_tfrecords(input_filename, output_filename):
    print("Start to convert {} to {}".format(input_filename, output_filename))
    writer = tf.python_io.TFRecordWriter(output_filename)

    for line in open(input_filename, "r"):
        data = line.split(",")
        label = float(data[9])
        features = [float(i) for i in data[:9]]

        example = tf.train.Example(features=tf.train.Features(feature={
            "label":
            tf.train.Feature(float_list=tf.train.FloatList(value=[label])),
            "features":
            tf.train.Feature(float_list=tf.train.FloatList(value=features)),
        }))
        writer.write(example.SerializeToString())

    writer.close()
    print("Successfully convert {} to {}".format(input_filename,
                                                 output_filename))

2. 接受命令行參數(shù)

有了TFRecords,我們就可以編寫代碼來訓(xùn)練神經(jīng)網(wǎng)絡(luò)模型了辕宏,但眾所周知畜晰,深度學習有過多的Hyperparameter需要調(diào)優(yōu),我們就優(yōu)化算法瑞筐、模型層數(shù)和不同模型都需要不斷調(diào)整凄鼻,這時候使用命令行參數(shù)是非常方便的。

TensorFlow底層使用了python-gflags項目聚假,然后封裝成tf.app.flags接口块蚌,使用起來非常簡單和直觀,在實際項目中一般會提前定義命令行參數(shù)膘格,尤其在后面將會提到的Cloud Machine Learning服務(wù)中峭范,通過參數(shù)來簡化Hyperparameter的調(diào)優(yōu)。

# Define hyperparameters
flags = tf.app.flags
FLAGS = flags.FLAGS
flags.DEFINE_boolean("enable_colored_log", False, "Enable colored log")
flags.DEFINE_string("train_tfrecords_file",
                    "./data/a8a/a8a_train.libsvm.tfrecords",
                    "The glob pattern of train TFRecords files")
flags.DEFINE_string("validate_tfrecords_file",
                    "./data/a8a/a8a_test.libsvm.tfrecords",
                    "The glob pattern of validate TFRecords files")
flags.DEFINE_integer("feature_size", 124, "Number of feature size")
flags.DEFINE_integer("label_size", 2, "Number of label size")
flags.DEFINE_float("learning_rate", 0.01, "The learning rate")
flags.DEFINE_integer("epoch_number", 10, "Number of epochs to train")
flags.DEFINE_integer("batch_size", 1024, "The batch size of training")
flags.DEFINE_integer("validate_batch_size", 1024,
                     "The batch size of validation")
flags.DEFINE_integer("batch_thread_number", 1,
                     "Number of threads to read data")
flags.DEFINE_integer("min_after_dequeue", 100,
                     "The minimal number after dequeue")
flags.DEFINE_string("checkpoint_path", "./sparse_checkpoint/",
                    "The path of checkpoint")
flags.DEFINE_string("output_path", "./sparse_tensorboard/",
                    "The path of tensorboard event files")
flags.DEFINE_string("model", "dnn", "Support dnn, lr, wide_and_deep")
flags.DEFINE_string("model_network", "128 32 8", "The neural network of model")
flags.DEFINE_boolean("enable_bn", False, "Enable batch normalization or not")
flags.DEFINE_float("bn_epsilon", 0.001, "The epsilon of batch normalization")
flags.DEFINE_boolean("enable_dropout", False, "Enable dropout or not")
flags.DEFINE_float("dropout_keep_prob", 0.5, "The dropout keep prob")
flags.DEFINE_boolean("enable_lr_decay", False, "Enable learning rate decay")
flags.DEFINE_float("lr_decay_rate", 0.96, "Learning rate decay rate")
flags.DEFINE_string("optimizer", "adagrad", "The optimizer to train")
flags.DEFINE_integer("steps_to_validate", 10,
                     "Steps to validate and print state")
flags.DEFINE_string("mode", "train", "Support train, export, inference")
flags.DEFINE_string("saved_model_path", "./sparse_saved_model/",
                    "The path of the saved model")
flags.DEFINE_string("model_path", "./sparse_model/", "The path of the model")
flags.DEFINE_integer("model_version", 1, "The version of the model")
flags.DEFINE_string("inference_test_file", "./data/a8a_test.libsvm",
                    "The test file for inference")
flags.DEFINE_string("inference_result_file", "./inference_result.txt",
                    "The result file from inference")

3. 定義神經(jīng)網(wǎng)絡(luò)模型

準備完數(shù)據(jù)和參數(shù)闯袒,最重要的還是要定義好網(wǎng)絡(luò)模型虎敦,定義模型參數(shù)可以很簡單肿仑,創(chuàng)建多個Variable即可匾乓,也可以做得比較復(fù)雜迅皇,例如使用使用tf.variable_scope()和tf.get_variables()接口匾七。為了保證每個Variable都有獨特的名字用狱,而且能都輕易地修改隱層節(jié)點數(shù)和網(wǎng)絡(luò)層數(shù)禽拔,我們建議參考項目中的代碼埠帕,尤其在定義Variables時注意要綁定CPU拔恰,TensorFlow默認使用GPU可能導(dǎo)致參數(shù)更新過慢褪尝。

# Define the model
input_units = FEATURE_SIZE
hidden1_units = 10
hidden2_units = 10
hidden3_units = 10
hidden4_units = 10
output_units = LABEL_SIZE

def full_connect(inputs, weights_shape, biases_shape):
    with tf.device('/gpu:0'):
        weights = tf.get_variable("weights", weights_shape, 
                                 initializer=tf.random_normal_initializer())
        biases = tf.get_variable("biases", biases_shape,
                                 initializer=tf.random_normal_initializer())
        return tf.matmul(inputs, weights) + biases

def full_connect_relu(inputs, weights_shape, biases_shape):
    return tf.nn.relu(full_connect(inputs, weights_shape, biases_shape))

def deep_inference(inputs):
    with tf.variable_scope("layer1"):
        layer = full_connect_relu(inputs, [input_units, hidden1_units],
                                 [hidden1_units])
    with tf.variable_scope("layer2"):
        layer = full_connect_relu(inputs, [hidden1_units, hidden2_units],
                                 [hidden2_units])
    with tf.variable_scope("layer3"):
        layer = full_connect_relu(inputs, [hidden2_units, hidden3_units],
                                 [hidden3_units])
    with tf.variable_scope("layer4"):
        layer = full_connect_relu(inputs, [hidden3_units, hidden4_units],
                                 [hidden4_units])
    with tf.variable_op_scope("output"):
        layer = full_connect_relu(inputs, [hidden4_units, output_units],
                                 [output_units])
    return layer

上述代碼在生產(chǎn)環(huán)境也十分常見闹获,無論是訓(xùn)練、實現(xiàn)inference還是驗證模型正確率和auc時都會用到河哑。項目中還基于此代碼實現(xiàn)了Wide and deep模型避诽,在Google Play應(yīng)用商店的推薦業(yè)務(wù)有廣泛應(yīng)用,這也是適用于普遍的推薦系統(tǒng)璃谨,將傳統(tǒng)的邏輯回歸模型和深度學習的神經(jīng)網(wǎng)絡(luò)模型有機結(jié)合在一起沙庐。

4. 使用不同的優(yōu)化算法

定義好網(wǎng)絡(luò)模型鲤妥,我們需要覺得使用哪種Optimizer去優(yōu)化模型參數(shù),是應(yīng)該選擇Sgd拱雏、Rmsprop還是選擇Adagrad棉安、Ftrl呢?對于不同場景和數(shù)據(jù)集沒有固定的答案铸抑,最好的方式就是實踐贡耽,通過前面定義的命令行參數(shù)我們可以很方便得使用不同優(yōu)化算法來訓(xùn)練模型。

def get_optimizer(optimizer, learning_rate):
    logging.info("Use the optimizer: {}".format(optimizer))
    if optimizer == "sgd":
        return tf.train.GradientDescentOptimizer(learning_rate)
    elif optimizer == "adadelta":
        return tf.train.AdadeltaOptimizer(learning_rate)
    elif optimizer == "adagrad":
        return tf.train.AdagradOptimizer(learning_rate)
    elif optimizer == "adam":
        return tf.train.AdamOptimizer(learning_rate)
    elif optimizer == "ftrl":
        return tf.train.FtrlOptimizer(learning_rate)
    elif optimizer == "rmsprop":
        return tf.train.RMSPropOptimizer(learning_rate)
    else:
        logging.error("Unknow optimizer, exit now")
        exit(1)

在生產(chǎn)實踐中鹊汛,不同優(yōu)化算法在訓(xùn)練結(jié)果蒲赂、訓(xùn)練速度上都有很大差異,過度優(yōu)化網(wǎng)絡(luò)參數(shù)可能效果沒有使用其他優(yōu)化算法來得有效柒昏,因此選用正確的優(yōu)化算法也是Hyperparameter調(diào)優(yōu)中很重要的一步凳宙,通過在TensorFlow代碼中加入這段邏輯也可以很好地實現(xiàn)對應(yīng)的功能职祷。

5. Online learning與Continuous learning

很多機器學習廠商都會宣稱自己的產(chǎn)品支持Online learning,其實這只是TensorFlow的一個基本的功能届囚,就是支持在線數(shù)據(jù)不斷優(yōu)化模型有梆。TensorFlow可以通過tf.train.Saver()來保存模型和恢復(fù)模型參數(shù)泥耀,使用Python加載模型文件后,可不斷接受在線請求的數(shù)據(jù)夸溶,更新模型參數(shù)后通過Saver保存成checkpoint,用于下一次優(yōu)化或者線上服務(wù)足绅。

# Create Session to run graph
with tf.Session() as sess:
    summary_op = tf.merge_all_summaries()
    write = tf.train.SummaryWriter(tensorboard_dir, sess.graph)
    sess.run(init_op)
    sess.run(tf.initialize_local_variables())
    
    if mode == "train" or mode == "train_from_scratch":
        if mode != "train_from_scratch":
            ckpt = tf.train.get_checkpoint_state(checkpoint_dir)
            if ckpt and ckpt.model_checkpoint_path:
                print("Continue training from the model {}".format(ckpt.model_checkpoint_path))
                saver.restore(sess, ckpt.model_checkpoint_path)

而Continuous training是指訓(xùn)練即使被中斷捷绑,也能繼續(xù)上一次的訓(xùn)練結(jié)果繼續(xù)優(yōu)化模型,在TensorFlow中也是通過Saver和checkpoint文件來實現(xiàn)氢妈。在deep_recommend_system項目默認能從上一次訓(xùn)練中繼續(xù)優(yōu)化模型粹污,也可以在命令行中指定train_from_scratch,不僅不用擔心訓(xùn)練進程被中斷首量,也可以一邊訓(xùn)練一邊做inference提供線上服務(wù)壮吩。

6. 使用TensorFlow優(yōu)化參數(shù)

TensorFlow還集成了一個功能強大的圖形化工具,也即是TensorBoard,一般只需要在代碼中加入我們關(guān)心的訓(xùn)練指標粥航,TensorBoard就會自動根據(jù)這些參數(shù)繪圖琅捏,通過可視化的方式來了解模型訓(xùn)練的情況。

tf.scalar_summary(‘loss’, loss)
tf.scalar_summary(‘a(chǎn)ccuracy’, accuracy)
tf.scalar_summary(‘a(chǎn)uc’, auc_op)
image.png

7. 分布式TensorFlow應(yīng)用

最后不得不介紹TensorFlow強大的分布式計算功能递雀,傳統(tǒng)的計算框架如Caffe柄延,原生不支持分布式訓(xùn)練,在數(shù)據(jù)量巨大的情況下往往無法通過增加機器scale out缀程。TensorFlow承載了Google各個業(yè)務(wù)PB級的數(shù)據(jù)搜吧,在設(shè)計之初就考慮到分布式計算的需求,通過gRPC杨凑、Protobuf等高性能庫實現(xiàn)了神經(jīng)網(wǎng)絡(luò)模型的分布式計算滤奈。

實現(xiàn)分布式TensorFlow應(yīng)用并不難,構(gòu)建Graph代碼與單機版相同撩满,我們實現(xiàn)了一個分布式的cancer_classifier.py例子蜒程,通過下面的命令就可以啟動多ps多worker的訓(xùn)練集群。

cancer_classifier.py --ps_hosts=127.0.0.1:2222,127.0.0.1:2223 --worker_hosts=127.0.0.1:2224,127.0.0.1:2225 --job_name=ps --task_index=0
 
cancer_classifier.py --ps_hosts=127.0.0.1:2222,127.0.0.1:2223 --worker_hosts=127.0.0.1:2224,127.0.0.1:2225 --job_name=ps --task_index=1
 
cancer_classifier.py --ps_hosts=127.0.0.1:2222,127.0.0.1:2223 --worker_hosts=127.0.0.1:2224,127.0.0.1:2225 --job_name=worker --task_index=0
 
cancer_classifier.py --ps_hosts=127.0.0.1:2222,127.0.0.1:2223 --worker_hosts=127.0.0.1:2224,127.0.0.1:2225 --job_name=worker --task_index=1

在深入閱讀代碼前伺帘,我們需要了解分布式TensorFlow中ps昭躺、worker、in-graph伪嫁、between-graph领炫、synchronous training和asynchronous training的概念。首先ps是整個訓(xùn)練集群的參數(shù)服務(wù)器张咳,保存模型的Variable帝洪,worker是計算模型梯度的節(jié)點,得到的梯度向量會交付給ps更新模型脚猾。in-graph與between-graph對應(yīng)葱峡,但兩者都可以實現(xiàn)同步訓(xùn)練和異步訓(xùn)練,in-graph指整個集群由一個client來構(gòu)建graph婚陪,并且由這個client來提交graph到集群中族沃,其他worker只負責處理梯度計算的任務(wù),而between-graph指的是一個集群中多個worker可以創(chuàng)建多個graph泌参,但由于worker運行的代碼相同因此構(gòu)建的graph也相同脆淹,并且參數(shù)都保存到相同的ps中保證訓(xùn)練同一個模型,這樣多個worker都可以構(gòu)建graph和讀取訓(xùn)練數(shù)據(jù)沽一,適合大數(shù)據(jù)場景盖溺。同步訓(xùn)練和異步訓(xùn)練差異在于,同步訓(xùn)練每次更新梯度需要阻塞等待所有worker的結(jié)果铣缠,而異步訓(xùn)練不會有阻塞烘嘱,訓(xùn)練的效率更高昆禽,在大數(shù)據(jù)和分布式的場景下一般使用異步訓(xùn)練。

8. Cloud Machine Learning

前面已經(jīng)介紹了TensorFlow相關(guān)的全部內(nèi)容蝇庭,細心的網(wǎng)友可能已經(jīng)發(fā)現(xiàn)醉鳖,TensorFlow功能強大,但究其本質(zhì)還是一個library哮内,用戶除了編寫TensorFlow應(yīng)用代碼還需要在物理機上起服務(wù)盗棵,并且手動指定訓(xùn)練數(shù)據(jù)和模型文件的目錄,維護成本比較大北发,而且機器之間不可共享纹因。

縱觀大數(shù)據(jù)處理和資源調(diào)度行業(yè),Hadoop生態(tài)儼然成為了業(yè)界的標準琳拨,通過MapReduce或Spark接口來處理數(shù)據(jù)瞭恰,用戶通過API提交任務(wù)后由Yarn進行統(tǒng)一的資源分配和調(diào)度,不僅讓分布式計算成為可能狱庇,也通過資源共享和統(tǒng)一調(diào)度平的臺極大地提高了服務(wù)器的利用率惊畏。很遺憾TensorFlow定義是深度學習框架,并不包含集群資源管理等功能僵井,但開源TensorFlow以后陕截,Google很快公布了Google Cloud ML服務(wù)驳棱,我們從Alpha版本開始已經(jīng)是Cloud ML的早期用戶批什,深深體會到云端訓(xùn)練深度學習的便利性。通過Google Cloud ML服務(wù)社搅,我們可以把TensorFlow應(yīng)用代碼直接提交到云端運行驻债,甚至可以把訓(xùn)練好的模型直接部署在云上,通過API就可以直接訪問形葬,也得益于TensorFlow良好的設(shè)計合呐,我們基于Kubernetes和TensorFlow serving實現(xiàn)了Cloud Machine Learning服務(wù),架構(gòu)設(shè)計和使用接口都與Google Cloud ML類似笙以。

image.png

TensorFlow是很好深度學習框架淌实,對于個人開發(fā)者、科研人員已經(jīng)企業(yè)都是值得投資的技術(shù)方向猖腕,而Cloud Machine Learning可以解決用戶在環(huán)境初始化拆祈、訓(xùn)練任務(wù)管理以及神經(jīng)網(wǎng)絡(luò)模型的在線服務(wù)上的管理和調(diào)度問題。目前Google Cloud ML已經(jīng)支持automatically hyperparameter tunning倘感,參數(shù)調(diào)優(yōu)未來也將成為計算問題而不是技術(shù)問題放坏,即使有的開發(fā)者使用MXNet或者其他,而不是TensorFlow老玛,我們也愿意與更多深度學習用戶和平臺開發(fā)者交流淤年,促進社區(qū)的發(fā)展钧敞。

總結(jié)

總結(jié)一下,本文主要介紹TensorFlow深度學習框架的學習與應(yīng)用麸粮,通過deep_recommend_system項目介紹了下面使用TensorFlow的8個核心要點溉苛,也歡迎大家下載源碼試用和反饋。

  1. 準備訓(xùn)練數(shù)據(jù)

  2. 接受命令行參數(shù)

  3. 定義神經(jīng)網(wǎng)絡(luò)模型

  4. 使用不同的優(yōu)化算法

  5. Online learning與Continuous learning

  6. 使用TensorBoard優(yōu)化參數(shù)

  7. 分布式TensorFlow應(yīng)用

  8. Cloud Machine Learning

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末弄诲,一起剝皮案震驚了整個濱河市炊昆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌威根,老刑警劉巖凤巨,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異洛搀,居然都是意外死亡敢茁,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進店門留美,熙熙樓的掌柜王于貴愁眉苦臉地迎上來彰檬,“玉大人,你說我怎么就攤上這事谎砾》瓯叮” “怎么了?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵景图,是天一觀的道長较雕。 經(jīng)常有香客問我,道長挚币,這世上最難降的妖魔是什么亮蒋? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮妆毕,結(jié)果婚禮上慎玖,老公的妹妹穿的比我還像新娘。我一直安慰自己笛粘,他們只是感情好趁怔,可當我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著薪前,像睡著了一般润努。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上序六,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天任连,我揣著相機與錄音,去河邊找鬼例诀。 笑死随抠,一個胖子當著我的面吹牛裁着,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播拱她,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼二驰,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了秉沼?” 一聲冷哼從身側(cè)響起桶雀,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎唬复,沒想到半個月后矗积,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡敞咧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年棘捣,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片休建。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡乍恐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出测砂,到底是詐尸還是另有隱情茵烈,我是刑警寧澤,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布砌些,位于F島的核電站呜投,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏寄症。R本人自食惡果不足惜宙彪,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望有巧。 院中可真熱鬧,春花似錦悲没、人聲如沸篮迎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽甜橱。三九已至,卻和暖如春栈戳,著一層夾襖步出監(jiān)牢的瞬間岂傲,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工子檀, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留镊掖,地道東北人乃戈。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像亩进,于是被迫代替她去往敵國和親症虑。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內(nèi)容