はじめに
今更になってAIの勉強を始めたいと思ったため、PyTorchのチュートリアルを読んで学習をしました。
この記事では、PyTorchのチュートリアルの内容を日本語に翻訳して、一部情報を追記しながらまとめていきます。
私の実行環境は下記のとおりです。
Debian 13
Python 3.11.9
PyTorch 2.4.1
Tensorとは
Tensorとは、配列や行列によく似たPyTorch独自のデータ構造です。
PyTorchではモデルへの入力や出力、パラメータの調整にこれを使います。
Tensorの利点として以下が挙げられます。
- GPUやハードウェアアクセラレータ上に配置可能
- 学習に必要な自動微分に最適化されている
Tensorの生成方法
必要なライブラリのインポート
import torch
import numpy as np
データから直接生成する
tensor()を使うことで、リストや数値から直接Tensorを生成することができます。
data = [[1,2],[3,4]]
x_data = torch.tensor(data) # Tensor([[1,2],[3,4]])
x_num = torch.tensor(1.) # Tensor(1.)
numpy配列から生成する
numpy配列からもTensorは作成することができます。
numpy配列とTensorはメモリを共有しているため、どちらか一方を変更するともう一方も変更されます
np_arr = np.array(data)
x_np = tensor.from_numpy(np_arr)
x_np[0][1] = 100
print(np_arr) # array([[1,100],[3,4]])
print(x_np) # tensor([[1,100],[3,4]])
その他の生成方法
shapeを指定して、要素がランダムや1のTensorを作成することもできます。
shapeを指定する以外では、Tensorを引数に渡すことでそのshapeをコピーすることができます。
x_ones = torch.ones_like(x_data) # tensor([[1,1],[1,1]])
x_rand = torch.rand_like(x_data, dtype=torch.float) # tensor([[0.30,0.30],[0.87,0.50]])
shape = (2,3,)
rand_tensor = torch.rand(shape) # tensor([[0.81,0.39,0.04],[0.11,0.57,0.74]])
ones_tensor = torch.ones(shape) # tensor([[1,1,1],[1,1,1]])
zeros_tensor = torch.zeros(shape) # tensor([[0,0,0],[0,0,0]])
Tensorが持つ属性
作成したTensorは以下の3つの属性をインスタンス変数として持っています。
- shape
- 作成したTensorの形状。reshape()を使うことで形状を変更することが可能。
- dtype
- TensorのDataType。作成する際に指定をしなければ、データから推論される。
- device
- Tensorが配置されるデバイス。デフォルトではcpu上に配置される。
TensorをGPU上に配置するには、以下のコードを実行する。
このコードでは、まずcudaが有効化されているかを確認し、有効化されている場合はto()
メソッドを使用してTensorをGPU上にコピーする。
ここでTensorは元の値がコピーされるため、numpy配列とのメモリの共有はされなくなる。
tensor = torch.rand(4)
if torch.cuda.is_available():
tensor = tensor.to("cuda")
Tensorに対する演算
Tensorに対する演算は100以上定義されているため、ここではよく利用されるものを抜粋します。
詳しくはこちらを参照してください。
行、カラムの抽出、Tensorの結合
PyTorchではnumpyと似た方法で行やカラムの抽出を行うことができる。
以下にコード例を記載する。
tensor = torch.ones(4,4)
# 1行目の抽出
tensor[0]
# 1列目の抽出
tensor[:,0]
# 最後尾のカラムの抽出
tensor[...,-1]
# Tensorの結合
torch.cat([tensor,tensor], dim=1) # dim=0で縦に結合、dim=1で横に結合する
算術演算
転置行列はtensor.T
とすることで求まります。
tensor = torch.rand(2,2)
transpose = tensor.T
次のコードでは行列の積を求めています。
行列の積の求め方はいくつかあり、下のy1~y3はどれも同じ結果です。
y1 = tensor @ tensor.T
y2 = tensor.matmul(tensor.T)
y3 = torch.zeros_like(y1) # 出力に使用する変数の定義
torch.matmul(tensor, tensor.T, out=y3)
次のコードでは成分ごとの積を求めています。
下のz1~z3はどれも同じ結果になります。
numpy同様、スカラー値やshapeの違うTensorも上手く変形して計算してくれます。
z1 = tensor * tensor
z2 = tensor.mul(tensor)
z3 = torch.zeros_like(tensor)
torch.mul(tensor, tensor, out=z3)
プリミティブ型への変換
Tensorを集約するなどして単一要素に形状を変化させたとき、item()
メソッドを使用することでpythonのプリミティブ型に変換することができます。
agg = tensor.sum()
agg_item = agg.item()
type(agg_item) # <class 'float'>
破壊的な演算
PyTorchでは演算結果を新しいTensorで返す、非破壊的な演算が主ですが、
メソッドの末尾に_
を付けることで、Tensorの値を変化させる破壊的な演算を行うことができます。
以下では各要素に5を加えるsum
メソッドを破壊的な演算に変更しています。
tensor.add_(5)
Numpyとの相互変換
TensorとNumpyは下記のようにして相互に変換することができます。
# Numpy -> Tensor
np_arr = numpy.array([1,2,3,4])
tensor = torch.from_numpy(np_arr)
# Tensor -> Numpy
np_arr = tensor.numpy()
最後に
稚拙な説明でしたが、これでTensorについての説明は終わりです。
次はモデルの学習に使用するDataLoaderとDatasetについて解説していきます。
いいねやご意見をぜひお願いします。
次の記事