logo

ジュリア、Python(NumPy、PyTorch)の配列の次元の違い 📂ジュリア

ジュリア、Python(NumPy、PyTorch)の配列の次元の違い

概要

JuliaとNumPy、PyTorch(以降、便宜上Pythonと呼ぶ)の高次元配列を扱う際、各次元が意味するものが異なるため注意が必要だ。この違いはJuliaの配列が列優先であり、Pythonの配列が行優先であるために生じる。ちなみに同じ列優先のMatlabはJuliaとの違いがないため、Matlabに慣れているユーザーは特に注意する必要はないが、Pythonに慣れている人はインデックスの間違いに注意しよう。

  • 配列の次元とベクトルの次元を混同して使っているので、しっかり理解しよう。

説明

1次元配列

Juliaでは、サイズがnnの配列はnn次元の列ベクトルを意味する。

julia> ones(3)
3-element Vector{Float64}:
 1.0
 1.0
 1.0

Pythonでは、サイズがnnの配列はnn次元の行ベクトルを意味する。

>>> import numpy as np
>>> np.ones(3)
array([1., 1., 1.])

列か行かの違いはあるが、1次元配列であるため、インデックスに特に注意する点はない。

2次元配列

表面上は2次元までは違いがないように見える。しかし、その意味は異なるので注意が必要だ。まず、Juliaでは配列の次元が後方に伸びる。つまり(m,n)(m,n)配列とは、サイズがmmの1次元配列(列ベクトル)がnn個あることを意味する。具体的には(3,2)(3,2)配列は、3次元の列ベクトルが2個あるということだ。

julia> ones(3,2)
3×2 Matrix{Float64}:
 1.0  1.0
 1.0  1.0
 1.0  1.0

また、Juliaは「列優先」なので、成分のインデックスは上から下へ先に、そして左から右に大きくなる。

julia> A = reshape(range(1,6), (3,2))
3×2 reshape(::UnitRange{Int64}, 3, 2) with eltype Int64:
 1  4
 2  5
 3  6

julia> for i ∈ 1:6
           println(A[i])
       end
1
2
3
4
5
6

一方、Pythonの配列では新しい次元が前方へ伸びる。つまり(m,n)(m,n)配列とは、サイズがnnの1次元配列(行ベクトル)がmm個あるということだ。以下の結果からは、配列が行単位で区分されているのがわかる。

>>> np.ones([3,2])
array([[1., 1.],
       [1., 1.],
       [1., 1.]])

つまり、見た目だけでは、JuliaとPythonの(m,n)(m,n)配列はどちらもm×nm \times nの行列だが、列優先/行優先の違いのためにインデックスの順序が異なる。インデックスの方向はJuliaでは上下左右、Pythonでは左右上下だ。

# julia에서 2차원 배열의 인덱싱은 위에서 아래로, 그 다음 좌에서 우로
julia> A = reshape(range(1,6), (3,2))
3×2 reshape(::UnitRange{Int64}, 3, 2) with eltype Int64:
 1  4
 2  5
 3  6

# python에서 2차원 배열의 인덱싱은 좌에서 우로, 그 다음 위에서 아래로 
>>> np.arange(6).reshape(3,2)
array([[0, 1],
       [2, 3],
       [4, 5]])

3次元配列

Juliaでは、配列の新しい次元が後ろに追加されると言った。従って、(m,n,k)(m,n,k)配列は、(m,n)(m,n)配列がkk個あることを意味する。

julia> ones(3,2,4)
3×2×4 Array{Float64, 3}:
[:, :, 1] =
 1.0  1.0
 1.0  1.0
 1.0  1.0

[:, :, 2] =
 1.0  1.0
 1.0  1.0
 1.0  1.0

[:, :, 3] =
 1.0  1.0
 1.0  1.0
 1.0  1.0

[:, :, 4] =
 1.0  1.0
 1.0  1.0
 1.0  1.0

一方、Pythonでは(m,n,k)(m,n,k)配列は、(n,k)(n,k)配列がmm個あるということだ。

>>> np.ones([3,2,4])
array([[[1., 1., 1., 1.],
        [1., 1., 1., 1.]],

       [[1., 1., 1., 1.],
        [1., 1., 1., 1.]],

       [[1., 1., 1., 1.],
        [1., 1., 1., 1.]]])

機械学習で

画像データで、H=hiehtH=\text{hieht}が高さ、W=widthW=\text{width}が幅、C=channelC=\text{channel}がチャンネル数、B=batch sizeB=\text{batch size}がバッチサイズとした場合、PyTorchでは(B,C,H,W)(B,C,H,W)配列であり、Juliaでは(H,W,C,B)(H,W,C,B)である。

環境

  • OS: Windows11
  • バージョン: Julia 1.7.1, Python 3.9.2, numpy 1.19.5