参考にした本:
テンソルとは
多次元配列のこと。k次元テンソルは、1つの値の位置を特定するのにk個のインデックスが必要になる。
pytorchのテンソルのメリット
・GPUでの高速な計算が可能
・複数のデバイスに計算を分散できる
・計算グラフで計算過程を追跡できる。
準備
macのGPUを使えるようにする。最後にTrueが出れば、OK
# m1のMACでGPUを使えるように設定する
pip install --pre torch torchvision --extra-index-url https://download.pytorch.org/whl/nightly/cpu
# m1のMACでGPUを使えるように設定する
conda install pytorch torchvision torchaudio -c pytorch
# m1のMACでGPUを使えるか確認する
torch.backends.mps.is_available()
import
import torch
テンソルの作成
画像のテンソルをイメージして作成する。
画像は縦横と色(RGB)の3種類の要素から構成されている。
画像の大きさを5✖️5とした場合のテンソルを作る。
img = torch.randn(3,5,5)
img
weightsの作成
例えば、RGBの画像からグレースケールにするにあたって輝度を計算したい場合に、RGBに重みをかけることで求めることができる。
weights = torch.tensor([0.2126,0.7152,0.0722])
weights
画像に重みを掛け合わせるために重みテンソルに影響のない次元を追加する
unsqueezed_wights = weights.unsqueeze(-1).unsqueeze(-1)
weights.shape,unsqueezed_wights.shape
# 結果:(torch.Size([3]), torch.Size([3, 1, 1]))
各色を重みで調整する
img_weights = img_t * unsqueezed_wights
img_weights
画像が10枚の場合(つまりバッチサイズが10の場合)
img2 = torch.randn(10,3,5,5) # (バッチ、RGB、行、列)
img2
テンソルのコピーの作り方
cloneを利用
test = torch.tensor(list(range(9))).view(3,3)
test2 = test.clone()
test2
# 出力結果
# tensor([[0, 1, 2],
# [3, 4, 5],
# [6, 7, 8]])
cloneを利用する理由
以下のコードを実行するとわかる。
結果を見ると、test2だけではなく、testの値も書き換えられている。原因はtestとtest2がCPU上で同じストレージ(場所)を共有しているから。後ほど出てくる転置したテンソルも同じストレージを共有しているのでテンソルが書き換えると、他のサブテンソルも書き換えられるので注意。なぜこのような仕組みをtorchが採用しているかというと、1つのストレージで複数のテンソルを表現できるので効率良くCPUを使えるため。
test = torch.tensor(list(range(9))).view(3,3)
test2 = test
test2[0,1] = 10
print(test2)
print(test)
サイズ、オフセット、ストライド
各要素でテンソルを定義している。
サイズ:各次元の要素の大きさ。
exsample.shape
オフセット:CPU内にテンソルの元となる、1列の数値があるとき、確認したいテンソルの最初の値の位置はその数列のどこにあるかを示す。
c = torch.tensor([[10,4],[4,2],[9,3]])
b = c[2] #ここの値をいじると結果が変わる。
b.storage_offset()
ストライド:データがCPUに保存される場合は0,1,2,3,,,のように1次元のデータで保存される。具体的にストライドは(2, 1)のように表現され、前半の2は2進めば次の行まで行けることを表す。後半の1は次の列に進むために必要な移動を表す。
exsample.stride()
テンソルに名前をつける
img_named = img.refine_names(...,'channels','rows','columns') # ...,は省略の意味。今回の例で言えば前半部分に次元が何個あるかわからないが、後ろから3番目までに名前をつけるという意味
img_named.names # 次元の名前を確認する。ない場合はNoneと表記される。
weights_names = torch.tensor([0.2126,0.7152,0.0722], names=['channels'])
テンソルの転置
2次元の場合
a = torch.ones(3,2)
a_t = a.transpose(0,1) # a.Tでもおk
a.shape, a_t.shape
3次元以上の場合。転置する次元を指定する必要がある
some_t = torch.ones(3,4,5)
transpose_t = some_t.transpose(0,1)
some_t.shape, transpose_t.shape
# 結果:(torch.Size([3, 4, 5]), torch.Size([4, 3, 5]))
GPUにテンソルを置く
Macの場合、結果がTrueだと可能。
torch.backends.mps.is_available()
# 引数のデバイスにmps(macのGPU)を設定する
points_gpu = torch.tensor([[4,1],[5,3],[2,1]], device='mps')
# または、cpuで作成したテンソルをgpuに送る
points = torch.ones(2,3)
points_gpu = points.to(device='mps')
points_gpu
参考サイト