【Pytorch】tensor型とは|知らないとまずいものをまとめてみた
- PyTorchでディープラーニングが実装できるようになりたい!
- PyTorchのTensorってなんだ??
- PyTorchのTensorを体系的に学びたい
この悩みを解決していきます。
本記事の内容
- PyTorchのTensorに関する基本知識
- Tensorの生成
- Tensorでよく使用するメソッド
- Tensorでよく使用する関数
本記事を読んで得られること
- PyTorchを用いて機械学習を行う際に必要不可欠なものを効率的に習得可能
*本記事は、10〜15分程度読み切ることができます。
PyTorchのTensorに関する基本知識
Tensorとは、PyTorchでデータを扱う際に最も基本となるデータ構造です。
PyTorchで機械学習を行う際は、必ずTensorに変換する必要があります。
Tensorパッケージは、例えるならNumpyのように多次元配列を扱うクラスです。
しかし、Numpyと異なり、引数でGPUを指定するだけで簡単にGPUが使用できるというメリットがあります。
PyTorchのインポート方法
まず初めに必要なライブラリを以下を実行してインポートしてください。
import torch
import numpy as np
本記事では、numpyのndarray配列に変換する方法を紹介するので、numpyもインポートしておいてください。
*Google Colabを使用していない方は、下記をコマンドラインに入力して、PyTorchをインストールする必要があります。
$ pip3 install torch torchvision
しかし、Google Colabを使用することで簡単にGPUが使用できるので、各自でGPUを持っていない方はGoogle Colabをインストールしてから本記事を読むことをおすすめします。
具体的なGoogle Colabのインストール方法は下記を参考にしてください。
Tensor型配列の生成
Tensorの生成方法について説明していきます。
- tensor : tensor配列を生成
- FloatTensor : float型のtensorを生成
- LongTensor : int型のtensorを生成
- arange : 値が等間隔に変化するtensorを生成
- zeros : 要素が全て0のtensorを生成
- ones : 要素が全て1のtensorを生成
- full : 要素が任意の値となるtensorを生成
tensor : tensor配列を生成
torchのtensor関数を使ってTensor
を生成します。
以下のようにPythonのリストを代入することでTensor配列を作成することができます。
# リストを渡すことで配列を作成
tensor = torch.tensor([[1, 2, 3], [4, 5, 6]], dtype = torch.float64)
tensor
<出力>
tensor([[1., 2., 3.],
[4., 5., 6.]], dtype=torch.float64, requires_grad=True)
引数について
- dtype : tensorの型を指定(デフォルト : torch.FloatTensor)
- requires_grad : 勾配計算を行うかどうか(デフォルトでTrue)
*requires_grad = True
とすることで、その配列を変数として、様々な演算を行ったときに、その変数に関する勾配の情報を保持します(後に詳しく説明するので、安心してください)
list型だけでなく、ndarray型もtensor型に変換できる
list型だけでなく、ndarray型もtensorに変換することができます。
*PyTorchは機械学習を行う際にfloat32
を使用します。Numpyではデフォルトでfloat64
なのでfloat()
メソッドを利用して変換する癖をつけましょう!
torch.tensor(np.array([1.0, 2.0, 3.0])).float()
<出力>
tensor([1, 2, 3])
FloatTensor : float型のTensorを生成
『torch.float32型』のTensorを生成する場合は、FloatTensor
を使用します。
torch.tensor
でdtype=torch.float32
と指定すれば同じ結果を得ることができるので、どちらを利用しても良いです。
# FloatTensor
torch.FloatTensor([1, 2, 3])
<出力>
tensor([1., 2., 3.])
すでに説明しましたがfloat()
メソッドを利用してもfloat32
のテンソルを作成することができます。
torch.tensor([1, 2, 3]).float()
LogTensor : int型のTensorを生成
『torch.int64型』のTensorを生成する場合は、LongTensorを使用します。
torch.tensor
でdtype=torch.int64
と指定すれば同じ結果を得ることができるので、どちらを利用しても良いです。
<入力>
# LongTensor
torch.LongTensor([1.2, 2.3, 3.4])
<出力>
tensor([1, 2, 3])
long()
メソッドを以下のように指定して配列を変換することもできます。
torch.tensor([1.1, 1.2, 1.3]).long()
なぜ、int64
型を使用するのか簡単に説明します。
PyTorchでは、多値分類のとき、クロスエントロピーを利用する場合は第二引数にint64型を入力として使用します。
それ以外の型を入力するとエラーが生じます。
arange : 値が等間隔に変化するtensorを生成
arange関数は、引数として(start, stop, step)という形式で配列を生成します。
# 等間隔な配列
tensor = torch.arange(0, 10)
tensor
<出力>
tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
zeros : 要素が0のtensorを生成
zeros
を使用することで、要素が0の配列を生成することができます。
torch.zeros(5, 5)
<出力>
tensor([[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]])
また、torch.zeros_like
を使用することで既存のtensorと同じサイズの0埋めされたtensorを生成することができます。
a = torch.tensor([[1, 2], [3, 4]])
torch.zeros_like(a)
<出力>
tensor([[0, 0],
[0, 0]])
ones : 要素が1のtensorを生成
torch.ones
を利用することで、要素が1の行列を生成することができます。
torch.ones(5, 5)
<出力>
tensor([[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.]])
また、torch.ones_like
を使用することで既存のtensorと同じサイズの1埋めされたtensorを生成することができます。
a = torch.tensor([[1, 2], [3, 4]])
torch.ones_like(a)
<出力>
tensor([[1, 1],
[1, 1]])
full : 要素が任意の値となるtensorを生成
torch.full
を使用することで任意の値で埋めtensorを生成することができます。
torch.full((3, 2), 1.23)
<出力>
tensor([[1.2300, 1.2300],
[1.2300, 1.2300],
[1.2300, 1.2300]])
また、torch.full_like
を使用することで既存のtensorと同じサイズの設定した値で埋められたtensorを生成することができます。
a = torch.tensor([[1, 2], [3, 4]])
torch.full_like(a, 3)
<出力>
tensor([[3, 3],
[3, 3]])
次に乱数生成方法を学んでいきましょう。
Tensor型の乱数生成方法
機械学習では、乱数を生成する場面が多くあります。
ここでは、Pytorchを利用して乱数を生成する方法を説明します。
- randn : 標準正規分布から乱数生成
- rand : 一様乱数を生成
randn : 標準正規分布から乱数生成
標準正規分布(平均0, 分散1のガウス分布)から乱数を生成する方法を下記に示します。
# 標準正規分布
torch.randn(2, 2)
<出力>
tensor([[-0.5803, 1.4557],
[-0.8255, -1.3658]])
rand : 一様乱数を生成
次に、[0, 1)の間の乱数を生成する方法を下記に示します。
# [0, 1)の間の一様乱数
torch.rand(2, 2)
<出力>
tensor([[0.7726, 0.5627],
[0.3817, 0.5896]])
次は、自動微分機能について説明します。
自動微分機能
自動微分機能を単体で使用することはありませんが、機械学習モデルのパラメータを更新する際に使用されます。
自動微分の詳しい説明は、『自動微分(Wikipedia)』に任せ、Pytorchによる自動微分の具体例を説明します。
具体例として、『y = x2』という関数を自動微分して、微分した結果『y’ = 2x』に『x = 1』を代入して得られる『2』を出力する方法を下記に示します。
# 自動微分の具体例
x = torch.tensor(1.0, requires_grad=True)
y = x**2
y.backward()
x.grad
<出力>
tensor(2.)
動作を簡単に説明します。
- 『x』のTensorを生成する際に、勾配情報を保持できるように、
requires_grad=True
を宣言 y.backward()
で勾配を計算x.grad
で勾配情報を表示
*int型では勾配計算ができないので、使用する際はfloatに変更しましょう。
with torch.no_grad()
のブロックの中は勾配計算を行わないようにすることができます。
x = torch.tensor(1.0, requires_grad=True)
print('勾配計算の有無', (x**2).requires_grad)
with torch.no_grad():
print('勾配計算の有無', (x**2).requires_grad)
<出力>
勾配計算の有無 True
勾配計算の有無 False
この機能は学習後のネットワークを推論用として利用することができます。
Tensorでよく使用するメソッド
ここからは、PytorchのTensorクラスでよく使用するメソッドについて紹介していきます。
- size : Tensorの形状を確認
- view : Tensorの形状を変更
- to : 配列を使用したいデバイスへ
- numpy, clone, detach : Tensorをndarray型(Numpy配列)に変換
- tolist : Tensorをlist型に変換
- item : tensor内の値を取得
- transpose : tensorの任意の2軸を入れ替える
- permute : 軸の順番を指定して入れ替える
size : tensorの形状を確認
sizeメソッドを使用することで、tensorの形状を確認することができます。
tensor1 = torch.tensor([[1, 2], [3, 4]])
tensor1.size()
<output>
torch.Size([2, 2])
numpyと同様に、shape
を使用して配列を確認することもできます。
tensor1 = torch.tensor([[1, 2], [3, 4]])
tensor1.shape
<output>
torch.Size([2, 2])
view : tensorの形状を変更
viewを用いることで、Tensorの形状を変換することができます。
動作は、numpyのreshape
とほとんど変わりません。
tensor1 = torch.tensor([[1, 2, 3, 4], [5, 6, 7, 8]])
# 4行2列に変換
tensor1 = tensor1.view(4, 2)
tensor1
<output>
tensor([[1, 2],
[3, 4],
[5, 6],
[7, 8]])
numpy同様、viewの引数に-1を指定することもできます。
tensor1 = torch.tensor([[1, 2, 3, 4], [5, 6, 7, 8]])
# -1を使用して自動で決定する
tensor1 = tensor1.view(-1, 2)
tensor1
<output>
tensor([[1, 2],
[3, 4],
[5, 6],
[7, 8]])
to : 配列を使用したいデバイスへ
toを使用することで、使用したいデバイスで配列を扱うことができます。
tensor1 = torch.tensor([[1, 2, 3], [4, 5, 6]])
tensor1.to('cuda')
<output>
tensor([[1, 2, 3],
[4, 5, 6]], device='cuda:0')
『to('デバイス名')
』で使用したいデバイスで配列を扱えるようになります。
GPUを使用したい場合は、以下を入力することでGPUの使用が可能かどうかを判断することができます。
# GPUの使用を確認
torch.cuda.is_available()
<output>
True # 使用不可の場合はFalse
さらに、使用するデバイスをGPUが使用可能な場合はGPUに設定し、使用不可能な時はCPUを指定する方法があります。
# GPUが使用できる場合はGPUを使用し、そうでない場合はCPUを使用
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
device
<output>
device(type='cuda')
この書き方を使用すれば、柔軟にTensorを指定したdeviceに指定することできます。
tensor1 = torch.tensor([[1, 2, 3], [4, 5, 6]])
tensor1.to(device)
<output>
tensor([[1, 2, 3],
[4, 5, 6]], device='cuda:0')
よく使用する書き方なので覚えておくと良いです。
numpy, clone, detach : Tensorをndarray型に変換
numpyメソッドを使用することで、Tensorをndarray型に変換することができます。
tensor1 = torch.tensor([[1, 2, 3], [4, 5, 6]])
array1 = tensor1.clone().numpy()
array1
<出力>
array([[1, 2, 3],
[4, 5, 6]])
*clone()を使用することで、メモリの共有を避けることができます。
ndarray型に変換する際には、さらに注意するポイントがあります。
Tensorは、勾配の情報とGPU使用が可能です。
しかし、そのような機能を使用したままだとndarray配列に変換することができません。
なので、変換する際は以下のメソッドを使用して、デバイスをcpuに指定し、tensorの勾配情報を消去しましょう。
- detach : Tensorから勾配情報を消去
- clone : 配列のコピー(メモリ共有を防ぐ)
tensor1 = torch.tensor([[1., 2., 3.], [4., 5., 6.]], device='cuda', requires_grad=True)
array1 = tensor1.detach().clone().to('cpu').numpy()
array1
<output>
array([[1., 2., 3.],
[4., 5., 6.]], dtype=float32)
tolist : TensorをList型に変更
numpyメソッドと同様に、tolistメソッドを使用することでtensor型をlist型に変更することができます。
a = torch.tensor([1., 2., 3.])
a.tolist()
<output>
[1.0, 2.0, 3.0]
numpyメソッドと異なりdetach, to('cpu')
を使用しなくても問題なく変換できます。
a = torch.tensor([1., 2., 3.], device="cuda:0", requires_grad=True)
a.tolist()
<出力>
[1.0, 2.0, 3.0]
item : tensor内の値を取得
itemメソットでtensor内の値を取得することができます。
*ベクトルや行列を取り出すことはできず、スカラー値のみ取り出すことができます。
tensor1 = torch.tensor([100])
tensor1.item()
<output>
100
transpose : テンソルの任意の2軸を入れ替える
transposeメソッドを利用することで以下のように任意の2軸を入れ替えることができます。
a = torch.ones(2, 3, 4)
b = a.transpose(0, 1)
b.size()
<output>
torch.Size([3, 2, 4])
permute : 軸の順番を指定して入れ替える
permuteを使用することで、軸の順番を指定して入れ替えることができます。
a = torch.ones(2, 3, 4)
b = a.permute(1, 0, 2)
b.size()
<output>
torch.Size([3, 2, 4])
Tensorでよく使用する関数
Tensorでよく使用する関数をまとめていきます。
- from_numpy : ndarrayをTensor型に変換
from_numpy : ndarrayをtensor型に変換
from_numpy
を用いることで、numpyの配列をTensorに変換することができます。
numpyの配列をそのまま変更することもできますが、PyTorchで機械学習を行う際に以下のように変更しておかないとエラーが起こることがあります。
- float型は『float32』に設定
- int型は『int64』に設定
# float32に直しておくと良い
array1 = np.array([[1, 2, 3], [4, 5, 6]]).astype(np.float32)
tensor1 = torch.from_numpy(array1.copy())
tensor1
<出力>
tensor([[1., 2., 3.],
[4., 5., 6.]])
参考資料|おすすめ教材
参考文献|おすすめ参考書
本記事を作成する際に利用した参考文献を下記にまとめました。
参考講座
UdemyのPyTorchコースがマジでおすすめです!
私は受講した中で特におすすめな講座を厳選しています。
PyTorch以外も講座もぜひ受講してみてください!
まとめ
PyTorchのTensorを扱うときによく使用するもののみピックアップして解説しました。
- PyTorchのTensorに関する基本知識
- Tensorの生成
- 乱数の生成方法
- Tensorでよく使用するメソッド
- Tensorでよく使用する関数
配列の要素を取り出す方法や四則演算の方法等はnumpyとほとんど変わらないため説明を割愛しました。
ディープラーニングを実装するために次に重要なのはPytorchによるネットワークの設計方法です。
Pytorchによるネットワークの詳しい設計方法に関しては下記を参考にしてください
配列の要素を取り出す方法(インデキシング)等が理解できていない方は下記を参考にしてください。
基本的に、Tensorから直接matplotlibを使用することができます。
matplotlibを利用したデータの可視化方法について知りたい方は下記を参考にしてください。
Pythonを学習するのに効率的なサービスを紹介していきます。
まず最初におすすめするのは、Udemyです。
Udemyは、Pythonに特化した授業がたくさんあり、どの授業も良質です。
また、セール中は1500円定義で利用することができ、コスパも最強です。
下記の記事では、実際に私が15個以上の講義を受講して特におすすめだった講義を紹介しています。
他のPythonに特化したオンライン・オフラインスクールも下記の記事でまとめています。
自分の学習スタイルに合わせて最適なものを選びましょう。
また、私がPythonを学ぶ際に使用した本を全て暴露しているので参考にしてください。