前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Keras Pytorch大比拼

Keras Pytorch大比拼

作者头像
云水木石
发布2019-07-02 15:15:59
1.4K0
发布2019-07-02 15:15:59
举报

终于结束本次出差,恢复正常的生活节奏。魔都码农的工作热情完全不输帝都码农,弄的我也只好入乡随俗。每天回到酒店已经很晚,洗洗就只想躺下睡觉,真的没啥时间研究新技术。有句话说的好,比你聪明的人,比你还拼,北上广深能领跑全国,也是必然。同时也很佩服那些日更的公号作者,他们是怎么做到年年如一日,保持更新的。我在自律性方面还是差很多,以后要多加强。 在选择深度学习框架时,估计不少人都曾经纠结过选择哪种框架。因此在这里翻译一篇keras和PyTorch的对比文章,原文地址:https://towardsdatascience.com/keras-vs-pytorch-for-deep-learning-a013cb63870d 在这里,我无意引起Keras Pytorch谁强谁弱的纷争,毕竟每种框架都有其独到之处,作为开发者,最佳策略是根据自己的需求选择框架。

对于许多数据科学家、工程师和开发人员来说,TensorFlow是他们深度学习框架的第一选择。TensorFlow 1.0于2017年2月发布,至少可以说,它不是非常用户友好。

在过去几年中,两个主要的深度学习库已经获得了巨大的普及,主要是因为它们比TensorFlow更容易使用:Keras和Pytorch。

译者注:TensorFlow 2.0已经将keras作为主要API,在TensorFlow 1.0中,也可以非常容易的引入Keras API。

本文将列出Keras与Pytorch的4个不同方面,以及为什么您会选择其中一个而不是另一个库。

Keras

Keras本身并不是一个框架,实际上它是一个位于其他Deep Learning框架之上的高级API。目前它支持TensorFlow、Theano和CNTK。

Keras的独到之处在于其易用性。它是迄今为止最容易上手和运行的框架。在Keras中,定义神经网络是直观的,而使用functional API允许开发人员将层定义为函数。

Pytorch

Pytorch是由Facebook的AI研究小组开发的深度学习框架(类似于TensorFlow)。像Keras一样,它也抽象了深度网络编程中大部分容易引起混淆的细节部分。

就高级和低级编码风格而言,Pytorch位于Keras和TensorFlow之间。它比Keras有更多的灵活性和控制力,但与此同时您不必做让人疯狂的声明性编程。

深度学习开发者整天都在争论应该使用哪个框架。一般来说,这取决于个人喜好。但是在做选择时您应该了解Keras和Pytorch的不同特点。

(1) 定义模型的类和函数对比

为了定义深度学习模型,Keras提供了Functional API。使用Functional API,神经网络被定义为一组序列函数,依次应用这些函数。例如,层1的输出是层2的输入:

代码语言:javascript
复制
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提供了层作为构建块,但由于它们位于Python类中,因此它们要在类的 __init__() 方法中引用,并由类的 forward() 方法执行。

代码语言:javascript
复制
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) 张量和计算图与标准数组的对比

Keras API隐藏了许多容易引起混乱的编程细节,定义网络层非常直观,默认设置通常足以让您入门。

只有当您实现一个相当尖端或”特别结构”的模型时,您才真正需要使用低级别的TensorFlow细节API。

棘手的是,当您真正深入到更低级别的TensorFlow代码时,您将获得随之而来的所有具有挑战性的部分!您需要确保所有矩阵乘法都排列正确。哦,甚至不要考虑尝试打印出图层的一个输出,因为这样只会在终端上打印出一个漂亮的Tensor定义。

Pytorch在这些方面倾向于更加宽容。您需要知道每个层的输入和输出大小,但这是一个可以很快掌握的简单方面之一。您不必处理和构建一个您无法在调试中看到的抽象计算图。

译者注:这里实际上是吐槽TensorFlow的张量图并非即时计算,现在TensorFlow引入了eager模式,不再存在此问题。

Pytorch的另一个好处是您可以在Torch 张量和Numpy阵列之间来回切换。如果您需要实现自定义的东西,那么在TF张量和Numpy阵列之间来回转换可能会很麻烦,需要开发人员对TensorFlow会话有充分的了解。

Pytorch互操作实际上要简单得多。您只需要知道两个操作:一个将Torch Tensor(一个Variable对象)切换到Numpy,另一个切换到相反的方向。

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

(3) 训练模型

在Keras训练模型非常容易!只是一个简单的.fit(),即可启动!

代码语言:javascript
复制
history = model.fit_generator(
    generator=train_generator,
    epochs=10,
    validation_data=validation_generator)

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

  1. 在每批次训练开始时初始化梯度
  2. 执行正向传递;
  3. 进行反向传递
  4. 计算损失并更新权重
代码语言:javascript
复制
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 和 GPU 模式

如果安装了tensorflow-gpu,则默认情况下在Keras中会启用并使用GPU。如果您希望将某些操作移动到CPU,则可以通过一行代码做到。

代码语言:javascript
复制
with tf.device('/cpu:0'):
    y = apply_non_max_suppression(x)

对于Pytorch,您必须为每个torch张量和numpy变量明确启用GPU。如果您在CPU和GPU之间来回切换以进行不同的操作,这会使代码变得混乱,并且可能容易出错。

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

代码语言:javascript
复制
# 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来说,这将是一项额外的工作,但不是那么多,以至于它会减慢您的速度。您仍然可以快速实施、训练和测试您的网络,还可以轻松调试!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-06-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 云水木石 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Keras
  • Pytorch
  • (1) 定义模型的类和函数对比
  • (2) 张量和计算图与标准数组的对比
  • (3) 训练模型
  • (4) 控制 CPU 和 GPU 模式
  • 选择框架的建议
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档