Programming lab

【Pytorch】tensor型とは(知らないとまずいものをまとめてみた)

【Pytorch】tensor型とは(知らないとまずいものをまとめてみた)

 

 

  • PyTorchでディープラーニングが実装できるようになりたい!
  • PyTorchのTensorってなんだ??
  • PyTorchのTensorを体系的に学びたい

 

この悩みを解決していきます。

本記事の内容

  1. PyTorchのTensorに関する基本知識
  2. Tensorの生成
  3. Tensorでよく使用するメソッド
  4. Tensorでよく使用する関数

本記事を読んで得られること

  1. PyTorchを用いて機械学習を行う際に必要不可欠なものを効率的に習得可能

*本記事は、10〜15分程度読み切ることができます。

PyTorchのTensorに関する基本知識

Tensorとは、PyTorchでデータを扱う際に最も基本となるデータ構造です。

PyTorchで機械学習を行う際は、必ずTensorに変換する必要があります。

Tensorパッケージは、例えるならNumpyのように多次元配列を扱うクラスです。

しかし、Numpyと異なり、引数でGPUを指定するだけで簡単にGPUが使用できるというメリットがあります。

pytorchのインポート方法

 

まず初めにPytorchを以下のようにインポートしましょう。

import torch
import numpy as np

 

本記事では、numpyのndarray配列を利用するのでnumpyもこのタイミングでインポートしてください。

*Google Colabを使用していない方は、まずPytorchを自分の環境に落としてから実行してください。

しかし、Google Colabを使用することで簡単にGPUが使用できるので、各自でGPUを持っていない方はGoogle Colabをインストールしてから本記事を読むことをおすすめします。

具体的なGoogle Colabのインストール方法は下記を参考にしてください。

 

【10分で完了】Google Colabのインストール法・使い方Google Colabは、GPUを使用できるため、低コストかつ高速で機械学習の実装を行う際に必要不可欠なツールです。本記事では、Google Colabのインストール方法と注意事項を10〜15分程度でまとめました。...

 

Tensor型配列の生成

 

Tensorの生成方法について説明していきます。

  1. tensor : tensor配列を生成
  2. FloatTensor : float型のtensorを生成
  3. LongTensor : int型のtensorを生成
  4. arange : 値が等間隔に変化するtensorを生成
  5. zeros : 要素が全て0のtensorを生成
  6. ones : 要素が全て1のtensorを生成
  7. full : 要素が任意の値となるtensorを生成

 

tensor : tensor配列を生成

 

torchのtensor関数を使って『Tensor』を生成します。

以下のようにPythonのリストを入れると作ることができます

# リストを渡すことで配列を作成
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に変換することができます。

torch.tensor(np.array([1, 2, 3]))

 

<出力>

tensor([1, 2, 3])

 

『dtype』等で型変換も容易にできます。

 

FloatTensor : float型のTensorを生成

 

『torch.float32型』のTensorを生成する場合は、『FloatTensor』を使用します。

『torch.tensor』で『dtype=torch.float32』と指定すれば同じ結果を得ることができるので、どちらを利用しても良いです。

<入力>

# FloatTensor
torch.FloatTensor([1, 2, 3])

 

<出力>

tensor([1., 2., 3.])

 

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])

 

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を利用して乱数を生成する方法を説明します。

  1. randn : 標準正規分布から乱数生成
  2. 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.)

 

動作を簡単に説明します。

  1. 『x』のTensorを生成する際に、勾配情報を保持できるように、『requires_grad=True』を宣言
  2. 『y.backward()』で勾配を計算
  3. 『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クラスでよく使用するメソッドについて紹介していきます。

 

  1. size : Tensorの形状を確認
  2. view : Tensorの形状を変更
  3. to : 配列を使用したいデバイスへ
  4. numpy, clone, detach : Tensorをndarray型(Numpy配列)に変換
  5. tolist : Tensorをlist型に変換
  6. item : tensor内の値を取得
  7. transpose : tensorの任意の2軸を入れ替える
  8. 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()

 

<出力>

True # 使用不可の場合はFalse

 

さらに、使用するデバイスをGPUが使用可能な場合はGPUに設定し、使用不可能な時はCPUを指定する方法があります。

<入力>

# GPUが使用できる場合はGPUを使用し、そうでない場合はCPUを使用
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
device

 

<出力>

device(type='cuda')

 

この書き方を使用すれば、柔軟にTensorを指定したdeviceに指定することできます。

<入力>

tensor1 = torch.tensor([[1, 2, 3], [4, 5, 6]])
tensor1.to(device)

 

<出力>

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の勾配情報を消去しましょう。

  1. detach : Tensorから勾配情報を消去
  2. clone : 配列のコピー(メモリ共有を防ぐ)

 

<入力>

tensor1 = torch.tensor([[1., 2., 3.], [4., 5., 6.]], device='cuda', requires_grad=True)
array1 = tensor1.detach().clone().to('cpu').numpy()
array1

 

<出力>

array([[1., 2., 3.],
       [4., 5., 6.]], dtype=float32)

 

tolist : TensorをList型に変更

 

numpyメソッドと同様に、tolistメソッドを使用することでtensor型をlist型に変更することができます。

a = torch.tensor([1., 2., 3.])
a.tolist()

 

<出力>

[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()

 

<出力>

100

 

transpose : テンソルの任意の2軸を入れ替える

 

transposeメソッドを利用することで以下のように任意の2軸を入れ替えることができます。

a = torch.ones(2, 3, 4)
b = a.transpose(0, 1)
b.size()

 

<出力>

torch.Size([3, 2, 4])

 

permute : 軸の順番を指定して入れ替える

 

permuteを使用することで、軸の順番を指定して入れ替えることができます。

a = torch.ones(2, 3, 4)
b = a.permute(1, 0, 2)
b.size()

 

<出力>

torch.Size([3, 2, 4])

 

 

Tensorでよく使用する関数

 

Tensorでよく使用する関数をまとめていきます。

  1. 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.]])

 

まとめ

 

PyTorchのTensorを扱うときによく使用するもののみピックアップして解説しました。

  1. PyTorchのTensorに関する基本知識
  2. Tensorの生成
  3. 乱数の生成方法
  4. Tensorでよく使用するメソッド
  5. Tensorでよく使用する関数

配列の要素を取り出す方法や四則演算の方法等はnumpyとほとんど変わらないため説明を割愛しました。

ディープラーニングを実装するために次に重要なのはPytorchによるネットワークの設計方法です。

Pytorchによるネットワークの詳しい設計方法に関しては下記を参考にしてください

 

Pytorchのネットワークの書き方を徹底解説Pytorchのネットワークの書き方を二つ説明しました。一つ目はSequentialを使用する方法で、二つ目はネットワークを自作モジュール化する方法を説明しました。また、二つのメリット・デメリットを具体例を通じて理解できるように工夫しました。...

 

配列の要素を取り出す方法(インデキシング)等が理解できていない方は下記を参考にしてください。

 

numpyの使い方【15分で使えるようになる】機械学習やデータ解析をいち早く行うために、numpyに関する基本事項を体系的にまとめました。15分程度で読めるので、この記事でnumpyの基本を習得し、次のステップに進みましょう。...

 

基本的に、Tensorから直接matplotlibを使用することができます。

matplotlibを利用したデータの可視化方法について知りたい方は下記を参考にしてください。

【15分】Pythonでグラフを作成する方法(matplotlib)Pythonでグラフを書くことが難しそうだと思っていませんか?実は、Pythonを使用したグラフ作成は、excelより便利で簡単です。この記事では、初心者でもグラフが書けるように丁寧にpythonのグラフの作成法を説明します。...
ABOUT ME
努力のガリレオ
【運営者】 : 東大で理論物理を研究中(経歴)東京大学, TOEIC950点, NASA留学, カナダ滞在経験有り, 最優秀塾講師賞, オンライン英会話講師試験合格, ブログと独自コンテンツで収益6桁達成 【編集者】: イングリッシュアドバイザーとして勤務中(経歴)中学校教諭一種免許取得[英語],カナダ留学経験あり, TOEIC650点