在过去的几十年中,许多技术革命改变了生活的世界,其中之一就是图形处理单元(GPU)。GPU的出现引领进入了一个新的计算时代——人工智能(AI),这得益于它提供的计算能力。如今,GPU已成为新的标准,它们的影响无处不在,从执行科学计算到发射火箭,甚至个人设备如PC和笔记本电脑。
今天,将了解GPU能为提供什么,以及它们如何提高生产力。还将通过训练两个神经网络来识别数字和衣物,比较它们的性能。
首先,让来了解什么是GPU,为什么要使用它们,以及它们的用例。GPU或图形处理单元与它们的对应物类似,但拥有许多核心,这使得它们能够同时进行更快的计算(并行计算)。这一特性非常适合执行大规模数学计算,如计算图像矩阵、计算特征值、行列式等。简而言之,可以将GPU视为一个额外的大脑,它一直存在,但现在科技巨头如Nvidia和AMD正在利用这种力量。
使用GPU的原因有很多,两个最常见的原因是:并行性:可以并行运行代码并得到结果,因为所有过程都是并行执行的。低延迟:由于能够处理高密集型计算,可以期待立即得到结果(即,快速计算)。
GPU的一些用例包括:虚拟桌面基础架构(VDI):可以从云端访问应用程序(如CAD),GPU可以实时处理它们,延迟非常低。人工智能:由于能够处理重型计算,可以使用神经网络和机器学习算法教机器模仿人类,这些算法主要在幕后进行复杂的数学计算。高性能计算(HPC):大多数公司可以在多个集群/节点/云服务器之间分配他们的计算,并显著加快完成工作的速度。多亏了GPU,增加一个可以显著提高计算时间。
希望这一部分能给一些理解。否则,可以在这里了解更多。现在,让进入讨论的第二部分——实际比较两种设备的绩效。为了简单起见,将这部分分为两个部分,每个部分涵盖一个单独的测试细节。此外,需要设置tensorflow_gpu(参考链接)和Jupyter笔记本行魔法。
可以通过列出所有物理设备来检查TensorFlow是否在GPU上运行:tensorflow.config.experimental.list_physical_devices()。对于CUDA友好的:tensorflow.test.is_built_with_cuda() >> True。
测试一——训练数字分类器。对于第一次测试,将为著名的cifar10数据集创建一个数字分类器,该数据集包含32*32的彩色图像,分为50,000个训练和10,000个测试图像,以及十个类别。让开始吧。
import tensorflow as tf
from tensorflow import keras
import numpy as np
import matplotlib.pyplot as plt
(X_train, y_train), (X_test, y_test) = keras.datasets.cifar10.load_data()
执行EDA——检查数据和标签形状:
# 检查图像形状
X_train.shape, X_test.shape
# 显示单个图像形状
X_train[0].shape
# 检查标签
y_train[:5]
应用预处理:将图像(NumPy数组)按255缩放,并对标签进行One-Hot编码,以表示所有类别为0,除了实际标签为1的'float32'。
# 将图像值缩放到0-1之间
X_train_scaled = X_train/255
X_test_scaled = X_test/255
# One-Hot编码标签
y_train_encoded = keras.utils.to_categorical(y_train, num_classes = 10, dtype = 'float32')
y_test_encoded = keras.utils.to_categorical(y_test, num_classes = 10, dtype = 'float32')
模型构建:一个函数来构建具有以下架构的神经网络,并包含编译:
def get_model():
model = keras.Sequential([
keras.layers.Flatten(input_shape=(32,32,3)),
keras.layers.Dense(3000, activation='relu'),
keras.layers.Dense(1000, activation='relu'),
keras.layers.Dense(10, activation='sigmoid')
])
model.compile(optimizer='SGD',
loss='categorical_crossentropy',
metrics=['accuracy'])
return model
使用model.summary()的架构:两个隐藏层分别有'3000 & 1000'个单元,后面跟着一个softmax层,有'10'个单元输出概率。
上述代码不言自明。现在让使用Jupyter的time it魔法训练模型并标记时间。
训练:训练十个周期,verbose = 0,意味着没有日志。
CPU
%%timeit -n1 -r1
# CPU
with tf.device('/CPU:0'):
model_cpu = get_model()
model_cpu.fit(X_train_scaled, y_train_encoded, epochs = 10)
GPU
%%timeit -n1 -r1
# GPU
with tf.device('/GPU:0'):
model_gpu = get_model()
model_gpu.fit(X_train_scaled, y_train_encoded, epochs = 10)
所以,认为现在可以理解为什么GPU更受青睐了。14~2,真的非常快😉。
测试二——训练衣物分类器。现在让通过另一个测试来确认假设,这次是使用fashion mnist数据集,它包含28*28的灰度图像,分为60,000个训练和10,000个测试,以及10个类别。让创建这个:
fashion_mnist = keras.datasets.fashion_mnist
(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
检查形状
print(train_images.shape)
print(train_labels[0])
>> (60000, 28, 28)
>> 9
检查图像
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
plt.imshow(train_images[0])
class_names[train_labels[0]]
>> 输出:
缩放
train_images_scaled = train_images / 255.0
test_images_scaled = test_images / 255.0
最后,让改变模型来定义需要多少隐藏层,并将远程单元设置为500。这将允许在模型过拟合的情况下调整模型架构。
def get_model(hidden_layers=1):
layers = [keras.layers.Flatten(input_shape=(28, 28))]
for i in range(hidden_layers):
layers.append(keras.layers.Dense(500, activation='relu'),)
layers.append(keras.layers.Dense(10, activation='sigmoid'))
model = keras.Sequential(layers)
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
return model
如果这看起来不熟悉,让来分解一下:在上述代码中,将层存储为一个列表,然后将那些隐藏层添加到hidden_layers中。最后,使用adam作为优化器,sparse_categorical_crossentropy作为损失函数来编译模型。要监控的指标再次是准确率。
最后,让用5个隐藏层训练模型,训练5个周期:
%%timeit -n1 -r1
with tf.device(‘/CPU:0’):
cpu_model = get_model(hidden_layers=5)
cpu_model.fit(train_images_scaled, train_labels, epochs=5)
%%timeit -n1 -r1
with tf.device('/GPU:0'):
gpu_model = get_model(hidden_layers=5)
gpu_model.fit(train_images_scaled, train_labels, epochs=5)
注意:由于某些GPU限制,周期运行需要从之前的更改。
显然,这次GPU也赢得了比赛!😁