为什么 numpy 向量化不能提高我的代码速度

Why does numpy vectorization not improve the speed of my code

这里是没有使用vectorize的原代码

import tensorflow as tf
import time
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA

(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data(
    path='mnist.npz'
)

x_train = x_train.reshape(60000,-1)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(x_train)
pca = PCA()
pca = PCA(n_components = 16) # or 12      ->       3, 4  filter_size=3
X_pca = pca.fit_transform(X_scaled).reshape(60000, 4, 4, 1)
start = time.time()
X_pca_zero = X_pca[0]
for i in range(1,60000):
    X_pca_expanded = X_pca[i]
    print(tf.image.ssim(X_pca_zero, X_pca_expanded, 255, filter_size=4))
print(time.time()-start)

本质上是比较参考图像和一组图像之间的相似度。我觉得它可以通过矢量化来加速(以避免 for 循环浪费时间)。因此,我使用了 numpy 向量化函数 -

import numpy as np
import tensorflow as tf
import time
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA

(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data(
    path='mnist.npz'
)
def my_func(x_train):
    x_train = x_train.reshape(60000,-1)
    scaler = StandardScaler()
    X_scaled = scaler.fit_transform(x_train)
    pca = PCA()
    pca = PCA(n_components = 16) # or 12      ->       3, 4  filter_size=3
    X_pca = pca.fit_transform(X_scaled).reshape(60000, 4, 4, 1)
    start = time.time()
    X_pca_zero = X_pca[0]
    for i in range(1,6000):
        X_pca_expanded = X_pca[i]
        print(tf.image.ssim(X_pca_zero, X_pca_expanded, 255, filter_size=4))
    print(time.time()-start)

    return 0
np.vectorize(my_func(x_train))

但是,似乎没有任何速度提升。

在 Python 函数调用中,参数在传递给函数之前先进行求值。 np.vectorize 是 Python 需要函数作为参数的函数,returns 是另一个函数。

np.vectorize(my_func(x_train))

运行s my_func(x_train) 在将结果传递给 vectorize 之前。该参数评估会执行所有打印和计时,并且 returns 0。我怀疑它是否会起作用,但是:

In [194]: np.vectorize(0)
Out[194]: <numpy.vectorize at 0x7ff091c36310>

所以它 运行 没有错误,但什么也没做。所有时间都在传递给 np.vectorize.

之前完成

我怀疑您阅读了“矢量化”的魔力,并试图在不阅读其文档的情况下使用类似名称的函数。您不仅错过了性能免责声明,而且还没有学习如何使用它(它确实有它的用途)。它不是某种“编译器”或“矢量化魔法”。

您的大部分代码是 sklearn,而您唯一花时间的是

X_pca_zero = X_pca[0]
for i in range(1,60000):
    X_pca_expanded = X_pca[i]
    print(tf.image.ssim(X_pca_zero, X_pca_expanded, 255, filter_size=4))

我不熟悉 tf.image.ssim 的功能。但它是一个张量流函数,可能很复杂。 运行 6000 次肯定需要很长时间。如果它不允许您一次提供所有 X_pca 值(而不是一个一个地提供),那么您无法加快速度。

我不知道它是什么 returns,但通常我们不会在计时块中包含 print。每次打印调用都会增加计算时间。