- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
许多用户都引用它作为切换到 Pytorch 的原因,但我还没有找到理由/解释来牺牲最重要的实用质量、速度来急切执行。
下面是代码基准性能,TF1 与 TF2 - TF1 在任何地方运行 速度提高 47% 到 276% .
我的问题是:在图形或硬件级别,是什么导致了如此显着的放缓?
寻找详细的答案 - 我已经熟悉广泛的概念。 Relevant Git
规范 :CUDA 10.0.130、cuDNN 7.4.2、Python 3.7.4、Windows 10、GTX 1070
基准测试结果 :
更新 :按照以下代码禁用 Eager Execution 无济于事。然而,这种行为是不一致的:有时在图形模式下运行有很大帮助,有时它相对于 Eager 运行得更慢。
基准代码 :
# use tensorflow.keras... to benchmark tf.keras; used GPU for all above benchmarks
from keras.layers import Input, Dense, LSTM, Bidirectional, Conv1D
from keras.layers import Flatten, Dropout
from keras.models import Model
from keras.optimizers import Adam
import keras.backend as K
import numpy as np
from time import time
batch_shape = (32, 400, 16)
X, y = make_data(batch_shape)
model_small = make_small_model(batch_shape)
model_small.train_on_batch(X, y) # skip first iteration which builds graph
timeit(model_small.train_on_batch, 200, X, y)
K.clear_session() # in my testing, kernel was restarted instead
model_medium = make_medium_model(batch_shape)
model_medium.train_on_batch(X, y) # skip first iteration which builds graph
timeit(model_medium.train_on_batch, 10, X, y)
def timeit(func, iterations, *args):
t0 = time()
for _ in range(iterations):
func(*args)
print("Time/iter: %.4f sec" % ((time() - t0) / iterations))
def make_small_model(batch_shape):
ipt = Input(batch_shape=batch_shape)
x = Conv1D(128, 400, strides=4, padding='same')(ipt)
x = Flatten()(x)
x = Dropout(0.5)(x)
x = Dense(64, activation='relu')(x)
out = Dense(1, activation='sigmoid')(x)
model = Model(ipt, out)
model.compile(Adam(lr=1e-4), 'binary_crossentropy')
return model
def make_medium_model(batch_shape):
ipt = Input(batch_shape=batch_shape)
x = Bidirectional(LSTM(512, activation='relu', return_sequences=True))(ipt)
x = LSTM(512, activation='relu', return_sequences=True)(x)
x = Conv1D(128, 400, strides=4, padding='same')(x)
x = Flatten()(x)
x = Dense(256, activation='relu')(x)
x = Dropout(0.5)(x)
x = Dense(128, activation='relu')(x)
x = Dense(64, activation='relu')(x)
out = Dense(1, activation='sigmoid')(x)
model = Model(ipt, out)
model.compile(Adam(lr=1e-4), 'binary_crossentropy')
return model
def make_data(batch_shape):
return np.random.randn(*batch_shape), np.random.randint(0, 2, (batch_shape[0], 1))
最佳答案
更新 8/1730/2020 :TF 2.3 终于做到了:所有案例的运行速度都与之前的任何版本一样快,或者明显更快。
此外,我之前的更新对 TF 不公平;我的 GPU 是罪魁祸首,最近一直过热。如果您看到迭代时间的上升茎图,则这是一个可靠的症状。最后,请参阅关于 Eager vs Graph 的开发人员说明.
这可能是我对这个答案的最后一次更新。模型速度的真实统计数据只能由您在您的设备上找到。
2020 年 5 月 19 日更新 :TF 2.2,使用相同的测试:Eager 速度仅略有提高。大型 Numpy 的绘图 train_on_batch
下面的情况,x 轴是连续拟合迭代;我的 GPU 还没有接近其全部容量,所以怀疑它正在节流,但随着时间的推移迭代确实会变慢。
如上所述,Graph 和 Eager 是 1.56x 和 1.97 倍 分别比它们的 TF1 对应物慢。不确定我会进一步调试这个,因为我正在考虑切换到 Pytorch,因为 TensorFlow 对自定义/低级功能的支持很差。然而,我确实打开了一个 Issue以获得开发人员的反馈。
2020 年 2 月 18 日更新 :我每晚都有 2.1 和 2.1 的板凳;结果喜忧参半。除了一个配置(模型和数据大小)之外的所有配置都与最好的 TF2 和 TF1 一样快或快得多。较慢且显着较慢的是大-大 - 尤其是。在图形执行中( 慢 1.6 倍到 2.5 倍 )。
此外,对于我测试的大型模型,Graph 和 Eager 之间存在极大的可重复性差异 - 无法通过随机性/计算并行性来解释。我目前无法针对每个时间限制为这些声明提供可重现的代码,因此我强烈建议您针对您自己的模型进行测试。
尚未针对这些打开 Git 问题,但我确实对 original 发表了评论。 - 还没有回应。一旦取得进展,我将更新答案。
判决 : 不是,如果你知道你在做什么。但是如果你不这样做,它可能会花费你很多 - 平均需要升级几个 GPU,最坏的情况是多个 GPU。
这个答案 :旨在提供对该问题的高级描述,以及有关如何决定特定于您的需求的培训配置的指南。有关详细的低级描述,包括所有基准测试结果 + 使用的代码,请参阅我的其他答案。
如果我学到了任何信息,我将更新我的答案(s)和更多信息 - 可以为这个问题添加书签/“加星标”以供引用。
问题摘要 :如 confirmed由 TensorFlow 开发人员 Q. Scott Zhu 撰写,TF2 将开发重点放在 Eager 执行和与 Keras 的紧密集成上,其中涉及 TF 源的彻底更改 - 包括图形级别。好处:大大扩展了处理、分发、调试和部署能力。然而,其中一些的代价是速度。
然而,事情要复杂得多。不仅仅是 TF1 与 TF2 - 导致列车速度显着差异的因素包括:
keras
对比 tf.keras
numpy
对比 tf.data.Dataset
与 ... train_on_batch()
对比 fit()
model(x)
对比 model.predict(x)
与 ... train_on_batch()
+ numpy
+ tf.keras
+ TF1 + Eager/Graph train_on_batch()
+ numpy
+ tf.keras
+ TF2 + 图 fit()
+ numpy
+ tf.keras
+ TF1/TF2 + 图 + 大模型和数据 fit()
+ numpy
+ keras
适用于中小型模型和数据fit()
+ numpy
+ tf.keras
+ TF1/TF2 + 渴望train_on_batch()
+ numpy
+ keras
+ TF1 + 渴望tf.python.keras
;它的运行速度可以慢 10-100 倍,并且有很多错误; more infolayers
, models
, optimizers
, & 相关的“开箱即用”用法导入; ops、utils 和相关的“私有(private)”导入很好 - 但可以肯定的是,检查 alt,以及它们是否用于 tf.keras
Conv1D
和 Dense
- 无 RNN、稀疏数据/目标、4/5D 输入和其他配置 numpy
和 tf.data.Dataset
,而存在许多其他格式;查看其他答案 .__dict__
一样简单.相比之下,Graph 需要熟悉特殊的后端功能——这使调试和内省(introspection)的整个过程变得非常复杂。 tf.enable_eager_execution() # TF1; must be done before any model/tensor creation
tf.compat.v1.disable_eager_execution() # TF2; above holds
TF2 中的误导;见
here .
_on_batch()
TF2 中的方法;根据 TF dev 的说法,他们仍然使用较慢的实现,但不是故意的 - 即它需要修复。有关详细信息,请参阅其他答案。 train_on_batch()
,以及调用 fit()
的性能方面迭代地;定制火车循环对很多人都很重要,尤其是对我来说。 keras
之间的差异和 tf.keras
然而,更具戏剧性: 18-40% ,平均。 32%(TF1 和 2)。 (* - 除了 Eager, TF2 OOM'd)on_batch()
recent commit 中的方法,声明速度有所提高 - 将在 TF 2.1 中发布,或者现在可用 tf-nightly
.由于我无法让后者跑起来,将把替补推迟到 2.1。关于python - 为什么 TensorFlow 2 比 TensorFlow 1 慢得多?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58441514/
我正在处理一组标记为 160 个组的 173k 点。我想通过合并最接近的(到 9 或 10 个组)来减少组/集群的数量。我搜索过 sklearn 或类似的库,但没有成功。 我猜它只是通过 knn 聚类
我有一个扁平数字列表,这些数字逻辑上以 3 为一组,其中每个三元组是 (number, __ignored, flag[0 or 1]),例如: [7,56,1, 8,0,0, 2,0,0, 6,1,
我正在使用 pipenv 来管理我的包。我想编写一个 python 脚本来调用另一个使用不同虚拟环境(VE)的 python 脚本。 如何运行使用 VE1 的 python 脚本 1 并调用另一个 p
假设我有一个文件 script.py 位于 path = "foo/bar/script.py"。我正在寻找一种在 Python 中通过函数 execute_script() 从我的主要 Python
这听起来像是谜语或笑话,但实际上我还没有找到这个问题的答案。 问题到底是什么? 我想运行 2 个脚本。在第一个脚本中,我调用另一个脚本,但我希望它们继续并行,而不是在两个单独的线程中。主要是我不希望第
我有一个带有 python 2.5.5 的软件。我想发送一个命令,该命令将在 python 2.7.5 中启动一个脚本,然后继续执行该脚本。 我试过用 #!python2.7.5 和http://re
我在 python 命令行(使用 python 2.7)中,并尝试运行 Python 脚本。我的操作系统是 Windows 7。我已将我的目录设置为包含我所有脚本的文件夹,使用: os.chdir("
剧透:部分解决(见最后)。 以下是使用 Python 嵌入的代码示例: #include int main(int argc, char** argv) { Py_SetPythonHome
假设我有以下列表,对应于及时的股票价格: prices = [1, 3, 7, 10, 9, 8, 5, 3, 6, 8, 12, 9, 6, 10, 13, 8, 4, 11] 我想确定以下总体上最
所以我试图在选择某个单选按钮时更改此框架的背景。 我的框架位于一个类中,并且单选按钮的功能位于该类之外。 (这样我就可以在所有其他框架上调用它们。) 问题是每当我选择单选按钮时都会出现以下错误: co
我正在尝试将字符串与 python 中的正则表达式进行比较,如下所示, #!/usr/bin/env python3 import re str1 = "Expecting property name
考虑以下原型(prototype) Boost.Python 模块,该模块从单独的 C++ 头文件中引入类“D”。 /* file: a/b.cpp */ BOOST_PYTHON_MODULE(c)
如何编写一个程序来“识别函数调用的行号?” python 检查模块提供了定位行号的选项,但是, def di(): return inspect.currentframe().f_back.f_l
我已经使用 macports 安装了 Python 2.7,并且由于我的 $PATH 变量,这就是我输入 $ python 时得到的变量。然而,virtualenv 默认使用 Python 2.6,除
我只想问如何加快 python 上的 re.search 速度。 我有一个很长的字符串行,长度为 176861(即带有一些符号的字母数字字符),我使用此函数测试了该行以进行研究: def getExe
list1= [u'%app%%General%%Council%', u'%people%', u'%people%%Regional%%Council%%Mandate%', u'%ppp%%Ge
这个问题在这里已经有了答案: Is it Pythonic to use list comprehensions for just side effects? (7 个答案) 关闭 4 个月前。 告
我想用 Python 将两个列表组合成一个列表,方法如下: a = [1,1,1,2,2,2,3,3,3,3] b= ["Sun", "is", "bright", "June","and" ,"Ju
我正在运行带有最新 Boost 发行版 (1.55.0) 的 Mac OS X 10.8.4 (Darwin 12.4.0)。我正在按照说明 here构建包含在我的发行版中的教程 Boost-Pyth
学习 Python,我正在尝试制作一个没有任何第 3 方库的网络抓取工具,这样过程对我来说并没有简化,而且我知道我在做什么。我浏览了一些在线资源,但所有这些都让我对某些事情感到困惑。 html 看起来
我是一名优秀的程序员,十分优秀!