两个最流行的基于Python的深度学习库是PyTorch和TensorFlow。对于一个机器学习新手来说,在使用深度学习模型的时候,可能很难决定使用哪一个。你可能完全不知道这些区别,使你不可能做出一个明智的决定。我们将在本文中通过使用这两个框架来创建一个分类器来解决同样的问题,来看看这些实践中的一些差异。最后,我们将得出结论,为解决同一问题而定义的类似模型,但使用不同的基础设施,其结果是如何推迟的。本文将涉及的主要内容列举如下。
内容列表
- 关于MNIST数字数据
- 关于TensorFlow的简介
- 关于PyTorch的简介
- 构建图像分类的深度学习模型
- 用TensorFlow建立模型
- 用PyTorch建立模型
- 比较性能
我们先来讨论一下MNIST数据集。
关于MNIST数字数据
修改后的美国国家标准和技术研究所数据集是MNIST数据集的缩写。它是一个由60,000个小方块灰度图像组成的手写单一数字的集合,范围从0到9。其目的是将手写数字图像分类到代表从0到9(含)的整数值的十个类别中。
这是一个被广泛使用和理解的数据集,大部分已经被解决了。深度学习卷积神经网络是表现最好的模型,分类准确率超过99%,在保持测试数据集上的错误率在0.4%至0.2%之间。下面的例子显示是来自于从Tensorflow数据集API加载的MNIST数字的训练数据集。

关于TensorFlow的简介
谷歌开发了TensorFlow,它在2015年被开放了源代码。它是从谷歌的内部机器学习软件演变而来,经过重构和优化后用于生产。
术语 "TensorFlow "指的是组织和处理数据的方式。张量是TensorFlow和PyTorch中最基本的数据结构。当你使用TensorFlow时,你建立一个有状态的数据流图,它类似于一个记住过去事件的流程图,以执行对这些张量中数据的操作。
TensorFlow因其是一个高性能的深度学习库而闻名。它有一个庞大而活跃的用户群,以及大量的官方和第三方的训练、部署和服务模型、工具和平台。
关于PyTorch的简介
PyTorch是最新的深度学习框架之一,由Facebook团队开发,于2017年在GitHub上发布。PyTorch因其易用性、简单性、动态计算图和高效的内存使用而越来越受欢迎。它是强制性的,这意味着它可以立即运行,用户可以在编写整个代码之前测试它是否有效。
我们可以写一段代码并实时运行,因为它有一个内置的Python实现,作为一个深度学习平台提供兼容性。由于其用户友好的界面,它迅速获得了普及,促使Tensorflow团队将其最受欢迎的功能纳入Tensorflow 2.0。
构建图像分类的深度学习模型
在本节中,我们将在最广泛使用的MNIST数据集上比较TensorFlow和PyTorch的代码可用性和易用性,以对手写数字进行分类。使用这两个框架,我们将检查为了有一个适当的分类模型而需要执行的最小程序。在这两个模型中,需要采取的步骤有:数据加载、预处理、模型建立、训练和结果的可视化。对于这两个模型,我试图保持各层和超参数配置的一致性。
所以现在让我们先从Tensorflow开始。
用TensorFlow建立模型
让我们在TensorFlow中建立一个用于图像分类的卷积神经网络模型:
import tensorflow
from tensorflow.keras.datasets import mnist
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.layers import Conv2D, Flatten, Dense, MaxPooling2D
from tensorflow.keras.models import Sequential
import matplotlib.pyplot as plt
加载和预处理数据。在这里,预处理只是将图像从28 x 28重塑为28 x 28 x 1,即我们已经添加了彩色通道,1表示灰色通道。接下来,我们对每个类别进行了二进制表示,最后,我们对所有的像素值进行了缩放:
# reshaping and one hot encoding
x_train = x_train.reshape(x_train.shape[0], 28, 28, 1)
x_test = x_test.reshape(x_test.shape[0], 28, 28, 1)
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)
# scaling
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train = x_train / 255.0
x_test = x_test / 255.0
接下来,我们将建立一个模型。这个模型将包括2个卷积层,然后是一个池化层和一个密集分类器。随机梯度下降被用作优化器函数,学习率为0.01,分类交叉熵作为损失函数,该模型被训练了5个epochs。在Pytorch模型中也是如此:
model = Sequential()
model.add(Conv2D(32, (3,3), input_shape = (28,28,1), activation='relu'))
model.add(Conv2D(64,(3,3), activation='relu'))
model.add(MaxPooling2D((2,2)))
model.add(Flatten())
model.add(Dense(1024, activation='relu'))
model.add(Dense(10, activation='softmax'))
# compile
model.compile(optimizer='sgd', loss='categorical_crossentropy', metrics=['accuracy'])
# training
history = model.fit(x_train, y_train, validation_split=0.3, epochs=5)
下面显示的是5个epochs的训练和验证损失:

(TensorFlow模型的损失曲线)
到此为止,这就是使用TensorFlow构建图像分类器所需的所有最小工作。
用PyTorch建立模型
让我们在PyTorch中建立一个卷积神经网络模型用于图像分类:
import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
from torchvision import datasets, transforms
加载并预处理数据:
# pre-processor
transform = transforms.Compose([
transforms.Resize((8, 8)),
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))])
# load the data
train_dataset = datasets.MNIST(
'data', train=True, download=True, transform=transform)
test_dataset = datasets.MNIST(
'data', train=False, download=True, transform=transform)
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=512)
test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=512)
接下来,和之前一样,我们将在这里建立一个模型,并将其编译:
# Build a model
class CNNModel(nn.Module):
def __init__(self):
super(CNNModel, self).__init__()
self.conv1 = nn.Conv2d(1, 32, 3, 1)
self.conv2 = nn.Conv2d(32, 64, 3, 1)
self.fc = nn.Linear(1024, 10)
def forward(self, x):
x = F.relu(self.conv1(x))
x = F.relu(self.conv2(x))
x = F.max_pool2d(x, 1)
x = torch.flatten(x, 1)
x = self.fc(x)
output = F.log_softmax(x, dim=1)
return output
net = CNNModel()
# compiling
optimizer = optim.SGD(net.parameters(), lr=0.01)
criterion = nn.CrossEntropyLoss()
在此之后,在训练阶段,我们必须创建一个循环,在我们的epochs和batches上循环。我们将相应地处理我们的图像,并使用前向传递来计算我们的损失。这段代码可以在下面链接的笔记本中找到。
现在,最后我们要看一下损失曲线:

(PyTorch模型的损失曲线)
比较一下性能
从上面两张图来看,TensorFlow模型的曲线看起来很陡峭,在第3个 epoch之后,验证集的损失似乎在增加。简而言之,我们可以说TensorFlow模型的学习过程是陡峭的,我们可以期待许多权衡。
而在PyTorch模型中,即使模型的建立过程看起来很复杂,但在整个过程中观察到的训练和损失是平稳的,验证损失适当地跟随测试损失。
最后的话
在这一点上,我们已经简单地讨论了TensorFlow和PyTorch,并看到了图像分类的最小建模过程。从这两张图的训练和测试表现来看,我们可以说PyTorch模型的训练和评估过程更加平稳,而在构建模块方面,我认为TensorFlow由于其简化的API而更加适合初学者。