深度学习:Keras vs PyTorch

对于许多科学家、工程师和开发人员来说,TensorFlow是他们的第一个深度学习框架。Tensorflow 1.0于2017年2月发布;至少可以说,这不是很友好。

在过去的几年中,两个主要的深度学习框架获得了巨大的知名度,这主要是由于它们对比 TensorFlow 更容易使用:Keras和Pytorch。

本文将从四个方面对比 Keras 和 Pytorch。

Keras

Keras 本身并不是一个框架,而是一个位于其他深度学习框架之上的高级 API。目前它支持 TensorFlow、Theano 和 CNTK。

Keras 的美妙之处在于它的易用性。它是迄今为止最容易启动和快速运行的框架。定义神经网络非常直观,使用函数式 API 可以将层定义为函数。

PyTorch

Pyorch 是由 Facebook 的 AI 研究小组开发的深度学习框架(类似于 TensorFlow)。与 Keras 一样,它也抽象掉了深度网络编程中的许多混乱部分。

就高级和低级编码风格而言,Pytorch 介于 Keras 和 TensorFlow 之间。与 Keras 相比,您拥有更多的灵活性和控制力,但同时您不必进行任何声明式编程。

深度学习从业者整天都在为应该使用哪个框架而争论不休。一般来说,这取决于个人喜好。但是在选择时,我们应该先从各个方面了解它。

(1) 定义模型的类与函数

为了定义深度学习模型,Keras 提供了Functional API。使用 Functional API,神经网络被定义为一组顺序函数,一个接一个地进行应用。例如,第二层的输入是第一层的输出。

img_input = layers.Input(shape=input_shape)
x = layers.Conv2D(64, (3, 3), activation='relu')(img_input)    
x = layers.Conv2D(64, (3, 3), activation='relu')(x)    
x = layers.MaxPooling2D((2, 2), strides=(2, 2))(x)

在 Pytorch 中,您将网络设置为一个类,它继承了 Torch 库中的 torch.nn.Module。与 Keras 类似,Pytorch 也提供了层用来构建 block,但由于它们位于 Python 类中,因此它们在类的 __init__() 方法中被引用并由类的 forward() 方法执行。

class Net(nn.Module):
   def __init__(self):
       super(Net, self).__init__()
       self.conv1 = nn.Conv2d(3, 64, 3)
       self.conv2 = nn.Conv2d(64, 64, 3)
       self.pool = nn.MaxPool2d(2, 2)
   def forward(self, x):
       x = F.relu(self.conv1(x))
       x = self.pool(F.relu(self.conv2(x)))
       return x
model = Net()

因为 Pytorch 允许您访问所有 Python 的类功能,而不是简单的函数调用,所以定义网络可以更清晰、更优雅地包含在内。这确实没有太大的缺点,除非你真的觉得尽快编写网络代码对你来说最重要,否则 Keras 会更容易使用。

(2) Tensors 和计算图 vs 标准数组

Keras API 对不经意的编码者隐藏了许多杂乱的细节。定义网络层很直观,默认设置通常足以让您入门。

唯一真正需要深入研究更底层、更细节的 TensorFlow,是你在实施比较前沿或比较“奇特”的模型时。

棘手的部分是,当您真正深入到较低级别的 TensorFlow 代码时,您会遇到随之而来的所有具有挑战性的部分!您需要确保所有矩阵乘法都对齐。哦,甚至不要考虑尝试打印出层的输出之一,因为您只会在终端上打印出一个 Tensor 对象。

Pytorch 在这些方面往往更宽容一些。您需要知道每一层的输入和输出大小,但这是可以很快掌握的较容易的方面之一。您不必处理构建抽象计算图的问题,您在调试时看不到它。

Pytorch 的另一个优点是可以在 Torch 张量和 Numpy 数组之间来回切换。如果您需要实现一些自定义的东西,那么在 TF 张量和 Numpy 数组之间来回切换可能会很痛苦,这需要开发人员对 TensorFlow 有深入的了解。

Pytorch 操作实际上要简单得多。您只需要知道两个操作:一个是将 Torch 张量(一个变量对象)切换到 Numpy,另一个是反向操作。

当然,如果您永远不需要实现任何花哨的东西,那么 Keras 会做得很好,因为您不会遇到任何 TensorFlow 障碍。但如果你想这样做,那么 Pytorch 可能会更顺畅。

(3) 训练模型

在 Keras 中训练模型非常简单!只需一个简单的 .fit()。

history = model.fit_generator(
   generator=train_generator,
   epochs=10,
   validation_data=validation_generator)

在 Pytorch 中训练模型包括几个步骤:

  • 在每批训练开始时初始化梯度;

  • 运行 forward 模式;

  • 运行反向传播

  • 计算损失并更新权重

for epoch in range(2):
   # loop over the dataset multiple times    
   running_loss = 0.0
   for i, data in enumerate(trainloader, 0):
       # Get the inputs; data is a list of [inputs, labels]
       inputs, labels = data        
       # (1) Initialise gradients
       optimizer.zero_grad()        
       # (2) Forward pass
       outputs = net(inputs)
       loss = criterion(outputs, labels)        
       # (3) Backward
       loss.backward()        
       # (4) Compute the loss and update the weights
       optimizer.step()

仅仅运行训练就需要很多步骤!

我想这样你总是知道发生了什么。同时,对于训练不同的模型,这些模型训练步骤基本上保持不变,这是完全没有必要的。

(4) 控制CPU vs GPU模式

如果您安装了 tensorflow-gpu,则在 Keras 中默认启用并完成使用 GPU。然后,如果您希望将某些操作移至 CPU,您可以使用下面代码来完成。

with tf.device('/cpu:0'):
   y = apply_non_max_suppression(x)

对于 Pytorch,您必须为每个 torch 张量和 numpy 变量显式启用 GPU。这会使代码混乱,如果您在 CPU 和 GPU 之间来回移动以进行不同的操作,可能会有点容易出错。

例如,要将我们之前的模型转移到 GPU 上运行,我们必须执行以下操作:

# Get the GPU device
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
# Transfer the network to GPU
net.to(device)
# Transfer the inputs and labels to GPU
inputs, labels = data[0].to(device), data[1].to(device)

Keras 以其简单性和良好的默认设置在这里获得了胜利。

选择框架的一般建议

我通常给出的建议是从 Keras 入手。

Keras 绝对是最容易使用、理解和快速启动和运行的框架。您不必担心 GPU 设置、摆弄抽象代码或通常做任何复杂的事情。您甚至可以在不接触任何一行 TensorFlow 的情况下执行自定义层和损失函数等操作。

如果您确实开始着手深入研究深度网络的更细粒度的方面,或者正在实施非标准的东西,那么 Pytorch 是您的首选框架。这会比 Keras 多一些额外的工作,但不会多到减慢你的速度。您仍然可以快速实施、训练和测试您的网络,并且还可以轻松调试!

·  END  ·

HAPPY LIFE

e8659352c9a76f1a65b792f1128b4d42.png

猜你喜欢

转载自blog.csdn.net/weixin_38739735/article/details/128246418
今日推荐