Tensorflow实现多GPU并行方式


Posted in Python onFebruary 03, 2020

Tebsorflow开源实现多GPU训练cifar10数据集:cifar10_multi_gpu_train.py

Tensorflow开源实现cifar10神经网络:cifar10.py

Tensorflow中的并行分为模型并行和数据并行。模型并行需要根据不同模型设计不同的并行方式,其主要原理是将模型中不同计算节点放在不同硬件资源上运算。比较通用且能简便地实现大规模并行的方式是数据并行,同时使用多个硬件资源来计算不同batch的数据梯度,然后汇总梯度进行全局更新。

数据并行几乎适用于所有深度学习模型,总是可以利用多块GPU同时训练多个batch数据,运行在每块GPU上的模型都基于同一个神经网络,网络结构一样,并且共享模型参数。

import os
import re
import time
import numpy as np
import tensorflow as tf
import cifar10_input
import cifar10

batch_size = 128
max_steps = 1000
num_gpus = 1 # gpu数量


# 在scope下生成神经网络并返回scope下的loss
def tower_loss(scope):
 # 数据集的路径可以在cifar10.py中的tf.app.flags.DEFINE_string中定义
 images, labels = cifar10.distorted_inputs()
 logits = cifar10.inference(images) # 生成神经网络
 _ = cifar10.loss(logits, labels) # 不直接返回loss而是放到collection
 losses = tf.get_collection('losses', scope) # 获取当前GPU上的loss(通过scope限定范围)
 total_loss = tf.add_n(losses, name='total_loss')
 return total_loss


'''
外层是不同GPU计算的梯度,内层是某个GPU对应的不同var的值
tower_grads = 
[[(grad0_gpu0, var0_gpu0), (grad1_gpu0, var1_gpu0),...],
 [(grad0_gpu1, var0_gpu1), (grad1_gpu1, var1_gpu1),...]]
zip(*tower_grads)= 相当于转置了
[[(grad0_gpu0, var0_gpu0), (grad0_gpu1, var0, gpu1),...],
 [(grad1_gpu0, var1_gpu0), (grad1_gpu1, var1_gpu1),...]]
'''


def average_gradients(tower_grads):
 average_grads = []
 for grad_and_vars in zip(*tower_grads):
  grads = [tf.expand_dims(g, 0) for g, _ in grad_and_vars]
  grads = tf.concat(grads, 0)
  grad = tf.reduce_mean(grads, 0)
  grad_and_var = (grad, grad_and_vars[0][1])
  # [(grad0, var0),(grad1, var1),...]
  average_grads.append(grad_and_var)
 return average_grads


def train():
 # 默认的计算设备为CPU
 with tf.Graph().as_default(), tf.device('/cpu:0'):
  # []表示没有维度,为一个数
  # trainable=False,不会加入GraphKeys.TRAINABLE_VARIABLES参与训练
  global_step = tf.get_variable('global_step', [],
          initializer=tf.constant_initializer(0),
          trainable=False)
  num_batches_per_epoch = cifar10.NUM_EXAMPLES_PER_EPOCH_FOR_TRAIN / batch_size
  decay_steps = int(num_batches_per_epoch * cifar10.NUM_EPOCHS_PER_DECAY)
  # https://tensorflow.google.cn/api_docs/python/tf/train/exponential_decay
  # decayed_learning_rate = learning_rate * decay_rate ^ (global_step / decay_steps)
  # staircase is True, then global_step / decay_steps is an integer division
  lr = tf.train.exponential_decay(cifar10.INITIAL_LEARNING_RATE,
          global_step,
          decay_steps,
          cifar10.LEARNING_RATE_DECAY_FACTOR,
          staircase=True)
  opt = tf.train.GradientDescentOptimizer(lr)

  tower_grads = []
  for i in range(num_gpus):
   with tf.device('/gpu:%d' % i):
    with tf.name_scope('%s_%d' % (cifar10.TOWER_NAME, i)) as scope:
     loss = tower_loss(scope)
     # 让神经网络的变量可以重用,所有GPU使用完全相同的参数
     # 让下一个tower重用参数
     tf.get_variable_scope().reuse_variables()
     grads = opt.compute_gradients(loss)
     tower_grads.append(grads)
  grads = average_gradients(tower_grads)
  apply_gradient_op = opt.apply_gradients(grads, global_step=global_step)

  init = tf.global_variables_initializer()
  # True会自动选择一个存在并且支持的设备来运行
  sess = tf.Session(config=tf.ConfigProto(allow_soft_placement=True))
  sess.run(init)
  tf.train.start_queue_runners(sess=sess)

  for step in range(max_steps):
   start_time = time.time()
   _, loss_value = sess.run([apply_gradient_op, loss])
   duration = time.time() - start_time

   if step % 10 == 0:
    num_examples_per_step = batch_size * num_gpus
    examples_per_sec = num_examples_per_step / duration
    sec_per_batch = duration / num_gpus

    print('step %d, loss=%.2f(%.1f examples/sec;%.3f sec/batch)'
      % (step, loss_value, examples_per_sec, sec_per_batch))



if __name__ == '__main__':
 train()

以上这篇Tensorflow实现多GPU并行方式就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python 打印对象的所有属性值的方法
Sep 11 Python
Python封装原理与实现方法详解
Aug 28 Python
pandas使用apply多列生成一列数据的实例
Nov 28 Python
解决Python3下map函数的显示问题
Dec 04 Python
python把一个字符串切开的实例方法
Sep 27 Python
详解anaconda安装步骤
Nov 23 Python
python 自定义异常和主动抛出异常(raise)的操作
Dec 11 Python
python实现双人五子棋(终端版)
Dec 30 Python
Python实现Appium端口检测与释放的实现
Dec 31 Python
Jupyter notebook 不自动弹出网页的解决方案
May 21 Python
Python 实现Mac 屏幕截图详解
Oct 05 Python
Pandas-DataFrame知识点汇总
Mar 16 Python
python如何通过twisted搭建socket服务
Feb 03 #Python
关于Tensorflow分布式并行策略
Feb 03 #Python
基于python修改srt字幕的时间轴
Feb 03 #Python
Python实现不规则图形填充的思路
Feb 02 #Python
Python ORM编程基础示例
Feb 02 #Python
Python 面向对象之类class和对象基本用法示例
Feb 02 #Python
flask 框架操作MySQL数据库简单示例
Feb 02 #Python
You might like
php中支持多种编码的中文字符串截取函数!
2007/03/20 PHP
php 多个submit提交表单 处理方法
2009/07/07 PHP
PHP 图片上传实现代码 带详细注释
2010/04/29 PHP
PHP批量检测并去除文件BOM头代码实例
2014/05/08 PHP
对采用动态原型方式无法展示继承机制得思考
2009/12/04 Javascript
js 金额文本框实现代码
2012/02/14 Javascript
ExtJS下 Ext.Direct加载和提交过程排错小结
2013/04/02 Javascript
js实现的类似于asp数据字典的数据类型代码实例
2014/09/03 Javascript
果断收藏9个Javascript代码高亮脚本
2016/01/06 Javascript
AngularJS 中的指令实践开发指南(一)
2016/03/20 Javascript
微信小程序 常用工具类详解及实例
2017/02/15 Javascript
Express下采用bcryptjs进行密码加密的方法
2018/02/07 Javascript
浅谈vue父子组件怎么传值
2018/07/21 Javascript
vue-cli项目使用mock数据的方法(借助express)
2019/04/15 Javascript
深入浅析vue中cross-env的使用
2019/09/12 Javascript
利用Python绘制数据的瀑布图的教程
2015/04/07 Python
Python中的下划线详解
2015/06/24 Python
详解python3百度指数抓取实例
2016/12/12 Python
PyQt4编程之让状态栏显示信息的方法
2019/06/18 Python
python在openstreetmap地图上绘制路线图的实现
2019/07/11 Python
python动态文本进度条的实例代码
2020/01/22 Python
Python类中self参数用法详解
2020/02/13 Python
德国前卫设计师时装在线商店:Luxury Loft
2019/11/04 全球购物
.NET面试题:什么是反射
2016/09/30 面试题
介绍下static、final、abstract区别
2015/01/30 面试题
工程管理造价应届生求职信
2013/11/13 职场文书
大学生创业策划书
2014/02/02 职场文书
致400米运动员广播稿
2014/02/07 职场文书
毕业生就业意向书
2014/04/01 职场文书
补充协议书范本
2014/04/23 职场文书
医院信息公开实施方案
2014/05/09 职场文书
2015年七一建党节活动总结
2015/03/20 职场文书
化妆品促销活动总结
2015/05/07 职场文书
教师节座谈会主持词
2015/07/03 职场文书
2019奶茶店创业计划书范本!
2019/07/15 职场文书
解决mysql:ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO/YES)
2021/06/26 MySQL