1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PyTorchに入門しよう① Tensorの使い方

Last updated at Posted at 2024-09-23

はじめに

今更になって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について解説していきます。
いいねやご意見をぜひお願いします。

次の記事

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?