【画像処理にも応用可能】PyTorch cumprod_関数:累積積を使って画像解析をレベルアップ
torch.Tensor.cumprod_
は、PyTorchにおけるテンソルの累積積を求める関数です。与えられたテンソルの各要素を、その前の要素との積として計算し、新しいテンソルとして返します。
詳細
この関数の動作は以下の通りです。
- 入力テンソル
input
を受け取ります。 - 指定された次元
dim
に沿ってテンソルの要素を積算します。 - 積算結果を新しいテンソルとして返します。
例
import torch
# サンプルデータ
data = torch.tensor([1, 2, 3, 4, 5])
# 0番目の次元(行方向)に沿って累積積を求める
result = data.cumprod_(dim=0)
print(result)
このコードを実行すると、以下の出力が得られます。
tensor([1, 2, 6, 24, 120])
上記の通り、result
テンソルは data
テンソルの各要素を、その前の要素との積として計算した結果となっています。
オプション
torch.Tensor.cumprod_
は、以下のオプション引数を受け取ります。
out
: 計算結果を出力するテンソルを指定します。デフォルトは新しいテンソルが作成されます。dtype
: 返されるテンソルのデータ型を指定します。デフォルトは入力テンソルのデータ型です。
2つの次元における累積積
この例では、2つの次元における累積積を求めます。
import torch
# サンプルデータ
data = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# 0番目の次元と1番目の次元それぞれに沿って累積積を求める
result1 = data.cumprod_(dim=0)
result2 = data.cumprod_(dim=1)
print(result1)
print(result2)
tensor([[1, 2, 6],
[4, 10, 30],
[7, 28, 84]])
tensor([[1, 2, 3],
[4, 10, 20],
[7, 14, 21]])
説明
result2
は、1番目の次元(列方向)に沿って累積積を求めた結果です。各列の要素は、その前の要素との積として計算されています。result1
は、0番目の次元(行方向)に沿って累積積を求めた結果です。各行の要素は、その前の要素との積として計算されています。
特定のデータ型への変換
この例では、累積積の結果を特定のデータ型に変換します。
import torch
# サンプルデータ
data = torch.tensor([1, 2, 3, 4, 5], dtype=torch.float32)
# 0番目の次元と1番目の次元それぞれに沿って累積積を求める
result1 = data.cumprod_(dim=0, dtype=torch.float64)
result2 = data.cumprod_(dim=1, dtype=torch.int64)
print(result1)
print(result2)
tensor([1.00000000e+00, 2.00000000e+00, 6.00000000e+00,
2.40000000e+01, 1.20000000e+02], dtype=torch.float64)
tensor([[1, 2, 3],
[4, 10, 20],
[7, 14, 21]], dtype=torch.int64)
説明
result2
は、1番目の次元(列方向)に沿って累積積を求めた結果です。結果はtorch.int64
型に変換されています。result1
は、0番目の次元(行方向)に沿って累積積を求めた結果です。結果はtorch.float64
型に変換されています。
この例では、累積積の結果を既存のテンソルに書き込みます。
import torch
# サンプルデータ
data = torch.tensor([1, 2, 3, 4, 5])
result = torch.tensor([0, 0, 0, 0, 0])
# 0番目の次元と1番目の次元それぞれに沿って累積積を求める
data.cumprod_(dim=0, out=result)
data.cumprod_(dim=1, out=result)
print(result)
tensor([1, 2, 6, 24, 120])
cumprod_
関数は、out
引数で指定されたテンソルに結果を書き込みます。result
テンソルは、data
テンソルの累積積結果で初期化されています。
forループによる逐次積算
最もシンプルな代替方法は、forループを使用して要素ごとに逐次的に積算していく方法です。
import torch
def cumprod_naive(data, dim):
result = torch.ones_like(data)
for i in range(data.size(dim)):
result[:, i] = result[:, i - 1] * data[:, i]
return result
# サンプルデータ
data = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# 0番目の次元と1番目の次元それぞれに沿って累積積を求める
result1 = cumprod_naive(data, dim=0)
result2 = cumprod_naive(data, dim=1)
print(result1)
print(result2)
tensor([[1, 2, 6],
[4, 10, 30],
[7, 28, 84]])
tensor([[1, 2, 3],
[4, 10, 20],
[7, 14, 21]])
scan 関数による累積操作
PyTorchには scan
関数が用意されており、累積操作を効率的に実行することができます。
import torch
def cumprod_scan(data, dim):
return torch.scan(torch.mul, data, dim=dim)
# サンプルデータ
data = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# 0番目の次元と1番目の次元それぞれに沿って累積積を求める
result1 = cumprod_scan(data, dim=0)
result2 = cumprod_scan(data, dim=1)
print(result1)
print(result2)
tensor([[1, 2, 6],
[4, 10, 30],
[7, 28, 84]])
tensor([[1, 2, 3],
[4, 10, 20],
[7, 14, 21]])
NumPy ライブラリの利用
PyTorchと併用して NumPy ライブラリを使用することもできます。
import torch
import numpy as np
def cumprod_numpy(data, dim):
return torch.from_numpy(np.cumprod(data.numpy(), axis=dim))
# サンプルデータ
data = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# 0番目の次元と1番目の次元それぞれに沿って累積積を求める
result1 = cumprod_numpy(data, dim=0)
result2 = cumprod_numpy(data, dim=1)
print(result1)
print(result2)
tensor([[1, 2, 6],
[4, 10, 30],
[7, 28, 84]])
tensor([[1, 2, 3],
[4, 10, 20],
[7, 14, 21]])