PyTorchの操作方法はNumpyの操作方法と似ています。
そのためNumpyが使用できれば同じような操作方法でPyTrochも扱えるという学習コストの低さが一つのメリットといえます。
しかし、多少の差異はどうしても存在します。
そこで、Numpyの練習に非常に役立つ「100 numpy exercises 」をPyTorchで書き換えることによって、PyTorchの操作方法を学ぶのと同時にNumpyとの類似点や相違点を学んでいきたいと思います。
PyTorchのコードだけでなくNumpyのコードもあわせて紹介していきます。
別記事に他の問題の解法も書いています。
次のリンクにまとめているので、他の問題もあわせて参考にしていただければと思います。
- 66. Considering a (w,h,3) image of (dtype=ubyte), compute the number of unique colors (★★☆)
- 67. Considering a four dimensions array, how to get sum over the last two axis at once? (★★★)
- 68. Considering a one-dimensional vector D, how to compute means of subsets of D using a vector S of same size describing subset indices? (★★★)
- 69. How to get the diagonal of a dot product? (★★★)
- 70. Consider the vector [1, 2, 3, 4, 5], how to build a new vector with 3 consecutive zeros interleaved between each value? (★★★)
66. Considering a (w,h,3) image of (dtype=ubyte), compute the number of unique colors (★★☆)
「(dtype = ubyte)の(w、h、3)画像を考慮して、一意の色の数を計算してください」
PyTorch
w, h = 256, 256 I = torch.randint(0, 4, (h, w, 3)) colors = torch.unique(I.view(-1, 3), dim=0) n = len(colors) print(n)
# Output 64
Numpy
w, h = 256, 256 I = np.random.randint(0, 4, (h, w, 3)).astype(np.ubyte) colors = np.unique(I.reshape(-1, 3), axis=0) n = len(colors) print(n)
# Output 64
67. Considering a four dimensions array, how to get sum over the last two axis at once? (★★★)
「4次元配列の最後の2つの軸の合計を一度に取得してください」
PyTorch
A = torch.randint(0, 10, (3, 4, 3, 4)) sum = A.sum(dim=(-2, -1)) print(sum) sum = A.view(A.size()[:-2] + (-1, )).sum(dim=-1) print(sum)
# Output tensor([[47, 69, 46, 66], [68, 52, 49, 50], [76, 38, 61, 62]]) tensor([[47, 69, 46, 66], [68, 52, 49, 50], [76, 38, 61, 62]])
Numpy
A = np.random.randint(0,10,(3,4,3,4)) sum = A.sum(axis=(-2,-1)) print(sum) sum = A.reshape(A.shape[:-2] + (-1,)).sum(axis=-1) print(sum)
# Output [[63 59 56 47] [63 68 50 71] [67 60 50 67]] [[63 59 56 47] [63 68 50 71] [67 60 50 67]]
68. Considering a one-dimensional vector D, how to compute means of subsets of D using a vector S of same size describing subset indices? (★★★)
「1次元ベクトルDについて、サブセットインデックスを記述する同じサイズのベクトルSを使用して、Dのサブセットの平均を計算してください」
PyTorch
D = torch.distributions.uniform.Uniform(0, 1).sample([100]) S = torch.randint(0, 10, (100, )) D_sums = torch.bincount(S, weights=D) D_counts = torch.bincount(S) D_means = D_sums / D_counts print(D_means)
# Output tensor([0.4601, 0.5256, 0.6136, 0.6511, 0.5553, 0.2704, 0.4001, 0.2308, 0.4230, 0.6285])
Numpy
D = np.random.uniform(0, 1, 100) S = np.random.randint(0, 10, 100) D_sums = np.bincount(S, weights=D) D_counts = np.bincount(S) D_means = D_sums / D_counts print(D_means)
# Output [0.57597679 0.48310766 0.38572511 0.67786808 0.48981223 0.53382379 0.6503257 0.43426519 0.34702275 0.4575979 ]
69. How to get the diagonal of a dot product? (★★★)
「内積の対角の要素を取得してください」
PyTorch
A = torch.distributions.uniform.Uniform(0, 1, (5, 5)).sample([5, 5]) B = torch.distributions.uniform.Uniform(0, 1, (5, 5)).sample([5, 5]) # Slow version torch.diag(torch.matmul(A, B)) # Fast version torch.sum(A * B.T, dim=1) # Faster version torch.einsum("ij,ji->i", A, B)
# Output tensor([1.0592, 1.2846, 1.0278, 0.4763, 1.1954])
Numpy
A = np.random.uniform(0, 1, (5, 5)) B = np.random.uniform(0, 1, (5, 5)) # Slow version np.diag(np.dot(A, B)) # Fast version np.sum(A * B.T, axis=1) # Faster version np.einsum("ij,ji->i", A, B)
# Output array([0.96746301, 1.47904334, 1.58183947, 1.54715639, 1.87035922])
70. Consider the vector [1, 2, 3, 4, 5], how to build a new vector with 3 consecutive zeros interleaved between each value? (★★★)
「ベクトル[1、2、3、4、5]について、各値の間に3つの連続するゼロが交互に配置された新しいベクトルを作成してください」
PyTorch
Z = torch.tensor([1, 2, 3, 4, 5]) nz = 3 Z0 = torch.zeros(len(Z) + (len(Z) - 1) * (nz)) Z0[::nz+1] = Z print(Z0)
# Output tensor([1., 0., 0., 0., 2., 0., 0., 0., 3., 0., 0., 0., 4., 0., 0., 0., 5.])
Numpy
Z = np.array([1, 2, 3, 4, 5]) nz = 3 Z0 = np.zeros(len(Z) + (len(Z) - 1) * (nz)) Z0[::nz+1] = Z print(Z0)
# Output [1. 0. 0. 0. 2. 0. 0. 0. 3. 0. 0. 0. 4. 0. 0. 0. 5.]
リンク