更改先通道和后通道之间的图像通道顺序的正确方法是什么?
What is the correct way to change image channel ordering between channels first and channels last?
我这辈子都想不出如何切换图像排序。图像以 (x,x,3) 格式读取,theano 要求它为 (3,x,x) 格式。我尝试更改顺序
numpy.array([img[:,:,i] for i in range(3)])
我想这已经完成了工作,但它既丑陋又我无法弄清楚如何反转它以恢复原始图像。
重新排序数据
您可以使用 numpy.rollaxis 将轴 3 滚动到位置 1(考虑到您将批量大小设置为维度 0)。
np.rollaxis(imagesArray, 3, 1)
但是,如果您使用的是 keras,您可能想要更改其配置或按层定义它。如果您使用的是 Keras,Theano 不需要您提供任何东西。
Keras 可以先配置通道,也可以最后配置通道,此外还允许您在每个单独的层中定义它,因此您不必更改数据。
配置keras
找到 keras.json
文件并更改它。该文件通常安装在 C:\Users\yourusername\.keras
或 ~/.keras
中,具体取决于您的 OS。
根据需要将 "image_data_format": "channels_last"
更改为 "channels_first"
,反之亦然。
通常,使用“channels_last”不会那么麻烦,因为大量其他(非卷积)函数仅在最后一个轴上起作用。
在图层中定义通道顺序。
Keras documentation 包含有关图层参数的所有信息,包括 data_format
参数。
我同意@Qualia 的评论,np.moveaxis(a, source, destination)更容易理解。这完成了工作:
x = np.zeros((12, 12, 3))
x.shape
#yields:
(12, 12, 3)
x = np.moveaxis(x, -1, 0)
x.shape
#yields:
(3, 12, 12)
x = np.zeros((12, 12, 3))
y = np.rollaxis(x, 2, 0)
y.shape
(3, 12, 12)
使用np.moveaxis
是有效的,但我发现np.einsum
要快得多。
x = np.zeros((12,12,3))
%timeit np.moveaxis(x,-1,0)
#yields 7.46 µs ± 312 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit np.einsum('ijk->kij',x)
#yields 1.11 µs ± 31 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
如果您正在寻找最快的选项,请选择 .transpose(...)
。它甚至比 np.einsum
还要快。
img = np.random.random((1000, 1000, 3))
img.shape
# (1000, 1000, 3)
%timeit img.transpose(2, 0, 1)
# 385 ns ± 1.11 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit np.rollaxis(img, -1, 0)
# 2.7 µs ± 50.7 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit np.einsum('ijk->kij', img)
# 2.75 µs ± 31.9 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit np.moveaxis(img, -1, 0)
# 7.26 µs ± 57.8 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
np.allclose(img.transpose(2, 0, 1), np.einsum('ijk->kij', img))
# True
np.allclose(img.transpose(2, 0, 1), np.moveaxis(img, -1, 0))
# True
np.allclose(img.transpose(2, 0, 1), np.rollaxis(img,-1, 0))
# True
我这辈子都想不出如何切换图像排序。图像以 (x,x,3) 格式读取,theano 要求它为 (3,x,x) 格式。我尝试更改顺序
numpy.array([img[:,:,i] for i in range(3)])
我想这已经完成了工作,但它既丑陋又我无法弄清楚如何反转它以恢复原始图像。
重新排序数据
您可以使用 numpy.rollaxis 将轴 3 滚动到位置 1(考虑到您将批量大小设置为维度 0)。
np.rollaxis(imagesArray, 3, 1)
但是,如果您使用的是 keras,您可能想要更改其配置或按层定义它。如果您使用的是 Keras,Theano 不需要您提供任何东西。
Keras 可以先配置通道,也可以最后配置通道,此外还允许您在每个单独的层中定义它,因此您不必更改数据。
配置keras
找到 keras.json
文件并更改它。该文件通常安装在 C:\Users\yourusername\.keras
或 ~/.keras
中,具体取决于您的 OS。
根据需要将 "image_data_format": "channels_last"
更改为 "channels_first"
,反之亦然。
通常,使用“channels_last”不会那么麻烦,因为大量其他(非卷积)函数仅在最后一个轴上起作用。
在图层中定义通道顺序。
Keras documentation 包含有关图层参数的所有信息,包括 data_format
参数。
我同意@Qualia 的评论,np.moveaxis(a, source, destination)更容易理解。这完成了工作:
x = np.zeros((12, 12, 3))
x.shape
#yields:
(12, 12, 3)
x = np.moveaxis(x, -1, 0)
x.shape
#yields:
(3, 12, 12)
x = np.zeros((12, 12, 3))
y = np.rollaxis(x, 2, 0)
y.shape
(3, 12, 12)
使用np.moveaxis
是有效的,但我发现np.einsum
要快得多。
x = np.zeros((12,12,3))
%timeit np.moveaxis(x,-1,0)
#yields 7.46 µs ± 312 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit np.einsum('ijk->kij',x)
#yields 1.11 µs ± 31 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
如果您正在寻找最快的选项,请选择 .transpose(...)
。它甚至比 np.einsum
还要快。
img = np.random.random((1000, 1000, 3))
img.shape
# (1000, 1000, 3)
%timeit img.transpose(2, 0, 1)
# 385 ns ± 1.11 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit np.rollaxis(img, -1, 0)
# 2.7 µs ± 50.7 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit np.einsum('ijk->kij', img)
# 2.75 µs ± 31.9 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit np.moveaxis(img, -1, 0)
# 7.26 µs ± 57.8 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
np.allclose(img.transpose(2, 0, 1), np.einsum('ijk->kij', img))
# True
np.allclose(img.transpose(2, 0, 1), np.moveaxis(img, -1, 0))
# True
np.allclose(img.transpose(2, 0, 1), np.rollaxis(img,-1, 0))
# True