首先,TensorFlow并行計算分為:模型并行,數(shù)據(jù)并行。
模型并行:根據(jù)不同模型設計不同并行方式,模型不同計算節(jié)點放在不同GPU或者機器上進行計算。
數(shù)據(jù)并行是比較通用簡便的實現(xiàn)大規(guī)模并行方式,同時使用多個硬件資源計算不同batch數(shù)據(jù)梯度,匯總梯度進行全局參數(shù)更新。
數(shù)據(jù)并行:多塊GPU同時訓練多個batch數(shù)據(jù),運行在每塊GPU模型基于同一神經(jīng)網(wǎng)絡,網(wǎng)絡結構一樣,共享模型參數(shù)。
1.同步數(shù)據(jù)并行,所有GPU計算完batch數(shù)據(jù)梯度,統(tǒng)計將多個梯度合在一起,更新共享模型參數(shù),類似使用較大batch。GPU型號、速度一致時,效率最高。
數(shù)據(jù)同步并行
2.異步數(shù)據(jù)并行,不等待所有GPU完成一次訓練,哪個GPU完成訓練,立即將梯度更新到共享模型參數(shù)。
數(shù)據(jù)異步并行
同步數(shù)據(jù)并行,比異步收斂速度更快,模型精度更高。
同步數(shù)據(jù)并行,數(shù)據(jù)集CIFAR-10。載入依賴庫,TensorFlow Models cifar10類,下載CIFAR-10數(shù)據(jù)預處理。設置batch大小 128,最大步數(shù)100萬步(中間隨時停止,模型定期保存),GPU數(shù)量4。
定義計算損失函數(shù)tower_loss。cifar10.distorted_inputs產(chǎn)生數(shù)據(jù)增強images、labels,調(diào)用cifar10.inference生成卷積網(wǎng)絡,每個GPU生成單獨網(wǎng)絡,結構一致,共享模型參數(shù)。根據(jù)卷積網(wǎng)絡、labels,調(diào)用cifar10.loss計算損失函數(shù)(loss儲存到collection),tf.get_collection('losses',scope)獲取當前GPU loss(scope限定范圍),tf.add_n 所有損失疊加一起得total_loss。返回total_loss作函數(shù)結果。
定義函數(shù)average_gradients,不同GPU計算梯度合成。輸入?yún)?shù)tower_grads梯度雙層列表,外層列表不同GPU計算梯度,內(nèi)層列表GPU計算不同Variable梯度。最內(nèi)層元素(grads,variable),tower_grads基本元素二元組(梯度、變量),具體形式[[(grad0_gpu0,var0_gpu0),(grad1_gpu0,var1_gpu0)……],[(grad0_gpu1,var0_gpu1),(grad1_gpu1,var1_gpu1)……]……]。創(chuàng)建平均梯度列表average_grads,梯度在不同GPU平均。zip(*tower_grads)雙層列表轉置,變[[(grad0_gpu0,var0_gpu0),(grad0_gpu1,var0_gpu1)……],[(grad1_gpu0,var1_gpu0),(grad1_gpu1,var1_gpu1)……]……]形式,循環(huán)遍歷元素。循環(huán)獲取元素grad_and_vars,同Variable梯度在不同GPU計算結果。同Variable梯度不同GPU計算副本,計算梯度均值。梯度N維向量,每個維度平均。tf.expand_dims給梯度添加冗余維度0,梯度放列表grad。tf.concat 維度0上合并。tf.reduce_mean維度0平均,其他維度全部平均。平均梯度,和Variable組合得原有二元組(梯度、變量)格式,添加到列表average_grads。所有梯度求均后,返回average_grads。
定義訓練函數(shù)。設置默認計算設備CPU。global_step記錄全局訓練步數(shù),計算epoch對應batch數(shù),學習速率衰減需要步數(shù)decay_steps。tf.train.exponential_decay創(chuàng)建隨訓練步數(shù)衰減學習速率,第一參數(shù)初始學習速率,第二參數(shù)全局訓練步數(shù),第三參數(shù)每次衰減需要步數(shù),第四參數(shù)衰減率,staircase設true,階梯式衰減。設置優(yōu)化算法GradientDescent,傳入隨機步數(shù)衰減學習速率。
定義儲存GPU計算結果列表tower_grads。創(chuàng)建循環(huán),循環(huán)次數(shù)GPU數(shù)量。循環(huán)中tf.device限定使用哪個GPU。tf.name_scope命名空間。
GPU用tower_loss獲取損失。tf.get_variable_scope().reuse_variables()重用參數(shù)。GPU共用一個模型入完全相同參數(shù)。opt.compute_gradients(loss)計算單個GPU梯度,添加到梯度列表tower_grads。average_gradients計算平均梯度,opt.apply_gradients更新模型參數(shù)。
創(chuàng)建模型保存器saver,Session allow_soft_placement 參數(shù)設True。有些操作只能在CPU上進行,不使用soft_placement。初始化全部參數(shù),tf.train.start_queue_runner()準備大量數(shù)據(jù)增強訓練樣本,防止訓練被阻塞在生成樣本。
訓練循環(huán),最大迭代次數(shù)max_steps。每步執(zhí)行一次更新梯度操作apply_gradient_op(一次訓練操作),計算損失操作loss。time.time()記錄耗時。每隔10步,展示當前batch loss。每秒鐘可訓練樣本數(shù)和每個batch訓練花費時間。每隔1000步,Saver保存整個模型文件。
cifar10.maybe_download_and_extract()下載完整CIFAR-10數(shù)據(jù),train()開始訓練。
loss從最開始4點幾,到第70萬步,降到0.07。平均每個batch耗時0.021s,平均每秒訓練6000個樣本,單GPU 4倍。

