深度学习|TensorFlow惊现大bug(网友(这是逼着我们用PyTorch啊!))

机器之心报道
参与:魔王、陈萍
本文转载自机器之心

诞生五年的 TensorFlow 出现大 bug,使用对应训练方式得到的模型甚至论文结果可能受到波及,然而相关 issue 提交 24 天后依然没有 TensorFlow 开发团队的处理。用户表示很失望,「怒而转用 PyTorch」。在事情发酵后,TensorFlow 团队终于回复了,表示已经在改,但对应的功能将在 2.4 版本中才能用。
【深度学习|TensorFlow惊现大bug(网友(这是逼着我们用PyTorch啊!))】谷歌团队 2015 年发布的 TensorFlow 框架是目前机器学习领域最流行的框架之一。虽然后起之秀 PyTorch 奋起直追,但 TensorFlow 框架的使用者仍然众多。
TensorFlow 经常被吐槽难用、新版本也常常收到差评,但不管怎样,已经诞生五年之久的 TensorFlow 应该不会有什么太大的 bug 吧?然而,事实似乎并非如此。
最近,机器学习工程师 Santosh Gupta 在使用 TensorFlow 时发现了一个问题:使用 Keras 功能 API 创建的模型自定义层中的权重无法进行梯度更新。
issue 详情:https://github.com/tensorflow/tensorflow/issues/40638
这个帖子在 reddit 上引起了热议,网友纷纷表示:「这是在逼我用 PyTorch!」
到底是什么惊天大 bug?
那么这个令人震惊的 bug 到底是什么呢?
Santosh Gupta 对此的描述是:由于 Tensorflow 的缺陷,阻止了 Keras 功能 API 创建模型的自定义层中权重的梯度更新,从而使这些权重基本上保持无法更新状态。
而我们都知道,梯度更新对于训练神经网络来说相当重要,它是保证模型正常训练的前提。
对于使用自定义图层功能性 API 的研究人员来说,他们往往会运行下列程序:
for i, var in enumerate(model.trainable_variables): print(model.trainable_variables[i].name)

这个程序会保存你的训练权重。而 Tensorflow 中出现的这个 bug,导致使用者在功能性 API 中使用自定义图层时 trainable_variables 缺少权重。同样地,这些权重在 non_trainable_variables 也会消失。
但是,如果这些权重不在可训练变量中,则必须冻结这些权重,因为只有这些权重才会接收梯度更新,如下面的 Keras 模型训练代码所示:
gradients = tape.gradient(loss, trainable_variables)# Whether to aggregate gradients outside of optimizer. This requires support # of the optimizer and doesn't work with ParameterServerStrategy and # CentralStroageStrategy. aggregate_grads_outside_optimizer = ( optimizer._HAS_AGGREGATE_GRAD and# pylint: disable=protected-access not isinstance(strategy.extended, parameter_server_strategy.ParameterServerStrategyExtended))if aggregate_grads_outside_optimizer: # We aggregate gradients before unscaling them, in case a subclass of # LossScaleOptimizer all-reduces in fp16. All-reducing in fp16 can only be # done on scaled gradients, not unscaled gradients, for numeric stability. gradients = optimizer._aggregate_gradients(zip(gradients,# pylint: disable=protected-access trainable_variables)) if isinstance(optimizer, lso.LossScaleOptimizer): gradients = optimizer.get_unscaled_gradients(gradients) gradients = optimizer._clip_gradients(gradients)# pylint: disable=protected-access if trainable_variables: if aggregate_grads_outside_optimizer: optimizer.apply_gradients( zip(gradients, trainable_variables), experimental_aggregate_gradients=False) else: optimizer.apply_gradients(zip(gradients, trainable_variables))

通过 Colab gist [1],你可以看到此 bug。
针对上述 bug,也有研究者提出了解决方案。
一种解决方法是改用 Keras 子类创建模型。模型子类化导致所有权重出现在 trainable_variables 中。为了确保功能性 API 和子类模型完全相同,研究人员在每个笔记本底部使用相同的输入对它们进行推论。模型的输出完全相同。但是使用功能性 API 模型进行训练会将许多权重视为冻结。
针对此帖,Keras 之父、谷歌软件工程师 Francois Chollet 也不淡定了。
他表示,「如果第三方写的代码有 bug,且涉及到了 Keras 模型,这并不意味着『Keras 就有 bug』。」
此外,他认为:跟踪自定义图层中训练参数的效果非常好,只需要 7 行代码就可以进行测试。
最新动向:引发热议后,谷歌回复
在 Francois Chollet 发推一小时后,谷歌工程师、TensorFlow 贡献者 Tomer Kaftan 在 GitHub 上回复了该 issue:
深度学习|TensorFlow惊现大bug(网友(这是逼着我们用PyTorch啊!))
文章图片

目前,TensorFlow 的情况是这样的:如果第一个参数中的所有输入来自其他 Keras 层,则当前层进入「functional api construction」模式。但是,你的第一个位置参数输入中包含 None,因此,无法触发「functional api construction」模式。
这导致该层与外部功能模型产生内联(inlined),而不是正确地被纳入外部模型。你可以更改层 API,排除掉输入中的 Nones,这样就可以解决该问题。
功能 API 的主要 cleanup/refactoring 已经大部分完成,以使功能 API 触发机制更加清晰(即使输入中出现任意符号值),并解决其他的一些 issue。但是,该功能将在 TensorFlow 2.4 版本中出现。
对此,issue 发起者 Santosh Gupta 表示同意:
深度学习|TensorFlow惊现大bug(网友(这是逼着我们用PyTorch啊!))
文章图片

网友:震惊,这是逼我用 PyTorch!
在这篇帖子的评论中,有网友复现了这个 bug,并表示震惊:「这个 bug 到底存在多久了?!这是不是意味着用这种方式训练的每一个模型都失效了,基于这些模型的每一篇研究论文的结果也会被拖累。」
此外,该网友对 TensorFlow 开发者的维护效率也表示质疑:
Git issue 显示 23 天前就有 TensorFlow 开发者承认了这个 bug 的存在,并将该 issue 指定给另一位开发者,而被指定者并没有查看这个 issue。
这就像一家食品公司 23 天就发现自己的产品中存在大肠杆菌,但是这么多天过去了他们啥都没干。
我见过很多对 TensorFlow 的抱怨,但是之前从未听到过这样的事情。
这件事也引发了开发者们对 TensorFlow 甚至谷歌产品的吐槽:
作为谷歌曾经的拥趸,现在我对它的所有产品感到厌倦。所有事情都半途而废,看不到完成的可能性,也看不到对用户的关注。
TensorFlow 真是糟糕透了。开发团队意识到 PyTorch 正在抢夺他们的用户,但他们仍和以往一样半途而废,没有将资源或 Keras 置于优先级较高的位置,因为他们内部并不使用。文档也很糟糕,是因为任何有自尊心的工程师都不想为写优秀的文档费心吗?
然而,竞争对手 PyTorch 的文档可读性就很强,PyTorch 官方甚至还提供了限时免费的权威官方教程书籍。
或许有一天谷歌也会出现一位像萨提亚 · 纳德拉那样的人物,改变谷歌的内部文化,更加关注用户和产品。而现在,谷歌只是停留在广告业务带来的收益上吃老底,这使得他们忽略了自己在几乎其他所有业务上的无能。
即便在事情引发热议后 TensorFlow 团队进行了回复,但这个 bug 仍有可能对 TensorFlow 造成影响。
下面这句评论或许最能反映广大开发者的心态:
「这将破坏用户对 TensorFlow 的信任,可能有更多的开发者转用 PyTorch。」
参考链接:
https://colab.research.google.com/gist/Santosh-Gupta/40c54e5b76e3f522fa78da6a248b6826/missingtrainablevarsinference_var.ipynb#scrollTo=28bP9FYpILJ9
https://www.reddit.com/r/MachineLearning/comments/hrawam/d_theres_a_flawbug_in_tensorflow_thats_preventing/

深度学习|TensorFlow惊现大bug(网友(这是逼着我们用PyTorch啊!))
文章图片


读者,你好!我们已经组建了微信群,方便大家学习交流!欢迎扫码进群,另外如果群满以后,可以单独加我的微信拉你进群!
深度学习|TensorFlow惊现大bug(网友(这是逼着我们用PyTorch啊!))
文章图片

深度学习|TensorFlow惊现大bug(网友(这是逼着我们用PyTorch啊!))
文章图片

深度学习|TensorFlow惊现大bug(网友(这是逼着我们用PyTorch啊!))
文章图片

    推荐阅读