PyTorchの操作方法はNumpyの操作方法と似ています。
そのためNumpyが使用できれば同じような操作方法でPyTrochも扱えるという学習コストの低さが一つのメリットといえます。
しかし、多少の差異はどうしても存在します。
そこで、Numpyの練習に非常に役立つ「100 numpy exercises 」をPyTorchで書き換えることによって、PyTorchの操作方法を学ぶのと同時にNumpyとの類似点や相違点を学んでいきたいと思います。
PyTorchのコードだけでなくNumpyのコードもあわせて紹介していきます。
別記事に他の問題の解法も書いています。
次のリンクにまとめているので、他の問題もあわせて参考にしていただければと思います。
- 16. How to add a border (filled with 0's) around an existing array? (★☆☆)
- 17. What is the result of the following expression? (★☆☆)
- 18. Create a 5x5 matrix with values 1,2,3,4 just below the diagonal (★☆☆)
- 19. Create a 8x8 matrix and fill it with a checkerboard pattern (★☆☆)
- 20. Consider a (6,7,8) shape array, what is the index (x,y,z) of the 100th element?
16. How to add a border (filled with 0's) around an existing array? (★☆☆)
「すでにある配列の周りに0の要素を追加してください」
PyTorch
Z = torch.ones((5, 5)) Z = torch.nn.functional.pad(Z, pad=(1, 1, 1, 1), mode='constant', value=0) print(Z)
# Output tensor([[0., 0., 0., 0., 0., 0., 0.], [0., 1., 1., 1., 1., 1., 0.], [0., 1., 1., 1., 1., 1., 0.], [0., 1., 1., 1., 1., 1., 0.], [0., 1., 1., 1., 1., 1., 0.], [0., 1., 1., 1., 1., 1., 0.], [0., 0., 0., 0., 0., 0., 0.]])
Numpy
Z = np.ones((5, 5)) Z = np.pad(Z, pad_width=1, mode='constant', constant_values=0) print(Z)
# Output [[0. 0. 0. 0. 0. 0. 0.] [0. 1. 1. 1. 1. 1. 0.] [0. 1. 1. 1. 1. 1. 0.] [0. 1. 1. 1. 1. 1. 0.] [0. 1. 1. 1. 1. 1. 0.] [0. 1. 1. 1. 1. 1. 0.] [0. 0. 0. 0. 0. 0. 0.]]
17. What is the result of the following expression? (★☆☆)
「次の式の結果を確認してください」
0 * np.nan np.nan == np.nan np.inf > np.nan np.nan - np.nan np.nan in set([np.nan]) 0.3 == 3 * 0.1
PyTorchの場合は、np.nan
の代わりにtorch.tensor(float('nan'))
というnanを格納したTensorで評価しています。
PyTorch
print(0 * torch.tensor(float('nan'))) print(torch.tensor(float('nan')) == torch.tensor(float('nan'))) print(torch.tensor(float('inf')) > torch.tensor(float('nan'))) print(torch.tensor(float('nan')) - torch.tensor(float('nan'))) print(torch.tensor(float('nan')) in set([torch.tensor(float('nan'))])) print(torch.tensor(0.3) == torch.tensor(3) + 0.1)
# Output tensor(nan) tensor(False) tensor(False) tensor(nan) False tensor(False)
Numpy
print(0 * np.nan) print(np.nan == np.nan) print(np.inf > np.nan) print(np.nan - np.nan) print(np.nan in set([np.nan])) print(0.3 == 3 * 0.1)
# Output nan False False nan True False
18. Create a 5x5 matrix with values 1,2,3,4 just below the diagonal (★☆☆)
「対角成分のすぐ下の要素が1, 2, 3, 4な5×5の配列を作成してください」
PyTorch
Z = torch.diag(1 + torch.arange(4), diagonal=-1) print(Z)
# Output tensor([[0, 0, 0, 0, 0], [1, 0, 0, 0, 0], [0, 2, 0, 0, 0], [0, 0, 3, 0, 0], [0, 0, 0, 4, 0]])
Numpy
Z = np.diag(1+np.arange(4),k=-1) print(Z)
# Output [[0 0 0 0 0] [1 0 0 0 0] [0 2 0 0 0] [0 0 3 0 0] [0 0 0 4 0]]
19. Create a 8x8 matrix and fill it with a checkerboard pattern (★☆☆)
「8×8でチェックボードパターンの配列を作成してください」
PyTorch
Z = torch.zeros((8, 8),dtype=torch.int32) Z[1::2,::2] = 1 Z[::2,1::2] = 1 print(Z)
# Output tensor([[0, 1, 0, 1, 0, 1, 0, 1], [1, 0, 1, 0, 1, 0, 1, 0], [0, 1, 0, 1, 0, 1, 0, 1], [1, 0, 1, 0, 1, 0, 1, 0], [0, 1, 0, 1, 0, 1, 0, 1], [1, 0, 1, 0, 1, 0, 1, 0], [0, 1, 0, 1, 0, 1, 0, 1], [1, 0, 1, 0, 1, 0, 1, 0]], dtype=torch.int32)
Numpy
Z = np.zeros((8, 8),dtype=int) Z[1::2,::2] = 1 Z[::2,1::2] = 1 print(Z)
# Output [[0 1 0 1 0 1 0 1] [1 0 1 0 1 0 1 0] [0 1 0 1 0 1 0 1] [1 0 1 0 1 0 1 0] [0 1 0 1 0 1 0 1] [1 0 1 0 1 0 1 0] [0 1 0 1 0 1 0 1] [1 0 1 0 1 0 1 0]]
20. Consider a (6,7,8) shape array, what is the index (x,y,z) of the 100th element?
「6×7×8の多次元配列で、100番目の要素のインデックス(x, y, z)を取得してください」
PyTorch
私の今使っているバージョンにはunravel_index関数
がなかったので、以下のコードを使用しています。
def unravel_indices(indices, shape): r"""Converts flat indices into unraveled coordinates in a target shape. Args: indices: A tensor of (flat) indices, (*, N). shape: The targeted shape, (D,). Returns: The unraveled coordinates, (*, N, D). """ coord = [] for dim in reversed(shape): coord.append(indices % dim) indices = indices // dim coord = torch.stack(coord[::-1], dim=-1) return coord def unravel_index(indices, shape): r"""Converts flat indices into unraveled coordinates in a target shape. This is a `torch` implementation of `numpy.unravel_index`. Args: indices: A tensor of (flat) indices, (N,). shape: The targeted shape, (D,). Returns: A tuple of unraveled coordinate tensors of shape (D,). """ coord = unravel_indices(indices, shape) return tuple(coord) print(unravel_index(torch.arange(100), (6, 7, 8))[99])
# Output tensor([1, 5, 3])
Numpy
print(np.unravel_index(99, (6, 7, 8)))
# Output (1, 5, 3)
リンク