【问题标题】:keras zca_whitening - no error, no output generatedkeras zca_whitening - 没有错误,没有生成输出
【发布时间】:2017-04-05 18:22:34
【问题描述】:

在使用zca_whitening 时,我的代码卡在某个地方,既没有显示任何错误,也没有显示输出。当我跳过zca_whitening 并应用其他转换时,代码运行完美。我在这里附上代码 sn-p。如果我在这里做错了什么,请帮助我:

datagen = ImageDataGenerator(zca_whitening=True)
datagen.fit(x_train)

其中 >> x_train 是训练图像集 (dim = 50 x 64 x 64 x 3)。运行datagen.fit后,代码没有进一步的输出或错误,似乎进程运行了无限时间。

另一方面,这些转换工作完美:

datagen = ImageDataGenerator(rotation_range=0.90,
    width_shift_range=0.2,
    height_shift_range=0.2,
    fill_mode='nearest',
    horizontal_flip=True,
    vertical_flip=True)
datagen.fit(x_train)

这里有什么我遗漏的吗?

【问题讨论】:

  • 你能不能修改 x_train 的形状为 (3,64,64) 然后应用 zca_whitening?
  • 是的,成功了!谢谢@AvijitDasgupta。我想知道为什么它只在 zca_whitening 的情况下有所不同。
  • 那我写这个作为答案,你可以接受。

标签: python python-2.7 image-processing keras


【解决方案1】:

x_train修改为(3, 64, 64).的形状

您可以使用以下代码来做到这一点:x_train = x_train.transpose((2,1,0))

这主要是由于theano和tensorflow后端之间的切换。在 Keras 文档中查看 dim_order

【讨论】:

  • 我也有同样的问题,但从 2020 年开始,这不起作用。通过 x_train 和形状 (3,64,64) 会导致 keras 发出警告,即应该有 4 个维度。制作形状(1,3,64,64) 会导致警告说不应该有64 个颜色通道。你能再给点建议吗?
  • 尝试制作 (1, 64, 64, 3)
【解决方案2】:

我不同意@Avjiit 的观点,即问题是由于形状错误造成的。这个问题很常见,因为 keras 主要贡献者 confirmed 问题是 zca 计算需要非常非常长的时间,因为它 uses numpy.linalg.svd() 即使在矩阵上计算量也很大(n * m * 3) , n~m~100。

有一些方法可以计算 svd 的快速近似值,例如 scikitlearn 的随机 svd、irlb 的截断 svd、Lanczos 方法 svd,但它们并不总是在数值上稳定。

我想我找到了另一种非常简单的方法,它非常快,并且给出的结果与标准方法完全相同!如果您有一个形状为 (m x n) 的数据矩阵,其中 m 远小于 n - 例如,它会有所帮助。您的图像(m~1000)比像素数(n~100 x 100 x 3 = 30000 像素)少得多。在这种情况下,keras 将使用sigma.shape=(30000,30000) 计算linalg.svd(sigma),这在计算上太费力并且需要很长时间。但在一个很好的近似值中,您可以在 (mxm) 矩阵上计算它,而不是在 (nxn) 矩阵上计算 svd,只需旋转输入数据 X 或翻转 sigma 计算的顺序看起来像 @987654337 @。使用这种方法,计算只需大约 ca。 10 秒,如果 m~1000 和 n~30000。好消息是linalg.svd(sigma) 的特征向量在两种情况下都是相同的,直到一个因子,请参阅here,幻灯片 30。您可以在您的数据集或使用 from keras.datasets import cifar10 的内置 cifer 集上进行测试.

数学证明可以在herehere 中找到。为了直观起见,我分享了这些图片:

以下是用于创建 zca 计算的修改后的 keras 代码。您可以使用它来修改位于here 的 keras zca 代码。我所做的修改是在需要时放置用于转置数据矩阵的 if 子句:

from keras.datasets import cifar10
import numpy as np
from scipy import linalg

(X_train, y_train), (X_test, y_test) = cifar10.load_data()
X = X_train[:1000]
flat_x = np.reshape(x, (x.shape[0], x.shape[1] * x.shape[2] * x.shape[3]))

# normalize x:
flat_x = flat_x / 255.
flat_x = flat_x - flat_x.mean(axis=0)

# CHANGES HAPPEN BELOW.
# if m>n execute the svd as usual
if flat_x.shape[0] => flat_x.shape[1]:
    sigma = np.dot(flat_x.T, flat_x) / flat_x.shape[0]
    u, s, _ = linalg.svd(sigma)
# and if m<n do the trnaspose trick
if flat_x.shape[0] < flat_x.shape[1]:
    sigma = np.dot(flat_x, flat_x.T) / flat_x.shape[0]
    u, s, _ = linalg.svd(sigma)
    u = np.dot(flat_x.T, u) / np.sqrt(s*flat_x.shape[0])

s_inv = 1. / np.sqrt(s[np.newaxis] + 0.1) # the 0.1 is the epsilon value for zca
principal_components = (u * s_inv).dot(u.T)
whitex = np.dot(flat_x, principal_components)

【讨论】:

    猜你喜欢
    • 2019-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-24
    • 2018-09-09
    • 1970-01-01
    • 2012-08-02
    • 2017-02-24
    相关资源
    最近更新 更多