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入门教程
Feb 08 Python
浅谈python字符串方法的简单使用
Jul 18 Python
Python 中的with关键字使用详解
Sep 11 Python
python用模块zlib压缩与解压字符串和文件的方法
Dec 16 Python
Python 使用with上下文实现计时功能
Mar 09 Python
python使用Matplotlib画条形图
Mar 25 Python
基于python生成器封装的协程类
Mar 20 Python
Python制作微信好友背景墙教程(附完整代码)
Jul 17 Python
python二分法查找算法实现方法【递归与非递归】
Dec 06 Python
python输出数组中指定元素的所有索引示例
Dec 06 Python
python构造函数init实例方法解析
Jan 19 Python
python如何提升爬虫效率
Sep 27 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中unlink()、mkdir()、rmdir()等方法的使用介绍
2012/12/21 PHP
PHP输出时间差函数代码
2013/01/28 PHP
深入分析使用mysql_fetch_object()以对象的形式返回查询结果
2013/06/05 PHP
PHP读取Excel内的图片(phpspreadsheet和PHPExcel扩展库)
2019/11/19 PHP
javascript事件函数中获得事件源的两种不错方法
2014/03/17 Javascript
javascript 获取HTML DOM父、子、临近节点
2014/06/16 Javascript
JavaScript 开发工具webstrom使用指南
2014/12/09 Javascript
node.js中的fs.fsyncSync方法使用说明
2014/12/15 Javascript
JQuery记住用户名密码实现下次自动登录功能
2015/04/27 Javascript
jQuery同步提交示例代码
2015/12/12 Javascript
javascript实现label标签跳出循环操作
2016/03/06 Javascript
去除html代码里面的script正则方法
2016/05/19 Javascript
React快速入门教程
2017/01/17 Javascript
javascript 删除数组元素和清空数组的简单方法
2017/02/24 Javascript
JavaScript 函数的定义-调用、注意事项
2017/04/16 Javascript
js分页之前端代码实现和请求处理
2017/08/04 Javascript
weebox弹出窗口不居中显示的解决方法
2017/11/27 Javascript
修改node.js默认的npm安装目录实例
2018/05/15 Javascript
vue获取元素宽、高、距离左边距离,右,上距离等还有XY坐标轴的方法
2018/09/05 Javascript
vue接入腾讯防水墙代码
2019/05/07 Javascript
JS中getElementsByClassName与classList兼容性问题解决方案分析
2019/08/07 Javascript
微信小程序嵌入腾讯视频源过程详解
2019/08/08 Javascript
[01:14]DOTA2亚洲邀请赛 ShowOpen
2015/02/07 DOTA
深入浅析python继承问题
2016/05/29 Python
树莓派安装OpenCV3完整过程的实现
2019/10/10 Python
python微信公众号开发简单流程实现
2020/03/09 Python
在django中使用post方法时,需要增加csrftoken的例子
2020/03/13 Python
HTML5开发动态音频图的实现
2020/07/02 HTML / CSS
.NET现在共支持多少种语言
2014/02/26 面试题
什么是lambda函数
2013/09/17 面试题
美德少年事迹材料
2014/01/23 职场文书
纪律教育学习月活动总结
2014/08/27 职场文书
文秘班元旦晚会活动策划方案
2014/08/28 职场文书
组工干部演讲稿
2014/09/02 职场文书
幼儿园教师自我评价
2015/03/04 职场文书
2017年大学生寒假社会实践活动总结
2016/04/06 职场文书