pytorch使用教程及应用-GANS编程(4)-CUDA

CUDA基础知识

在前面,我们介绍了信号如何传递并通过神经网络,以及反向传播更新网络链接权重的计算过程。

它们都可以用矩阵乘法计算。一个简单的矩阵乘法,可以取代成百上万次单独计算。也就是吴恩达老师最喜欢的向量化运算代替FOR循环,详情可以查看我前面的文章,numpy作为python的科学计算库使用C语言实现的,这本身就加快了计算速度,如果想进一步了解为何计算机更擅长做矩阵运算,可以深入研究计算机底层原理,或者看一下这个大神的github:https://github.com/flame/how-to-optimize-gemm/wiki

1.numpy与python的比较

使用numpy来计算矩阵乘法,可以避免在python的下层软件中操作矩阵值。numpy可以直接在内存中存储矩阵值。同时,numpy会尝试使用CPU的特殊功能,例如并行功能,而不是一个接一个地逐个计算。

我们可以尝试使用numpy进行矩阵乘法比使用python进行循环计算的效能提高多少。

  1. 矩阵乘法代码
#方形矩阵大小
import time
size=600
a=numpy.random.rand(size,size)
b=numpy.random.rand(size,size)
time1=time.time()
x=numpy.dot(a,b)
print(time.time()-time1)
  1. 普通的循环计算代码
time2=time.time()
for i in range(size):
	for j in range(size):
		for k in range(size):
			c[i,j]+=a[i,k]*b[k,j]
		pass
	pass
print(time.time()-time2)

大家可以将输出的时间进行比较,相比之下,numpy的计算大概比python快了1500倍!

虽然这种计时测试并不是十分科学,因为有很多外部环境难以控制,并没有做到控制变量法,但是对我们来说,这么一种粗略的比较已经足够我们了解numpy进行矩阵乘法的计算优越性。

许多现实中的神经网络比我们试验所用的神经网络要复杂得多,所处理的数据量也大得多。在这种情况下,训练时间可能会非常长。即使使用numpy矩阵乘法,也可能需要数小时、数天甚至数周来训练。

为了追求更快的速度,机器学习的研究人员们也开始利用一些计算机中的特殊硬件。这些硬件原本是用来提升图形处理性能的。读者可能听说过这种叫做显卡也就是GPU的硬件。

2.NVIDIA CUDA

每台计算机都有一个中央处理器(central processing unit,CPU),它是完成大多数工作的主要元件。比如说,是它在运行我们的python代码。我们可以把它想象成计算机的大脑。GPU的设计是通用的,可以胜任多种不同的任务。

但是显卡就不一样了,GPU(central processing unit)顾名思义是图形处理器,其是专门针对一些特定任务而设计的。其中一个就是数值计算,包括以高度并行化的方式实现矩阵乘法。

这里我将引用原教材的一张图来让大家更明显地看出两者的区别:
在这里插入图片描述

如果要进行很多计算,CPU需要一个接一个地运行。现代GPU可能会用到2或4个甚至8或16个内核来进行计算。最近,最强大的消费级CPU已经配备了64个内核。如果大家了解过多进程和多线程的区别,就知道内核对于提升计算机计算速度的重要性。我有一篇博客就描述了这一知识点,大家可以看看。

而GPU呢,普遍都有上千个,这意味着一个负荷较大的任务可以被分割并分配给所有内核,这将大大缩短整个任务的完成时间。

在很长一段时间里,NVIDIA的GPU市场份额一直保持领先。同时,它也是机器学习研究标准的制定者之一。因为他们有一套成熟的软件工具,可以充分利用硬件加速。这套软件框架就是CUDA。也是我们需要学习的重点。

CUDA的缺点在于,它只适用于NVIDIA的GPU,造成了我们在硬件选择上的局限性。NVIDIA的竞争对手是AMD,而后者才刚刚开始针对自己的GPU研发类似的框架。不久之后,可能会出现一个跨平台的标准并得到普及。但是,现在我们必须同时使用NVIDIA和CUDA。

在原著中,使用的是谷歌云计算来支持Jupiter的使用,其Colab服务免费提供高性能GPU资源来支持加速计算。但是,其限制GPU连续使用不超过12个小时。(禁止挖矿!)

3.在python中使用CUDA(anaconda3+pycharm+pytorch+cuda10.0+cudnn)
import torch
import os
os.environ["CUDA_VISIBLE_DEVICES"]="0" #一块GPU的写法
x=torch.cuda.FloatTensor([3.5])
print(x)
print(x.type())

output:
tensor([3.5000], device='cuda:0')
torch.cuda.FloatTensor #大家可以看到数据类型的变化

大家可以通过x.device来进一步确定张量x所在的设备。

对存储在GPU中的张量进行计算是十分简单的,大多数时候与正常使用Pytorch没有任何区别。

得益于NVIDIA的cuda,我们将整个计算过程搬移到了GPU上,这是一种非常大的进步。但是,我们前面提到,GPU计算能力更快的一个重要原因是其有很多个内核,所以只有当数据量很大,然后我们将其拆分成很多个小份分配给多个GPU内核的时候,才是利用其计算优势的时候。而简单的计算可能甚至不会比CPU快。

下面我们可以做一个对其计算性能的小测试

import torch
import numpy
import os
os.environ["CUDA_VISIBLE_DEVICES"]="0" #一块GPU的写法
import time
size=600
a=numpy.random.rand(size,size)
b=numpy.random.rand(size,size)
time1=time.time()
aa=torch.cuda.FloatTensor(a)
bb=torch.cuda.FloatTensor(b)
cc=torch.matmul(aa,bb) #pytorch进行矩阵乘法的函数
print(str(time.time()-time1)+'s')
print(cc.type())
print(cc.device)

经过测试,实际上我发现,我电脑上cpu算的比GPU都快,这是因为这里的数据量太小。

import torch
import numpy
import os
os.environ["CUDA_VISIBLE_DEVICES"]="0" #一块GPU的写法
import time
size=10000
a=numpy.random.rand(size,size)
b=numpy.random.rand(size,size)
time1=time.time()
aa=torch.cuda.FloatTensor(a)
bb=torch.cuda.FloatTensor(b)
cc=torch.matmul(aa,bb) #pytorch进行矩阵乘法的函数
print(str(time.time()-time1)+'s')
print(cc.type())
print(cc.device)

在这种情况下,GPU的优势就体现出来了,其远远快于我的CPU计算。当然,计算的速度都会随着矩阵变大而变慢。
在这里插入图片描述

在数据量少的情况下,GPU确实比CPU慢,但当数据慢慢增大时,numpy的计算时间呈指数上升,而cuda并没有收到什么影响。以单个计算为栗,GPU并不总是快于CPU,而且CPU之间的数据传输与GPU之间的数据传输同样耗时。只有在我们可以充分利用多核计算的情况下,GPU才能发挥优势。数据量才能被充分分割成若干份进行并行计算。

最后,我们来进行一些使用cuda的标准化设置:

if torch.cuda.is_available():
    torch.set_default_tensor_type(torch.cuda.FloatTensor) #如果设备可用,我们将默认的数据类型设为torch.cuda.FloatTensor
    print("using cuda:",torch.cuda.get_device_name(0))
    pass
device=torch.device("cuda" if torch.cuda.is_available() else "cpu") #设置一个pytorch设备,在没有默认使用GPU的情况下,允许我们通过代码将数据传入GPU。如果CUDA不可用,则设备会指向CPU。
print(device)

using cuda: GeForce MX230
cuda

原教材学习要点:

1. Gpu包含很多计算内核,能以高度并行的方式运行一些计算。最初,它们被设计用来加速计算机图形计算,现在越来越多地被用于加速机器学习计算。
2.CUDA是NVIDIA针对GPU加速计算而开发的编程框架。通过PyTorch可以很方便地使用CUDA,无需过多地改变代码。
3.在简单的基准测试中,如矩阵乘法,GPU的速度超过cpu150倍。
4.在单个计算上,GPU可能比cpu慢。这是因为在CPU之间和在GPU之间的数据传送同样耗时。如果数据量不足以分配给多个内核,GPU的优势便无法得到发挥。
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值