"機械学習","信号解析","ディープラーニング"の勉強

HELLO CYBERNETICS

深層学習、機械学習、強化学習、信号処理、制御工学などをテーマに扱っていきます

【Pytorch】torch.Tensorの作成と基本操作

 

 

f:id:s0sem0y:20170925014700j:plain

 

はじめに

この記事ではPytorchでディープラーニングをやる前に、必要最低限のtorch.Tensorの操作をメモしたものです。したがってこの記事ではニューラルネットワークを書いていくための情報は直接的には得られません。

 

以下の記事ではchainerをやっていた人を想定して書いていましたが、今回は純粋にPytorchだけの操作を淡々と書いていきます。

s0sem0y.hatenablog.com

 

 

Tensorの作成

乱数から作る

正規分布

各要素がそれぞれ標準正規分布N(0,1)(平均0、分散1)から発生します。

f:id:s0sem0y:20171019052127p:plain

 

一様分布

各要素がそれぞれ一様分布から発生します。

区間が[0,1\)なので0が出ることはあっても1が出ることはありません。

f:id:s0sem0y:20171019052325p:plain

 

permutation

一次元のLongTensorを作ります。

Nを引数に入れたら、0〜N-1の数がランダムで並んだ数列が作られます。

ランダムなindexを作りたい時に利用。

f:id:s0sem0y:20171019052139p:plain

 

指定して作る

要素が全て0

f:id:s0sem0y:20171019052949p:plain

 

要素が全て1

f:id:s0sem0y:20171019053031p:plain

 

ステップの大きさを指定した数列

torch.arrage(start, end, step)という形式で作ります。

区間は[start, end\)であり、endの数は含まれません。

f:id:s0sem0y:20171019053246p:plain

 

ステップの数を指定した数列

torch.linspace(start, end, num_step)という形式で作ります。

区間は[start, end]であり、endも含まれます。

f:id:s0sem0y:20171019053404p:plain

 

Tensorの型

FloatTensorでサイズ指定

intを複数与えると、そのサイズのFloatTensorが作られます。値は適当に初期化されます。

下記ではtorch.Tensorを使っていますが、標準の型がFloatになっています。(torch.FloatTensorを使っても同じ)

f:id:s0sem0y:20171019053802p:plain

 

FloatTensorにリストを渡す

リストを渡すと、それをそのままFloatTensorにします。

f:id:s0sem0y:20171019053943p:plain

 

LongTensor

整数を扱う場合はlong型を使います(int型も別途ありますが、ニューラルネットのラベルとして受け付けてくれませんので、よほど使う機会はないです)。

 

f:id:s0sem0y:20171019054730p:plain

 

メソッドで型を変換することもできます。

f:id:s0sem0y:20171019054838p:plain

 

要素へのアクセス

Pythonで慣れ親しんだ方法で要素へアクセスができます。

f:id:s0sem0y:20171019061425p:plain

 

Torchの絶対押さえておく関数・メソッド

numpy周り

numpyへの変換

torch.Tensor.numpy()メソッドでtorch.Tensorをnumpy.arrayに変換できます。

f:id:s0sem0y:20171019055128p:plain

 

numpyからの変換

numpyのarrayをtorch.from_numpy()に渡すと、対応するTensorへ変換してくれます。ただし、変換されたTensorの型には注意しておきましょう。

f:id:s0sem0y:20171019055852p:plain

 

 

特にnumpyのint32はIntTensorになりますが、一方でPytorchではLongTensorを使うのが標準なので注意が必要です。

f:id:s0sem0y:20171019060229p:plain

 

 

GPU周り

cpuからgpuへ

.cuda()メソッドで簡単にgpu用の型に変更できます。

また、torch.cuda.Tensorで直接gpu用のTensorを作ることもできます。

f:id:s0sem0y:20171019060442p:plain

 

gpuからcpuへ

.cpu()メソッドで簡単にcpu用の型に変更できます。

f:id:s0sem0y:20171019060659p:plain

 

Tensorの形を知る

.size()メソッドでtorchのサイズを得ることができます。

メソッドなので引数を与えることができ、与えたaxisのサイズを直接得られます。まとめてサイズを得てから、indexにアクセスしても同じように指定したaxisのサイズを知ることができます。

 

f:id:s0sem0y:20171019060901p:plain

 

Tensorの連結

torch.cat()

torch.Tensorをリスト入れてして渡すことで、それらを連結したTensorを返してくれます。

連結する軸はdimによって指定します。

f:id:s0sem0y:20171019061927p:plain

 

torch.stack()

torch.Tensorをリストにして渡すことで、新しい軸に沿ってTensorを連結します。以下ではTensorを4つ渡したので、0番目の軸に沿ったサイズが4になっています。

f:id:s0sem0y:20171019062305p:plain

 

dim=1と指定すれば、1番目の軸方向にTensorを積んでいくことになります。

f:id:s0sem0y:20171019062459p:plain

 

 

Tensorのスライシング

torch.chunk

torch.chunk()によって、渡したTensorを指定した個数に切り分けてくれます。切り分ける方向はdimによって指定します。切り分ける個数と、戻り値の個数は等しくしておかなければいけません。

f:id:s0sem0y:20171019062958p:plain

 

あるいは、戻り値を1つにすれば、タプルとして返ってきます。

f:id:s0sem0y:20171019063248p:plain

 

切り分ける方向をdim=1とすれば、以下のように列を切ってくれます。

f:id:s0sem0y:20171019063436p:plain

 

torch.split

こちらも切り分けてくれるメソッドですが、何個の要素ごとに切るかを指定します。以下では、3×8のテンソルを、dim=1方向に3つずつに分けるように指示しています。

f:id:s0sem0y:20171019064139p:plain

dim=1方向には要素が8つしか無いため、最後だけ3×2のTensorが格納されます。こちらは切り分けられた結果、何個も戻り値を持つかは計算しなければわからないため(単に割り算するだけだけど)、基本的にはタプルで受け取ります。

 

軸の操作

torch.squeeze

torch.squeezeは要素数が1のみの軸を削除してくれます。

dimで削除したい軸を指定することも可能です。仮に指定した軸の要素数が1でない場合は何も実行されません。

f:id:s0sem0y:20171019064732p:plain

 

torch.Tensor.view

Tensorのサイズを変えたい場合にはviewメソッドを使います(numpyでのreshapeに対応)。

-1を指定した軸は、要素数を自動で調整してくれます。

f:id:s0sem0y:20171019065154p:plain

 

torch.Tensor.transpose

指定した2つの軸を交換します。

f:id:s0sem0y:20171019065552p:plain

 

あくまで指定した軸を交換するものであって、以下のように、軸を好きなように並べ替えようと思った場合にはエラーを起こします。

f:id:s0sem0y:20171019065759p:plain

 

 

 

最後に

torch.Tensorへの操作は基本的にVariableで包んだ後でも使えます。とりあえず最低限ココラヘンを知っていれば、あとはPythonの操作と組み合わせていろいろできると思います。

 

 

s0sem0y.hatenablog.com

s0sem0y.hatenablog.com

s0sem0y.hatenablog.com