PyTorch 2.0 チュートリアル : 学習 : テンソル (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 03/19/2023 (2.0.0)
* 本ページは、PyTorch 2.0 Tutorials の以下のページを翻訳した上で適宜、補足説明したものです:
- Learning PyTorch : Tensors
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
- 人工知能研究開発支援
- 人工知能研修サービス(経営者層向けオンサイト研修)
- テクニカルコンサルティングサービス
- 実証実験(プロトタイプ構築)
- アプリケーションへの実装
- 人工知能研修サービス
- PoC(概念実証)を失敗させないための支援
- お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
◆ お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。
- 株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション
- sales-info@classcat.com ; Website: www.classcat.com ; ClassCatJP
PyTorch 2.0 チュートリアル : 学習 : テンソル
テンソルは配列や行列に非常に類似した特別なデータ構造です。PyTorch では、モデルの入出力、そしてモデルのパラメータをエンコードするためにテンソルを使用します。
テンソルは NumPy の ndarray に類似しています、テンソルが計算を高速化する GPU や他の特別なハードウェア上で実行できることを除いて。ndarray に馴染みがあれば、テンソル API で居心地が良いでしょう。そうでないなら、この簡単な API ウォークスルーに一緒についてきてください。
import torch
import numpy as np
テンソル初期化
テンソルは様々な方法で初期化できます。以下の例を見てください :
データから直接的に
テンソルはデータから直接的に作成できます。データ型は自動的に推論されます。
data = [[1, 2], [3, 4]]
x_data = torch.tensor(data)
NumPy 配列から
テンソルは NumPy 配列から作成できます (そして vice versa – Bridge with NumPy 参照)。
np_array = np.array(data)
x_np = torch.from_numpy(np_array)
他のテンソルから :
新しいテンソルは引数のテンソルのプロパティ (shape, datatype) を保持します、明示的に override されない限りは。
x_ones = torch.ones_like(x_data) # retains the properties of x_data
print(f"Ones Tensor: \n {x_ones} \n")
x_rand = torch.rand_like(x_data, dtype=torch.float) # overrides the datatype of x_data
print(f"Random Tensor: \n {x_rand} \n")
Ones Tensor: tensor([[1, 1], [1, 1]]) Random Tensor: tensor([[0.5162, 0.5335], [0.7114, 0.5971]])
ランダム or 定数値で :
shape はテンソルの次元のタプルです。下の関数では、それは出力テンソルの次元性を決定します。
shape = (2, 3,)
rand_tensor = torch.rand(shape)
ones_tensor = torch.ones(shape)
zeros_tensor = torch.zeros(shape)
print(f"Random Tensor: \n {rand_tensor} \n")
print(f"Ones Tensor: \n {ones_tensor} \n")
print(f"Zeros Tensor: \n {zeros_tensor}")
Random Tensor: tensor([[0.8826, 0.2115, 0.5840], [0.0444, 0.2227, 0.7966]]) Ones Tensor: tensor([[1., 1., 1.], [1., 1., 1.]]) Zeros Tensor: tensor([[0., 0., 0.], [0., 0., 0.]])
テンソルの属性
テンソルの属性はそれらの shape, データ型とそれらがストアされるデバイスを記述します。
tensor = torch.rand(3, 4)
print(f"Shape of tensor: {tensor.shape}")
print(f"Datatype of tensor: {tensor.dtype}")
print(f"Device tensor is stored on: {tensor.device}")
Shape of tensor: torch.Size([3, 4]) Datatype of tensor: torch.float32 Device tensor is stored on: cpu
テンソルの演算
転置、インデキシング、スライシング、算術演算、線形代数、ランダムサンプリング等を含む、100 を越えるテンソルの演算は ここ で包括的に説明されています。
それらの各々は GPU 上で (通常は CPU 上よりも速いスピードで) 実行できます。
# We move our tensor to the GPU if available
if torch.cuda.is_available():
tensor = tensor.to('cuda')
print(f"Device tensor is stored on: {tensor.device}")
Device tensor is stored on: cuda:0
リストから演算の幾つかを試します。NumPy API に馴染みがあるならば、テンソル API を利用するのが容易であることを見い出すでしょう。
標準的な numpy-like なインデキシングとスライシング
tensor = torch.ones(4, 4)
tensor[:,1] = 0
print(tensor)
tensor([[1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.]])
テンソルの結合
与えられた次元に沿ってテンソルのシークエンスを結合するために torch.cat を使用できます。torch.stack も見てください、torch.cat とは微妙に異なるもう一つのテンソル結合 op です。
t1 = torch.cat([tensor, tensor, tensor], dim=1)
print(t1)
tensor([[1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.], [1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.], [1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.], [1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.]])
テンソルの乗算
# This computes the element-wise product
print(f"tensor.mul(tensor) \n {tensor.mul(tensor)} \n")
# Alternative syntax:
print(f"tensor * tensor \n {tensor * tensor}")
tensor.mul(tensor) tensor([[1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.]]) tensor * tensor tensor([[1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.]])
これは 2 つのテンソル間の行列乗算を計算します。
print(f"tensor.matmul(tensor.T) \n {tensor.matmul(tensor.T)} \n")
# Alternative syntax:
print(f"tensor @ tensor.T \n {tensor @ tensor.T}")
tensor.matmul(tensor.T) tensor([[3., 3., 3., 3.], [3., 3., 3., 3.], [3., 3., 3., 3.], [3., 3., 3., 3.]]) tensor @ tensor.T tensor([[3., 3., 3., 3.], [3., 3., 3., 3.], [3., 3., 3., 3.], [3., 3., 3., 3.]])
In-place 演算
_ サフィックスを持つ演算は in-place です。例えば: x.copy_(y), x.t_() は x を変更します。
print(tensor, "\n")
tensor.add_(5)
print(tensor)
tensor([[1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.]]) tensor([[6., 5., 6., 6.], [6., 5., 6., 6.], [6., 5., 6., 6.], [6., 5., 6., 6.]])
Note
in-place 演算はメモリを節約しますが、履歴の直ちの損失のために導関数を計算するとき問題になる可能性があります。そのため、それらの使用は奨励されません。
Bridge with NumPy
CPU 上のテンソルと NumPy 配列はそれらの基礎的なメモリ位置を共有できて、そして一つの変更は他方を変更します。
テンソル to NumPy 配列
t = torch.ones(5)
print(f"t: {t}")
n = t.numpy()
print(f"n: {n}")
t: tensor([1., 1., 1., 1., 1.]) n: [1. 1. 1. 1. 1.]
テンソル内の変更は NumPy 配列に反映します。
t.add_(1)
print(f"t: {t}")
print(f"n: {n}")
t: tensor([2., 2., 2., 2., 2.]) n: [2. 2. 2. 2. 2.]
NumPy 配列 to テンソル
n = np.ones(5)
t = torch.from_numpy(n)
NumPy 配列内の変更はテンソルに反映します。
np.add(n, 1, out=n)
print(f"t: {t}")
print(f"n: {n}")
t: tensor([2., 2., 2., 2., 2.], dtype=torch.float64) n: [2. 2. 2. 2. 2.]
以上