Make Your First GAN With PyTorch:4.CUDA基础

  • 本章是 Make Your First GAN With PyTorch 的第 4 章,本书的介绍详见这篇文章。
  • 本章针对的 神经网络 是指在本书第 2 章建立的数字分类的网络,该网络详见 这篇文章。
  • 而且,本文也是基于 Google Colab 开展的,详细情况说明见这篇文章的说明。

本文目录

  • 1. Numpy 和 Python
  • 2. NVIDIA CUDA 介绍
  • 3. 在 Python 下使用 CUDA
  • 4. 要点总结


Make Your Own Neural Network 中明确了如何计算信号穿过一个神经网络,以及如何使用反向传播来更新网络权重。

我们发现这个过程涉及的计算,不用写出几百甚至上千个分立的计算式,而是可以直接写成一个简单的矩阵相乘。而类似于 numpy 的库,可以用于完成矩阵相乘,速度很快效率很高,使用 numpy 来对两个矩阵进行相乘, 比单纯使用 Python 代码完成所需计算的效率更高。

  • numpyPython 中一种开源的数值计算扩展库,入门介绍可以参见这篇文章。

1. Numpy 和 Python

使用 numpy 对矩阵相乘,避免了在 Python 的软件层的一些复杂操作。同时,numpy 可以直接对矩阵制的存储内存进行操作,同时使用了 CPU 的一些特性,比如并行计算,来提升效率。

下面通过实例,探究一下使用 numpy 的矩阵乘法比直接使用 Python 高效多少。新建一个 notebook 文件并导入 torchnumpy ,在一个新的 cell 中输入下面的代码:

# 方形矩阵的尺寸为 size
size = 600

a = numpy.random.rand(size, size)
b = numpy.random.rand(size, size)

上述代码简单创建了两个 numpy 数组,元素值为 01 之间的随机值,数组的宽度和高度都是 size ,这里设置为 600

在一个新 cell 中输入下面的代码:

%%timeit

x = numpy.dot(a, b)

其中 %%timeit 是对一个 cell 运行时间进行记录的特殊命令,其他代码则是简单使用 numpy 来对两个数据进行矩阵相乘。

运行该代码,并观察代码运行所需的时间:

Make Your First GAN With PyTorch:4.CUDA基础_第1张图片

  • 上面图片中最后一行,说明 %%timeit 命令运行了代码多次,并从中选出最好的时间,以尽量减少其他影响。运行时间的最佳值是 12.7 毫秒,考虑到数组的尺寸很大,这个时间已经相当快了。

下面编写代码,故意不使用 numpy 来完成矩阵相乘,而是使用 Python 从两个矩阵中所有组合的值来构建答案矩阵。

由于代码比较复杂(也比较直接),这里不探讨具体的代码,重要的是这个代码避免了使用 numpy 来完成相乘。

Make Your First GAN With PyTorch:4.CUDA基础_第2张图片

可以看到这个代码使用了 3 分钟 11 秒(191秒),相比之前时间更长。

也就是说,numpy 版本的代码大约快了 1500 倍!

  • 需要注意的是,这些计时测试非常简单,但是并不科学,只是一个粗略的比较。如果真的想要比较性能,应该在控制选项的情况下运行更多的测试。
  • 但是无论如何,可以看到 numpy 矩阵相乘比纯 Python 的代码要快几个数量级。

相比这里的实验,许多实际的神经网络要大很多,而且处理更多的数据,训练时间可能非常长,即使使用如 numpy 等可以做快速矩阵相乘的库也可能需要几小时、几天甚至几周。

为了寻求更高的速度,机器学习研究人员开始利用一些计算机中的特殊硬件,这些硬件最初是为了提高图形性能而设计的,也就是 “显卡”

2. NVIDIA CUDA 介绍

所有的电脑都有 CPU(Central Processing Unit,中央处理器),可以将 CPU 视为我们的大脑,是电脑完成绝大多数工作的主要部件。但是,由于 CPU 是用来完成通用目标的,对各种不同的任务都很擅长。

除了 CPU 外,显卡中包括了 GPU (Graphics Processing Unit,图像处理器)。不同于通用的 CPUGPU 用于 完成特定任务,其中一个任务是使用并行计算,快速完成包括矩阵相乘在内的算术计算。

下面的图像展示了 CPUGPU 的核心区别:

Make Your First GAN With PyTorch:4.CUDA基础_第3张图片
如果需要做很多的计算,CPU 需要逐个完成计算。现代的 CPU 可能使用 2 个或 4 个核心,甚至 8 个或 16 个核心来完成这些计算,直到最近才有定制的包括了 64 个核心的 CPU

但是,GPU 有很多算术核心,现在可能包括数千个,这意味着巨大的工作负载可以分配到这些核心上,而且这些工作可以很快完成。

NVIDIAGPU 市场处于引领地位,并且使用他们的软件工具进行硬件加速已经相当成熟,所以已经成为了机器学习研究中的标准,这个软件框架称之为 CUDA

  • CUDA 的缺点是只能使用 NVIDIAGPU
  • Google Colab 服务允许使用免费的 GPU 来加速计算。ColabGPU 几乎是现有的最强大的,但是 Google 不允许用户连续使用一个 GPU 超过 12 个小时。

3. 在 Python 下使用 CUDA

为了在 Google ColabPython notebook 中使用 GPU,需要改变一些设定。

notebook 文件顶部的选项目录中,选择 Runtime,并选择 Change runtype type

Make Your First GAN With PyTorch:4.CUDA基础_第4张图片
保持 runtime typePython 3,然后将 硬件加速器(Hardware accelerator)None 改为 GPU

上述设定将重启 Google 平台的虚拟机,并且增加 GPU 到其中。

我们能做的最简单的事是创建一个运行在 GPU 上的张量。

在本书的开头,我们创建了类似下面的张量:

x = torch.tensor(3.5)
print(x)

这个简单的代码并没有指定张量使用何种类型的数字,所以使用了默认的float32 类型。实际上 numpy 有很多数据类型的选项,如整型变量为 int32,浮点型数据为 float32,甚至可以使用 float64 获得更高的精度。

如果想要数据类型更具体,可以写成下面形式:

x = torch.FloatTensor([3.5])

简单使用 x.type() 来检查类型,可以看到类型为 torch.FloatTensor

在这里插入图片描述
为了在 GPU 上创建张量,可以将类型更改为 torch.cuda.FloatTensor

可以看到类型已经被更改了:

在这里插入图片描述
使用x.device,再次检查确认张量所在的设备:

在这里插入图片描述
可以看到是 CUDA 设备!

使用 GPU 上的张量很简单,很多情况下与正常使用 PyTorch 没有区别:

# 使用 GPU 上的张量进行计算
y = x * x
y

观察结果:

在这里插入图片描述
计算并不是由 CPU,而是由 GPU 完成的,获得的结果也是 GPU 上的张量。

  • 这看起来只是一个很小的成就,但实际上很难得。特别是过去使用 GPU 加速非常困难,现在用很简单的语句就能实现。
  • 其实,刚完成的简单计算并不能从 GPU 强大的功能中收益。为了从 GPU 中获益,需要很多的数据,并将数据分为不同部分提供给 GPU 核心。

下面来使用之前使用的 600*600 的矩阵来创建 CUDA 张量,并在 GPU 上完成矩阵相乘:

aa = torch.cuda.FloatTensor(a)
bb = torch.cuda.FloatTensor(b)

PyTorch 函数中用来完成等效矩阵相乘的函数是 matmul()

cc = torch.matmul(aa, bb)

在一个单独的 cell 中进行计时:

Make Your First GAN With PyTorch:4.CUDA基础_第5张图片

  • 可以看到,使用 GPU 计算使用了 74.4 微秒。不是 毫秒,而是 微秒。这非常快!

尽管并不严格,但这个简单的测试确实显示出使用 CUDA 进行矩阵相
乘比使用 numpy 快了 150 倍。

使用不同的矩阵尺寸完成上述实验,可以对 CPUGPU 的性能有更好的比较。

下面的图像展示了 numpyCUDA 对矩阵尺寸为 1002000 的矩阵相乘的时间。

Make Your First GAN With PyTorch:4.CUDA基础_第6张图片

  • 可以看到随着矩阵增大,numpy 速度降低(所需时间增加),使用 CUDA 的计算速度虽然也有所降低。但是在这种规模下,GPU 速度非常非常快!
  • 该图表确实显示了 GPU 处理大量数据的好处,这些数据可以分解成大块并开展并行计算。

对于少量数据,可能会惊讶地发现 GPU 可能会变慢。这是因为在单独的计算中, GPU 并不总是比 CPU 快,而且在 CPUGPU 之间移动数据也要付出代价。仅当可以利用许多计算核心时(拥有足够的数据时),GPU 才有优势。

下面介绍一些代码,这些代码已经成为检查 CUDA 是否可用的标准方法:

if torch.cuda.is_available():
    torch.set_default_tensor_type(torch.cuda.FloatTensor)
    print("using cuda:", torch.cuda.get_device_name(0))
    
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    
    device

上述代码使用 torch.cuda.is_available() 进行简单检查。如果 CUDA 可用,就将默认的张量类型设置为 torch.cuda.FloatTensor,并输出 CUDA 发现的设备类型。

代码同时设定了一个 PyTorch device 变量,使得在非默认情况下,方便
地将数据转移到 GPU 中。同时,如果 CUDA 不可用, device 将指向 CPU

下面来试一下代码,观察 CUDA 可以发现的设备:

Make Your First GAN With PyTorch:4.CUDA基础_第7张图片

  • 可以看到 CUDA 设备是一个 Tesla P100,这个硬件非常强大和昂贵。

4. 要点总结

  • GPU包括了很多计算核心,使用高并行方法来完成特定的计算。最早 GPU 是用来加速计算机图像的,现在随着机器学习计算量的增加,对 GPU 的使用也在增加;
  • CUDANVIDIA 用来GPU 加速计算的编程框架。PyTorch 使得不大幅度改变代码形式的情况下可以简单的使用 CUDA
  • 在综合基准上来看,比如矩阵相乘,GPUCPU 的性能可以高出150 倍以上;
  • 单次计算中,GPU 可能比 CPU 更慢。在 CPUGPU 之间传递数据也有时间消耗,如果数据不能广泛分配到很多核心上,使用 GPU 可能没有多少甚至没有任何优势。

你可能感兴趣的:(Pytorch,Make,First,GAN,With,PyTorch,pytorch,python,深度学习,人工智能,生成对抗网络)