python - 为什么 tf.concat 比 np.concatenate 和原生 python 列表的“追加”慢得多?如果可能,我们应该避免吗?
问题描述
我正在使用 Tensorflow 实现一个数学库,它tf.concat
经常在内部调用。我很好奇它的速度tf.concat
。为了测试,我创建了以下简单的代码来比较速度tf.concat
,np.concatenate
以及append
原生 python 列表的方法。当然,在下面的例子中,我们可以使用tf.range
andnp.arange
来获得更好的效率。就我而言,我想检查tf.concat
实际数学库中的速度,我需要任意添加元素。
#/usr/bin/python3
import tensorflow as tf
import numpy as np
import time
x_tf = tf.constant([], dtype=tf.dtypes.float32)
x_np = np.array([], dtype=np.float32)
x_list = []
limit = 10000
start_time = time.time()
for i in range(limit):
x_list.append(np.float32(i))
print("Elapsed time: {0}".format(time.time() - start_time))
start_time = time.time()
for i in range(limit):
x_np = np.concatenate((x_np, [i]), axis=0)
print("Elapsed time: {0}".format(time.time() - start_time))
start_time = time.time()
for i in range(limit):
x_tf = tf.concat((x_tf, [i]), axis=0)
print("Elapsed time: {0}".format(time.time() - start_time))
当我同时使用 CPU 和 GPU 进行测试时,Tensorflow 版本最慢,numpy 版本次之。原生 python 数组在很大程度上是最快的。以下是结果。
2021-01-02 22:00:20.438159: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1402] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 11271 MB memory) -> physical GPU (device: 0, name: GeForce GTX TITAN X, pci bus id: 0000:0a:00.0, compute capability: 5.2)
Elapsed time: 0.004985332489013672
Elapsed time: 0.06686067581176758
Elapsed time: 2.0447843074798584
因为速度上的差异是巨大的,所以如果可能的话,似乎最好避免使用 tf.concat。在这种情况下,似乎最好使用 Native Python 列表进行所有处理,并且只将最终列表转换为张量。
谁能告诉我我的理解是否正确并给出一些建议或意见?
解决方案
np.concatenate
正在增长一个数组,这与追加到列表不同;在循环的每一轮中都必须分配一个新的内存块,大小为 n+1,因此如果您一次插入一个项目,列表自然append
会更快。
Numpy 和 tensorflow 针对数组或张量操作进行了优化。例如,您可以在没有循环的情况下创建相同的 numpy 数组:np_array = np.arange(limit)
,这将比您的循环快得多append
。
推荐阅读
- ios - 本机链接错误:架构 x86_64 的 1 个重复符号
- ios - retain scroll position for nested collectionView
- javascript - 如果单击与数据库中特定记录相关的按钮,如何在表中显示一行
- c# - C# switch clause on boolean variable
- scala - Akka 仅保存/保留最后一个状态
- java - 如何在应用服务器上部署简单的 JMS 应用程序?
- list - 在 3 列中列出文本
- python - Python3电子邮件模块中的解码不正确
- mysql - 在 MySQL 5.7 中截断不正确的 DECIMAL 值
- java - Maven 尝试解决依赖关系时出错,无法解决