作者: 陳迪豪困鸥,就職小米科技嗅蔬,深度學習工程師,TensorFlow代碼提交者疾就。
TensorFlow深度學習框架
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)
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類似笙以。
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個核心要點溉苛,也歡迎大家下載源碼試用和反饋。
準備訓(xùn)練數(shù)據(jù)
接受命令行參數(shù)
定義神經(jīng)網(wǎng)絡(luò)模型
使用不同的優(yōu)化算法
Online learning與Continuous learning
使用TensorBoard優(yōu)化參數(shù)
分布式TensorFlow應(yīng)用
Cloud Machine Learning