精华内容
下载资源
问答
  • 一张是gtx titan x 一张是老旧的gt640 通过运行cuda程序发现时间相差8倍。 想通过硬件参数来比较其计算能力 或者应该如何确定8倍的时间已经是用上了所有的显卡算力, GPU利用率?什么的 有没有人给我点意见,谢谢
  • 而这篇文章我们着重讲解如何利用Pytorch深度学习框架的一些特性,去查看我们当前使用的变量所占用的显存大小,以及一些优化工作。以下代码所使用的平台框架为Pytorch。优化显存在Pytorch中优化显存是我们处理大量...

    前言

    在上篇文章《浅谈深度学习:如何计算模型以及中间变量的显存占用大小》中我们对如何计算各种变量所占显存大小进行了一些探索。而这篇文章我们着重讲解如何利用Pytorch深度学习框架的一些特性,去查看我们当前使用的变量所占用的显存大小,以及一些优化工作。以下代码所使用的平台框架为Pytorch。

    优化显存

    在Pytorch中优化显存是我们处理大量数据时必要的做法,因为我们并不可能拥有无限的显存。显存是有限的,而数据是无限的,我们只有优化显存的使用量才能够最大化地利用我们的数据,实现多种多样的算法。

    估测模型所占的内存

    上篇文章中说过,一个模型所占的显存无非是这两种:

    模型权重参数

    模型所储存的中间变量

    其实权重参数一般来说并不会占用很多的显存空间,主要占用显存空间的还是计算时产生的中间变量,当我们定义了一个model之后,我们可以通过以下代码简单计算出这个模型权重参数所占用的数据量:

    import numpy as np

    # model是我们在pytorch定义的神经网络层

    # model.parameters()取出这个model所有的权重参数

    para = sum([np.prod(list(p.size())) for p in model.parameters()])

    假设我们有这样一个model:

    Sequential(

    (conv_1): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))

    (relu_1): ReLU(inplace)

    (conv_2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))

    (relu_2): ReLU(inplace)

    (pool_2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)

    (conv_3): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))

    )

    然后我们得到的para是112576,但是我们计算出来的仅仅是权重参数的“数量”,单位是B,我们需要转化一下:

    # 下面的type_size是4,因为我们的参数是float32也就是4B,4个字节

    print('Model {} : params: {:4f}M'.format(model._get_name(), para * type_size / 1000 / 1000))

    这样就可以打印出:

    Model Sequential : params: 0.450304M

    但是我们之前说过一个神经网络的模型,不仅仅有权重参数还要计算中间变量的大小。怎么去计算,我们可以假设一个输入变量,然后将这个输入变量投入这个模型中,然后我们主动提取这些计算出来的中间变量:

    # model是我们加载的模型

    # input是实际中投入的input(Tensor)变量

    # 利用clone()去复制一个input,这样不会对input造成影响

    input_ = input.clone()

    # 确保不需要计算梯度,因为我们的目的只是为了计算中间变量而已

    input_.requires_grad_(requires_grad=False)

    mods = list(model.modules())

    out_sizes = []

    for i in range(1, len(mods)):

    m = mods[i]

    # 注意这里,如果relu激活函数是inplace则不用计算

    if isinstance(m, nn.ReLU):

    if m.inplace:

    continue

    out = m(input_)

    out_sizes.append(np.array(out.size()))

    input_ = out

    total_nums = 0

    for i in range(len(out_sizes)):

    s = out_sizes[i]

    nums = np.prod(np.array(s))

    total_nums += nums

    上面得到的值是模型在运行时候产生所有的中间变量的“数量”,当然我们需要换算一下:

    # 打印两种,只有 forward 和 foreward、backward的情况

    print('Model {} : intermedite variables: {:3f} M (without backward)'

    .format(model._get_name(), total_nums * type_size / 1000 / 1000))

    print('Model {} : intermedite variables: {:3f} M (with backward)'

    .format(model._get_name(), total_nums * type_size*2 / 1000 / 1000))

    因为在backward的时候所有的中间变量需要保存下来再来进行计算,所以我们在计算backward的时候,计算出来的中间变量需要乘个2。

    然后我们得出,上面这个模型的中间变量需要的占用的显存,很显然,中间变量占用的值比模型本身的权重值多多了。如果进行一次backward那么需要的就更多。

    Model Sequential : intermedite variables: 336.089600 M (without backward)

    Model Sequential : intermedite variables: 672.179200 M (with backward)

    我们总结一下之前的代码:

    # 模型显存占用监测函数

    # model:输入的模型

    # input:实际中需要输入的Tensor变量

    # type_size 默认为 4 默认类型为 float32

    def modelsize(model, input, type_size=4):

    para = sum([np.prod(list(p.size())) for p in model.parameters()])

    print('Model {} : params: {:4f}M'.format(model._get_name(), para * type_size / 1000 / 1000))

    input_ = input.clone()

    input_.requires_grad_(requires_grad=False)

    mods = list(model.modules())

    out_sizes = []

    for i in range(1, len(mods)):

    m = mods[i]

    if isinstance(m, nn.ReLU):

    if m.inplace:

    continue

    out = m(input_)

    out_sizes.append(np.array(out.size()))

    input_ = out

    total_nums = 0

    for i in range(len(out_sizes)):

    s = out_sizes[i]

    nums = np.prod(np.array(s))

    total_nums += nums

    print('Model {} : intermedite variables: {:3f} M (without backward)'

    .format(model._get_name(), total_nums * type_size / 1000 / 1000))

    print('Model {} : intermedite variables: {:3f} M (with backward)'

    .format(model._get_name(), total_nums * type_size*2 / 1000 / 1000))

    当然我们计算出来的占用显存值仅仅是做参考作用,因为Pytorch在运行的时候需要额外的显存值开销,所以实际的显存会比我们计算的稍微大一些。

    关于inplace=False

    我们都知道激活函数Relu()有一个默认参数inplace,默认设置为False,当设置为True时,我们在通过relu()计算时的得到的新值不会占用新的空间而是直接覆盖原来的值,这也就是为什么当inplace参数设置为True时可以节省一部分内存的缘故。

    牺牲计算速度减少显存使用量

    在Pytorch-0.4.0出来了一个新的功能,可以将一个计算过程分成两半,也就是如果一个模型需要占用的显存太大了,我们就可以先计算一半,保存后一半需要的中间结果,然后再计算后一半。

    也就是说,新的checkpoint允许我们只存储反向传播所需要的部分内容。如果当中缺少一个输出(为了节省内存而导致的),checkpoint将会从最近的检查点重新计算中间输出,以便减少内存使用(当然计算时间增加了):

    # 输入

    input = torch.rand(1, 10)

    # 假设我们有一个非常深的网络

    layers = [nn.Linear(10, 10) for _ in range(1000)]

    model = nn.Sequential(*layers)

    output = model(input)

    上面的模型需要占用很多的内存,因为计算中会产生很多的中间变量。为此checkpoint就可以帮助我们来节省内存的占用了。

    # 首先设置输入的input=>requires_grad=True

    # 如果不设置可能会导致得到的gradient为0

    input = torch.rand(1, 10, requires_grad=True)

    layers = [nn.Linear(10, 10) for _ in range(1000)]

    # 定义要计算的层函数,可以看到我们定义了两个

    # 一个计算前500个层,另一个计算后500个层

    def run_first_half(*args):

    x = args[0]

    for layer in layers[:500]:

    x = layer(x)

    return x

    def run_second_half(*args):

    x = args[0]

    for layer in layers[500:-1]:

    x = layer(x)

    return x

    # 我们引入新加的checkpoint

    from torch.utils.checkpoint import checkpoint

    x = checkpoint(run_first_half, input)

    x = checkpoint(run_second_half, x)

    # 最后一层单独调出来执行

    x = layers[-1](x)

    x.sum.backward() # 这样就可以了

    对于Sequential-model来说,因为Sequential()中可以包含很多的block,所以官方提供了另一个功能包:

    input = torch.rand(1, 10, requires_grad=True)

    layers = [nn.Linear(10, 10) for _ in range(1000)]

    model = nn.Sequential(*layers)

    from torch.utils.checkpoint import checkpoint_sequential

    # 分成两个部分

    num_segments = 2

    x = checkpoint_sequential(model, num_segments, input)

    x.sum().backward() # 这样就可以了

    跟踪显存使用情况

    显存的使用情况,在编写程序中我们可能无法精确计算,但是我们可以通过pynvml这个Nvidia的Python环境库和Python的垃圾回收工具,可以实时地打印我们使用的显存以及哪些Tensor使用了我们的显存。

    类似于下面的报告:

    # 08-Jun-18-17:56:51-gpu_mem_prof

    At __main__ <module>: line 39 Total Used Memory:399.4 Mb

    At __main__ <module>: line 40 Total Used Memory:992.5 Mb

    + __main__ <module>: line 40 (1, 1, 682, 700) 1.82 M <class 'torch.Tensor'>

    + __main__ <module>: line 40 (1, 3, 682, 700) 5.46 M <class 'torch.Tensor'>

    At __main__ <module>: line 126 Total Used Memory:1088.5 Mb

    + __main__ <module>: line 126 (64, 64, 3, 3) 0.14 M <class 'torch.nn.parameter.Parameter'>

    + __main__ <module>: line 126 (128, 64, 3, 3) 0.28 M <class 'torch.nn.parameter.Parameter'>

    + __main__ <module>: line 126 (128, 128, 3, 3) 0.56 M <class 'torch.nn.parameter.Parameter'>

    + __main__ <module>: line 126 (64, 3, 3, 3) 0.00 M <class 'torch.nn.parameter.Parameter'>

    + __main__ <module>: line 126 (256, 256, 3, 3) 2.25 M <class 'torch.nn.parameter.Parameter'>

    + __main__ <module>: line 126 (512, 256, 3, 3) 4.5 M <class 'torch.nn.parameter.Parameter'>

    + __main__ <module>: line 126 (512, 512, 3, 3) 9.0 M <class 'torch.nn.parameter.Parameter'>

    + __main__ <module>: line 126 (64,) 0.00 M <class 'torch.nn.parameter.Parameter'>

    + __main__ <module>: line 126 (1, 3, 682, 700) 5.46 M <class 'torch.Tensor'>

    + __main__ <module>: line 126 (128,) 0.00 M <class 'torch.nn.parameter.Parameter'>

    + __main__ <module>: line 126 (256,) 0.00 M <class 'torch.nn.parameter.Parameter'>

    + __main__ <module>: line 126 (512,) 0.00 M <class 'torch.nn.parameter.Parameter'>

    + __main__ <module>: line 126 (3,) 1.14 M <class 'torch.Tensor'>

    + __main__ <module>: line 126 (256, 128, 3, 3) 1.12 M <class 'torch.nn.parameter.Parameter'>

    ...

    以下是相关的代码,目前代码依然有些地方需要修改,等修改完善好我会将完整代码以及使用说明放到github上:https://github.com/Oldpan/Pytorch-Memory-Utils

    请大家多多留意。

    import datetime

    import linecache

    import os

    import gc

    import pynvml

    import torch

    import numpy as np

    print_tensor_sizes = True

    last_tensor_sizes = set()

    gpu_profile_fn = f'{datetime.datetime.now():%d-%b-%y-%H:%M:%S}-gpu_mem_prof.txt'

    # if 'GPU_DEBUG' in os.environ:

    # print('profiling gpu usage to ', gpu_profile_fn)

    lineno = None

    func_name = None

    filename = None

    module_name = None

    # fram = inspect.currentframe()

    # func_name = fram.f_code.co_name

    # filename = fram.f_globals["__file__"]

    # ss = os.path.dirname(os.path.abspath(filename))

    # module_name = fram.f_globals["__name__"]

    def gpu_profile(frame, event):

    # it is _about to_ execute (!)

    global last_tensor_sizes

    global lineno, func_name, filename, module_name

    if event == 'line':

    try:

    # about _previous_ line (!)

    if lineno is not None:

    pynvml.nvmlInit()

    # handle = pynvml.nvmlDeviceGetHandleByIndex(int(os.environ['GPU_DEBUG']))

    handle = pynvml.nvmlDeviceGetHandleByIndex(0)

    meminfo = pynvml.nvmlDeviceGetMemoryInfo(handle)

    line = linecache.getline(filename, lineno)

    where_str = module_name+' '+func_name+':'+' line '+str(lineno)

    with open(gpu_profile_fn, 'a+') as f:

    f.write(f"At {where_str:<50}"

    f"Total Used Memory:{meminfo.used/1024**2:<7.1f}Mb\n")

    if print_tensor_sizes is True:

    for tensor in get_tensors():

    if not hasattr(tensor, 'dbg_alloc_where'):

    tensor.dbg_alloc_where = where_str

    new_tensor_sizes = {(type(x), tuple(x.size()), np.prod(np.array(x.size()))*4/1024**2,

    x.dbg_alloc_where) for x in get_tensors()}

    for t, s, m, loc in new_tensor_sizes - last_tensor_sizes:

    f.write(f'+ {loc:<50} {str(s):<20} {str(m)[:4]} M {str(t):<10}\n')

    for t, s, m, loc in last_tensor_sizes - new_tensor_sizes:

    f.write(f'- {loc:<50} {str(s):<20} {str(m)[:4]} M {str(t):<10}\n')

    last_tensor_sizes = new_tensor_sizes

    pynvml.nvmlShutdown()

    # save details about line _to be_ executed

    lineno = None

    func_name = frame.f_code.co_name

    filename = frame.f_globals["__file__"]

    if (filename.endswith(".pyc") or

    filename.endswith(".pyo")):

    filename = filename[:-1]

    module_name = frame.f_globals["__name__"]

    lineno = frame.f_lineno

    return gpu_profile

    except Exception as e:

    print('A exception occured: {}'.format(e))

    return gpu_profile

    def get_tensors():

    for obj in gc.get_objects():

    try:

    if torch.is_tensor(obj):

    tensor = obj

    else:

    continue

    if tensor.is_cuda:

    yield tensor

    except Exception as e:

    print('A exception occured: {}'.format(e))

    需要注意的是,linecache中的getlines只能读取缓冲过的文件,如果这个文件没有运行过则返回无效值。Python 的垃圾收集机制会在变量没有应引用的时候立马进行回收,但是为什么模型中计算的中间变量在执行结束后还会存在呢。既然都没有引用了为什么还会占用空间?

    一种可能的情况是这些引用不在Python代码中,而是在神经网络层的运行中为了backward被保存为gradient,这些引用都在计算图中,我们在程序中是无法看到的:

    后记

    实际中我们会有些只使用一次的模型,为了节省显存,我们需要一边计算一遍清除中间变量,使用del进行操作。限于篇幅这里不进行讲解,下一篇会进行说明。

    如何在Pytorch中精细化利用显存以及提高Pytorch显存利用率 - pytorch中文网

    原文出处: https://www.ptorch.com/news/181.html

    问题交流群 :168117787

    展开全文
  • 我比较关注其中Peak bandwidths的计算,以便在opencl程序测试bandwidth利用率。 下面,我以5870为例,探讨一下如何计算得到这些结果:  L1 cache的 peak bandwidth(L1ALU) = compute units* Wav

    在ATI Stream Computing Programming Guide中,例举了AMD 5系列显卡的参数信息。

    我比较关注其中Peak bandwidths的计算,以便在opencl程序测试bandwidth利用率。

    下面,我以5870为例,探讨一下如何计算得到这些结果:

        L1 cache的 peak bandwidth(L1<=>ALU) = compute units* Wavefront Size/compute Unit *Engine clock = cu数量*每个cu的wave大小*显卡系统时钟频率

    = 20 * 64 * 0.85 = 1088 GB/s

    注:在AMD GPU中,每个wave包含64个thread.

    L2 cache peak bandwidth(L1<=>L2) = Number of Channels * wavefrontSize * Engine clock = 内存通道数量*wave大小*显卡系统时钟频率

    = 8 * 64 * 0.85 = 435.2 GB/s

    注:在AMD 8XXX显卡中,每个mc通道对应一个64K的L2 cache。

    Global memeory peak rate(L2<=>Memory) = Number of Channels * memory pin rate * bits per chanel/8 = 内存通道数量*memory pin rate*每个channel位宽/8

    = 8 * 4.800 * 32/8 = 153.6 GB/s

    注:在cypress中,用的GDDR5,mclk是1200MHZ, GDDR5的date rate 是4,所以memory pin rate = 1200 * 4 = 4800Mb/pin

    除以8是转化为字节。

     

    Const cache read peak rate = peak read bandwidth per stream core * pe number * engine clock = 每个pe 的读带宽*pe数量*系统时钟频率

    = 16 * 320 * 0.85 = 4352 GB/s

    注:5870中的hardware参数

    1

    另外需要注意的对于consant buffer,只有直接地址访问时候,才能达到4352GB/s的峰值,如果通过索引方式,参考上表,用4或这0.6代替16.

    LDS Read peak rate = peak read bandwidth per stream core * pe number * engine clock = 每个pe 的读带宽*pe数量*系统时钟频率

    = 8 * 320 * 0.85 = 2176 Gb/s

    注:LDS(对应cl中local memory)带宽计算方式和const buffer一样。

    GPR read peak rate = peak read bandwidth per stream core * pe number * engine clock = 每个pe 的读带宽*pe数量*系统时钟频率

    = 48 * 320 * 0.85 = 13056 GB/s

    注:GPR(通用寄存器,对应cl中worktime 使用的private变量,对于kernel中局部变量,shade compiler一般都为其分配GPR)带宽计算方式和const buffer一样

    下图为58xx的性能参数

    2

    展开全文
  • 深度学习的兴起,给我们带来了新的努力和尝试的方向,同时也带来了对机器计算能力的更高要求。GPU加速是当前提高计算速度的关键,...接下来,我将向你展示如何使用一台破集显笔记本利用谷歌提供的云计算资源来构建一...

    深度学习的兴起,给我们带来了新的努力和尝试的方向,同时也带来了对机器计算能力的更高要求。GPU加速是当前提高计算速度的关键,但对大多数人来说,买个好的显卡代价过于昂贵。假如你不是土豪,假如你使用着计算资源极其有限的计算机,假如你想训练一个自己的深度学习神经网络并快速迭代还不想花钱升级自己的机器,那么可以参考下面的文章。

    接下来,我将向你展示如何使用一台破集显笔记本利用谷歌提供的云计算资源来构建一个属于自己的深度学习模型,以及如何将训练的结果保存到你自己的计算机。这将使你得以把需要大量计算的模型迭代过程放在云端,而将需要较少计算资源的模型使用放在客户端,也即你自己的电脑。

     

     1、使用Colab Notebooks——Colaboratory

    首先新建一个Colaboratory:

     

    然后,进入该notebook,进行基本设置:文件名称、需要的软件环境、是否使用GPU加速(这是是主要目的)等。

    点击“更改运行时类型”按钮后,在弹出的对话框,设置你需要的软硬件类型,我这里设置为:Python 3、使用GPU加速。

     

     经过上面的步骤,你就可以使用免费的云计算资源了,在里面可以尝试文件的上传、下载,导入各种工具包,编写你自己的代码并运行之等等。

    2、代码段的使用

    当进到这个notebook里面,它的基本使用与Jupyter Notebook类似,界面、基本操作都差不多,此外它还提供了各种现成的小点心——代码段:点开右边的隐藏窗口,就可以看到目录、代码段、文件三个选项,中间的代码段给我们提供了各种实用小功能的示例,我们可以查看各个小功能并尝试使用它,来解决特定的需求。

    下图标出了使用步骤,示例是将文件保存到本地计算机的一个代码段。还有其他各种功能,大家可以按需使用。

     3、一个完整例子

    通过上面的步骤,每个人都可以按照自己的想法做些事了。下面贴出我的一个例子,是关于构建一个CNN手写字体识别网络,并在线迭代训练,然后将模型保存在谷歌给我们分配的这个服务器上,最后将保存的模型下载到自己的计算机,这样的一个完整的过程。

    首先,是CNN网络的构建、训练、测试、模型的保存相关代码:

    # -*- coding: utf-8 -*-
    """
    Created on Wed Oct 24 09:48:06 2018
    
    @author: Leon
    
    内容:
    以LeNet-5网络为模型,搭建CNN,对mnist手写数字进行训练及测试
    给关键tensor添加name,方便保存模型后的调用
    """
    
    import tensorflow.examples.tutorials.mnist.input_data as input_data
    import tensorflow as tf
    import time
    tf.reset_default_graph()#如果保存模型时报错,应清除已有图
    mnist = input_data.read_data_sets("MNIST_data/",one_hot=True)
    
    x = tf.placeholder(tf.float32,[None,784],name='x')
    y = tf.placeholder(tf.float32,[None,10],name='y')
    
    def weight_variable(shape,name):  
        initial = tf.truncated_normal(shape, stddev = 0.1,name=name) # 截断正态分布  
        return tf.Variable(initial)  
      
    def bias_variable(shape,name):  
        initial = tf.constant(0.1, shape=shape, name=name) # 常量0.1  
        return tf.Variable(initial)
    
    # =============================================================================
    #  第一层:卷积+激活+池化
    # =============================================================================
    # 卷积核5*5,通道为1,个数为32个
    filter1 = weight_variable([5,5,1,32],name='filter1')
    # 卷积层:步长1*1,
    # Padding 有两个参数:
    # SAME——输出大小为:输入大小/s;
    # VALID——输出大小为:(输入大小-f+1)/s
    x_img = tf.reshape(x,[-1,28,28,1],name='x_img')
    conv1 = tf.nn.conv2d(x_img, filter1, strides=[1,1,1,1], padding='SAME',name='conv1')
    # 激活层:加偏移,然后激活
    bias1 = bias_variable([32],name='bias1')
    relu1 = tf.nn.relu(conv1+bias1,name='relu1')
    # 池化层:窗口大小2*2,步长2*2
    pool1 = tf.nn.max_pool(relu1,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME',name='pool1')
    print("第一层输出尺寸:",pool1.shape)
    
    # =============================================================================
    # 第二层:卷积+激活+池化
    # =============================================================================
    # 卷积核大小5*5,1通道,64个卷积核
    filter2 = weight_variable([5,5,32,64],name='filter2')
    # 卷积层:步长1*1
    conv2 = tf.nn.conv2d(pool1,filter2,strides=[1,1,1,1],padding='SAME',name='conv2')
    # 激活层:加偏移,然后激活
    bias2 = bias_variable([64],name='bias2')
    relu2 = tf.nn.relu(conv2+bias2,name='relu2')
    # 池化层:
    pool2 = tf.nn.max_pool(relu2,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME',name='pool2')
    print("第二层输出尺寸:", pool2.shape)
    
    # =============================================================================
    # 第三层:全连接层
    # =============================================================================
    # 提取上一层输出的尺寸
    shape = pool2.shape.as_list()
    # 拉伸上层输出,构造本层输入
    fc_input = tf.reshape(pool2,[-1,shape[1]*shape[2]*shape[3]])
    # 全连接层的权重:大小为本层输入*本层神经元的个数,也即下面的:[shape[1]*shape[2]*shape[3],32]
    fc_w = weight_variable([shape[1]*shape[2]*shape[3],1024], name='fc_w')
    # 全连接层的偏移量:大小为本层神经元的个数——32
    fc_b = bias_variable([1024],name='fc_b')
    # 建立本层全连接结构,并激活
    fc_out = tf.nn.relu(tf.matmul(fc_input,fc_w)+fc_b,name='fc_out')
    print("第三层输出尺寸:", fc_out.shape)
    
    # Dropout,用来防止过拟合  
    # 加在输出层之前,训练过程中开启dropout,测试过程中关闭  
    keep_prob = tf.placeholder(tf.float32,name='keep_prob')
    fc_out_drop = tf.nn.dropout(fc_out, keep_prob,name='fc_out_drop')
    
    # =============================================================================
    # 输出层
    # =============================================================================
    out_w = weight_variable([1024,10],name='out_w')
    out_b = bias_variable([10],name='out_b')
    pred = tf.nn.softmax(tf.matmul(fc_out_drop,out_w)+out_b,name='pred')
    
    # 定义损失函数
    loss = -tf.reduce_sum(y*tf.log(pred),name='loss')
    # 定义优化器:Adam优化函数
    optimizer = tf.train.AdamOptimizer(learning_rate=0.001,name='optimizer').minimize(loss)
    
    # 定义评价指标——准确率
    bool_pred = tf.equal(tf.arg_max(y,1), tf.arg_max(pred,1))
    accuracy = tf.reduce_mean(tf.cast(bool_pred,tf.float32),name='accuracy')
    
    # 定义全局变量初始化
    init = tf.global_variables_initializer()
    
    # 定义保存模型类
    saver = tf.train.Saver()
    
    # 启动图
    with tf.Session() as sess:
        # 执行是初始化
        sess.run(init)
        # 训练样本中,总的batch个数
        total_batch_nums = int(mnist.train.num_examples/50)
        for epoch in range(1):
            avg_loss = 0.
            time_start = time.clock()
            for i in range(total_batch_nums):
                
                batch = mnist.train.next_batch(50)
                batch_xs,batch_ys = batch
    #            batch_xs = batch_xs.reshape([-1,28,28,1])
                sess.run(optimizer,feed_dict={x:batch_xs,y:batch_ys,keep_prob:0.5})
    #            avg_loss += sess.run(loss, feed_dict={x:batch_xs,y:batch_ys})
            time_end = time.clock()
            
            if epoch %1 == 0:
                accuracy_eval = sess.run(accuracy, 
                                         feed_dict={x:batch_xs,y:batch_ys,keep_prob:1.0})
                print("Epoch:","%04d"%(epoch+1),
    #                  "loss:","%.4f"%avg_loss,
                      "accuracy:",accuracy_eval,
                      "running time:","%g"%(time_end-time_start))
                
        saver.save(sess,'model/my_model')
        accuracy_test = sess.run(accuracy,feed_dict={x:mnist.test.images,y:mnist.test.labels,keep_prob:1.0})
        print("test accuracy:",accuracy_test)

    插个题外话:Colaboratory 分配给我们的临时服务器是基于Linux环境的,我们在这个Notebook里面也可以与系统进行交互,不过需要在Linux命令前加上“!”,例如:

    因为我上面的代码,是将模型保存在当前目录的一个子目录“model”下的,所以通过命令:!ls model/即可列出该目录下的所有文件。

    好了,接下来我们就可以把这些文件下载下来了,下面是将保存好的模型下载到本地的代码:

    # 将保存的模型下载到本地
    import os
    from google.colab import files
    
    dir_list = os.listdir("model")
    for file in dir_list:
      path = 'model/'+file
      files.download(path)

    通过上面的代码执行,你就可以在你自己浏览器的下载目录下找到刚才保存的模型了,即下面的四个文件:

    最后,我们将下载到本地的 模型在自己计算机上进行应用:

    # -*- coding: utf-8 -*-
    """
    Created on Wed Oct 31 10:53:16 2018
    
    @author: Leon
    
    内容:
    1、从保存的模型中,加载之前训练好的CNN网络
    2、利用网络中变量的名字“name”来提取相应变量
    3、对相关变量进行feed,构造feed_dict
    4、最后,使用模型对新数据进行测试
    """
    
    import tensorflow as tf
    import tensorflow.examples.tutorials.mnist.input_data as input_data
    mnist = input_data.read_data_sets("MNIST_data/",one_hot=True)
    
    
    with tf.Session() as sess:
        saver = tf.train.import_meta_graph("model/my_model.meta")
        saver.restore(sess,tf.train.latest_checkpoint("model/"))
        
        graph = tf.get_default_graph()
        x = graph.get_tensor_by_name("x:0")
        y = graph.get_tensor_by_name("y:0")
        keep_prob = graph.get_tensor_by_name("keep_prob:0")
        accuracy = graph.get_tensor_by_name("accuracy:0")
        
        accuracy_eval = sess.run(accuracy, feed_dict={x:mnist.test.images[:1000],y:mnist.test.labels[:1000],keep_prob:1.0})
        print("acc:",accuracy_eval)
    

    OK,大功告成!至此,我们就完成了从使用谷歌云计算资源训练自己的模型,到将模型移植到其他机器进行测试应用的全过程,避免了因自身计算能力不足引起的迭代时耗过长的问题。

    展开全文
  • 浅析GPU计算——cuda编程 浅析GPU计算——CPU和GPU的选择 GPU与CPU、显卡区别 CPU与GPU并行计算联系与区别 使用 GPU 加速计算 深度强化学习是如何利用GPU进行并行计算的? ...
    展开全文
  •   在上一章中提到,计算机图形学主要研究内容就是研究如何在计算机中表示图形、以及利用计算机进行图形的计算、处理和显示的相关原理与算法。网上大多数教程都缺失对图像,以及渲染图像的显卡,显示图像的显示器的...
  • 利用显卡运行OpenCV算法,从你的系统中挤出每一点计算能力 GPU的相似性检查(PNSR和SSIM) 如果你已经知道如何处理其他模块,这将有助于您快速掌握:如何在GPU模块上编码。作为一个测试用例,它将会把 借助OpenCV...
  •   CUDA(Compute Unified Device Architecture)是显卡厂商NVIDIA推出的通用并行计算平台和编程模型,它利用NVIDIA GPU中的并行计算引擎能更有效地解决复杂的计算问题。通过使用CUDA,开发人员可以像在...
  • 1. 确认是英伟达的显卡(可以利用GPU并行计算) 2.下载anaconda 该步骤很简单,博客很多 如这个 注:anaconda里面会自动为计算机下载python,所以之前没有安装python也不影响。可以自行百度如何查看anaconda和python...
  • 利用显卡的图像处理器(GPU)计算Bitcoin大大提高了计算速度,所以现在通过Bitcoin比特币官方客户端的CPU计算已经很难发现一个新的Block来获得50个BTC,一台普通个人电脑可能需要2年时间才有可能一次性计算出50个或25...
  • 如何学好WPF

    2012-03-22 09:01:06
    当然,作为一种更高层次的封装,对于硬件本身不支持的一些图形特效的硬实现,WPF提供了利用CPU进行计算的软实现,用以简化开发人员的工作。  简单的介绍了一下WPF,这方面的资料也有很多。作于微软力推的技术,...
  • 下面看看如何利用设备管理器查看硬件信息。进入桌面,鼠标右击“我的电脑”图标,在出现的菜单中选择“属性”,打开“系统属性”窗口,点击“硬件--设备管理器”,在“设备管理器”中显示了机器配置的所有硬件设备。...
  • 透过这个技术,用户可利用NVIDIA的GeForce 8以后的GPU和较新的Quadro GPU进行计算。 查看显卡是否支持CUDA 输入下面命令查看电脑的NVIDIA型号: $lspci | grep -i nvidia 02:00.0 VGA compatible controller: ...
  • 公民科学有很多种实现方式,但主要有两大类:一类是靠志愿者来收集、记录、分类或分析科学数据,另一类就是利用大家手里闲置的算力来计算科学数据。现在通过WCG上的算力,科学家已经找出了更高效的过滤膜用以低成本...
  • Visual C++编程技巧精选500例.pdf

    热门讨论 2012-09-01 15:01:50
    194 如何计算一个字符串的大小? 195 如何快速格式化一个字符串? 196 如何将CString类型转换成int类型? l97 如何将CString类型转换成loat类型? 198 如何将CString中的字符串赋值给字符指针? 199 如何折行显示字符串? ...
  • 因为cuda具有高效利用GPU进行科学计算的优势,而人工智能的重点之一就是复杂的计算任务,因此学好GPU... 我们看一个例子,如何对矩阵进行分配显卡内存以及元素赋值操作。通常来讲,在GPU中分配内存使用的是cudaMal...
  • 在弹性的计算能力需求场景中,在大并发量集群机器管理中,我们如何有效的利用我们的集群能力。由国内一线云服务器厂商华为云带来的开源大数据分布式集群批处理系统Volcano能不能解决我们面临的机器集群问题?在实际的...
  • cuda二维数组内存分配和数据拷贝

    千次阅读 2016-04-20 10:54:45
    我们看一个例子,如何对矩阵进行分配显卡内存以及元素赋值操作。通常来讲,在GPU中分配内存使用的是cudaMalloc函数,但是对于二维或者三维矩阵而言,使用cudaMalloc来分配内存并不能得到最好的性能,原因是对于2
  • 【遇见CUDA】线程模型与内存模型

    千次阅读 2018-11-21 09:44:45
      CUDA(Compute Unified Device Architecture)[139]是显卡厂商NVIDIA推出的通用并行计算平台和编程模型,它利用NVIDIA GPU中的并行计算引擎能更有效地解决复杂的计算问题。通过使用CUDA,开发人员可以像在CPU上...
  • Matlab中调用CUDA加速的方法……

    千次阅读 2014-03-18 14:09:02
    现在nVIDIA显卡计算能力那是越来越强大了,不利用一下岂不是可惜了,尤其是现在Fermi大大加强了双精度计算能力之后,N卡+Matlab已经变成了我们解决数理问题的强大工具(计算速度可加快数十倍),但是应该如何使用...
  • 该章介绍节点、主题和服务,以及如何使用它们,还将通过一系列示例说明如何调试一个节点或利用可视化方法直观地查看通过主题发布的消息。 第3章进一步展示ROS强大的调试工具,以及通过对节点主题的图形化将节点间的...
  • ROS机器人程序设计

    2017-11-29 17:09:52
    该章介绍节点、主题和服务,以及如何使用它们,还将通过一系列示例说明如何调试一个节点或利用可视化方法直观地查看通过主题发布的消息。, 第3章进一步展示ROS强大的调试工具,以及通过对节点主题的图形化将节点间的...
  • 102.利用注册表找回“丢失”的内存 103.Windows经常进入安全模式 104.随机性死机 105.玩游戏时“内存不足” 106.Windows 98下“内存不足” 1.4 硬盘故障 107.开机找不到硬盘 108.开机不能从硬盘启动 109.开机时硬盘...
  • Nehe的OpenGL教程电子书

    2018-04-07 12:25:03
    在这一课里,你将学会如何读取你显卡支持的OpenGL的扩展,并在你指定的剪裁区域把它显示出来。 25.变形和从文件中加载3D物体 在这一课中,你将学会如何从文件加载3D模型,并且平滑的从一个模型变换为另一个模型...
  • 在这一课里,你将学会如何读取你显卡支持的OpenGL的扩展,并在你指定的剪裁区域把它显示出来。 25.变形和从文件中加载3D物体 在这一课中,你将学会如何从文件加载3D模型,并且平滑的从一个模型变换为另一个模型。...
  • 慧创连锁版超市POS收银系统

    热门讨论 2009-07-29 09:01:00
    如何科学合理的订货,快捷地配送,有效提高商品的周转率,降低库存,提高资金的利用率;如何避免组织机构庞大,机构重叠,人员编制不合理的现象。大型连锁商业商务信息系统建设正是针对这些问题而提出的,包括超级...

空空如也

空空如也

1 2 3
收藏数 42
精华内容 16
关键字:

如何利用显卡计算