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中声明只包含一个元素的元组数据方法
Aug 25 Python
Python遍历目录的4种方法实例介绍
Apr 13 Python
python转换字符串为摩尔斯电码的方法
Jul 06 Python
Django项目中包含多个应用时对url的配置方法
May 30 Python
Python读取excel中的图片完美解决方法
Jul 27 Python
python生成以及打开json、csv和txt文件的实例
Nov 16 Python
PyQt5 实现字体大小自适应分辨率的方法
Jun 18 Python
python全栈知识点总结
Jul 01 Python
Python大数据之网络爬虫的post请求、get请求区别实例分析
Nov 16 Python
pandas factorize实现将字符串特征转化为数字特征
Dec 19 Python
python3 使用traceback定位异常实例
Mar 09 Python
python脚本使用阿里云slb对恶意攻击进行封堵的实现
Feb 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
php5 图片验证码实现代码
2009/12/11 PHP
无法载入 mcrypt 扩展,请检查 PHP 配置终极解决方案
2011/07/18 PHP
php Xdebug的安装与使用详解
2013/06/20 PHP
如何使用PHP获取指定日期所在月的开始日期与结束日期
2013/08/01 PHP
简单谈谈PHP vs Node.js
2015/07/17 PHP
PHP进行批量任务处理不超时的解决方法
2016/07/11 PHP
PHP的RSA加密解密方法以及开发接口使用
2018/02/11 PHP
PHP设计模式之适配器模式原理与用法分析
2018/04/25 PHP
Javascript常考语句107条收集
2010/03/09 Javascript
jquery事件机制扩展插件 jquery鼠标右键事件。
2011/12/26 Javascript
javascript针对DOM的应用分析(二)
2012/04/15 Javascript
JavaScript分析、压缩工具JavaScript Analyser
2014/12/31 Javascript
js实现a标签超链接提交form表单的方法
2015/06/24 Javascript
Java  Spring 事务回滚详解
2016/10/17 Javascript
jQuery 全选 全不选 事件绑定的实现代码
2017/01/23 Javascript
Javascript中数组去重与拍平的方法示例
2017/02/03 Javascript
Ionic项目中Native Camera的使用方法
2017/06/07 Javascript
基于vue中css预加载使用sass的配置方式详解
2018/03/13 Javascript
修改vue+webpack run build的路径方法
2018/09/01 Javascript
nodejs中函数的调用实例详解
2018/10/31 NodeJs
跟老齐学Python之有容乃大的list(4)
2014/09/28 Python
Python的collections模块中的OrderedDict有序字典
2016/07/07 Python
python实现随机梯度下降法
2020/03/24 Python
解决python3.5 正常安装 却不能直接使用Tkinter包的问题
2019/02/22 Python
公司办公室岗位职责
2014/03/19 职场文书
本科毕业生求职自荐信
2014/04/09 职场文书
基层党员公开承诺书
2014/05/29 职场文书
环境卫生标语
2014/06/09 职场文书
政风行风自查自纠报告
2014/10/21 职场文书
2015毕业寄语大全
2015/02/26 职场文书
2015年度公共机构节能工作总结
2015/05/26 职场文书
千与千寻观后感
2015/06/04 职场文书
2016年优秀少先队辅导员事迹材料
2016/02/26 职场文书
go 实现简易端口扫描的示例
2021/05/22 Golang
浅析Python中的套接字编程
2021/06/22 Python
奥特曼十大神器:奥特手镯在榜,第一是贝利亚的神器
2022/03/18 日漫