有没有更快的方法来获取 MNIST 数据集的 Local Binary Pattern?

Is there a faster way to get the Local Binary Pattern of the MNIST dataset?

我想知道是否有更快的方法来获取 MNIST 数据集的 LBP 和结果直方图。这将用于手写文本识别,通过我尚未确定的模型..

我已加载 MNIST 数据集并将其拆分为 x、y 训练集和 x、y 测试集,基于 tensorflow 教程。

然后我使用 cv2 反转图像。

从那里我定义了一个函数,使用 skimage 来获取输入图像的 LBP 和相应的直方图

我终于使用了一个经典的for循环来遍历图像,得到它们的直方图,将它们存储在一个单独的列表中,return两个训练的新列表和未改变的标签列表和测试集。

这是加载 MNIST 数据集的函数:

def loadDataset():
    mnist = tf.keras.datasets.mnist
    (x_train, y_train), (x_test, y_test) = mnist.load_data()

    # should I invert it or not?
    x_train = cv2.bitwise_not(x_train)
    x_test = cv2.bitwise_not(x_test)

    return (x_train, y_train), (x_test, y_test)

这里是获取LBP和对应直方图的函数:

def getLocalBinaryPattern(img, points, radius):
    lbp = feature.local_binary_pattern(img, points, radius, method="uniform")
    hist, _ = np.histogram(lbp.ravel(), 
                bins=np.arange(0, points + 3),
                range=(0, points + 2))

    return lbp, hist

最后是迭代图像的函数:

def formatDataset(dataset):
    (x_train, y_train), (x_test, y_test) = dataset

    x_train_hst = []
    for i in range(len(x_train)):
        _, hst = getLocalBinaryPattern(x_train[i], 8, 1)
        print("Computing LBP for training set: {}/{}".format(i, len(x_train)))
        x_train_hst.append(hst)

    print("Done computing LBP for training set!")

    x_test_hst=[]
    for i in range(len(x_test)):
        _, hst = getLocalBinaryPattern(x_test[i], 8, 1)
        print("Computing LBP for test set: {}/{}".format(i, len(x_test)))
        x_test_hst.append(hst)

    print("Done computing LBP for test set!")

    print("Done!")

    return (x_train_hst, y_train), (x_test_hst, y_test)

我知道它会很慢,确实很慢。所以我正在寻找更多的方法来加速它,或者如果已经有一个版本的数据集包含我需要的信息。

我不认为有一种直接的方法可以加速图像的迭代。人们可能期望使用 NumPy 的 vectorize or apply_along_axis 会提高性能,但这些解决方案实际上比 for 循环(或列表理解)慢。

演示

遍历图像的不同选择:

def compr(imgs):
    hists = [getLocalBinaryPattern(img, 8, 1)[1] for img in imgs]
    return hists

def vect(imgs):
    lbp81riu2 = lambda img: getLocalBinaryPattern(img, 8, 1)[1]
    vec_lbp81riu2 = np.vectorize(lbp81riu2, signature='(m,n)->(k)')
    hists = vec_lbp81riu2(imgs)
    return hists

def app(imgs):
    lbp81riu2 = lambda img: getLocalBinaryPattern(img.reshape(28, 28), 8, 1)[1]
    pixels = np.reshape(imgs, (len(imgs), -1))
    hists = np.apply_along_axis(lbp81riu2, 1, pixels)
    return hists

结果:

In [112]: (x_train, y_train), (x_test, y_test) = loadDataset()

In [113]: %timeit -r 3 compr(x_train)
1 loop, best of 3: 14.2 s per loop

In [114]: %timeit -r 3 vect(x_train)
1 loop, best of 3: 17.1 s per loop

In [115]: %timeit -r 3 app(x_train)
1 loop, best of 3: 14.3 s per loop

In [116]: np.array_equal(compr(x_train), vect(x_train))
Out[116]: True

In [117]: np.array_equal(compr(x_train), app(x_train))
Out[117]: True