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 Web框架Flask中使用新浪SAE云存储实例
Feb 08 Python
python正则表达式爬取猫眼电影top100
Feb 24 Python
Python对象属性自动更新操作示例
Jun 15 Python
TensorFlow 模型载入方法汇总(小结)
Jun 19 Python
Python设计模式之抽象工厂模式原理与用法详解
Jan 15 Python
django foreignkey(外键)的实现
Jul 29 Python
python 实现让字典的value 成为列表
Dec 16 Python
python 实现保存最新的三份文件,其余的都删掉
Dec 22 Python
python使用配置文件过程详解
Dec 28 Python
python实现飞机大战项目
Mar 11 Python
python 实现仿微信聊天时间格式化显示的代码
Apr 17 Python
Anaconda安装pytorch及配置PyCharm 2021环境
Jun 04 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设计模式之工厂模式定义与用法详解
2018/04/03 PHP
Prototype1.5 rc2版指南最后一篇之Position
2007/01/10 Javascript
javascript Onunload与Onbeforeunload使用小结
2009/12/31 Javascript
HTML长文本截取含有HTML代码同样适用的两种方法
2013/07/31 Javascript
jquery 使用简明教程
2014/03/05 Javascript
JavaScript实现twitter puddles算法实例
2014/12/06 Javascript
js实现跨域的多种方法
2015/12/25 Javascript
常用Javascript函数与原型功能收藏(必看篇)
2016/10/09 Javascript
使用vue.js编写蓝色拼图小游戏
2017/03/17 Javascript
ES6新特性之变量和字符串用法示例
2017/04/01 Javascript
Vue实现百度下拉提示搜索功能
2017/06/21 Javascript
JS原生数据双向绑定实现代码
2017/08/14 Javascript
浅谈Postman解决token传参的问题
2018/03/31 Javascript
layui的layedit富文本赋值方法
2019/09/18 Javascript
layui table单元格事件修改值的方法
2019/09/24 Javascript
javaScript 实现重复输出给定的字符串的常用方法小结
2020/02/20 Javascript
js实现滚动条自动滚动
2020/12/13 Javascript
使用Python简单的实现树莓派的WEB控制
2016/02/18 Python
详解使用python crontab设置linux定时任务
2016/12/08 Python
python3实现UDP协议的服务器和客户端
2017/06/14 Python
python中Matplotlib实现绘制3D图的示例代码
2017/09/04 Python
python 列表,数组,矩阵两两转换tolist()的实例
2018/04/04 Python
spark: RDD与DataFrame之间的相互转换方法
2018/06/07 Python
python实现自动登录
2018/09/17 Python
Python opencv实现人眼/人脸识别以及实时打码处理
2019/04/29 Python
Python通过2种方法输出带颜色字体
2020/03/02 Python
python torch.utils.data.DataLoader使用方法
2020/04/02 Python
详解python os.path.exists判断文件或文件夹是否存在
2020/11/16 Python
Python try except else使用详解
2021/01/12 Python
html5与css3小应用
2013/04/03 HTML / CSS
HTML5 audio标签使用js进行播放控制实例
2015/04/24 HTML / CSS
Alba Moda德国网上商店:意大利时尚女装销售
2016/11/14 全球购物
Scholastic父母商店:儿童书籍
2017/01/01 全球购物
char型变量中能不能存贮一个中文汉字
2015/07/08 面试题
2015年库房工作总结
2015/04/30 职场文书
世界十大动漫制作公司排行榜,迪士尼上榜,第二是美国代表性文化符
2022/03/18 欧美动漫