Pytorch学習軌跡

2020/12/06

## torch.nn.init.normal_(tensor, mean=0.0, std=1.0)
- tensor: n次元のTensor型
- mean: 正規分布の平均値
- std: 正規分布の標準偏差  
Gans生成の重みの初期化で出てきた。  

```
例
w = torch.empty(2, 5)
nn.init.normal_(w, 0.0, 0.02)
--> 
tensor([[-0.0038, -0.0077, -0.0248,  0.0167, -0.0318],
        [-0.0232, -0.0192, -0.0027, -0.0211,  0.0047]])
```   

2020/12/07


## torch.nn.Sequential(*args: Any)
- *args: 複数の引数をタプルとして受け取る  

使うメリットはMaxpooling, Conv等をまとめることができるので、コード量が減る。
例を書くと長いので他の[サイト](https://deepblue-ts.co.jp/python/pytorch%E3%81%A7%E3%81%AEsequential%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9/)に任せます。
[公式: torch.nn.Sequential](https://pytorch.org/docs/stable/generated/torch.nn.Sequential.html)


## torch.nn.ConvTranspose2d
CNNを復習してきたので処理の引数の意味も理解できました
日本語では転置畳み込みで別の言い方でDeconvolutionと言ったりします。
これは元の特徴マップを拡大してから畳み込むようです。
あまりぱっとイメージしにくいかもしれませんので、[こちら](https://github.com/vdumoulin/conv_arithmetic/blob/master/README.md)にわかりやすく画像とアニメーションがついてるので確認してみてください。

- in_channels:入力画像のチャンネル数
- out_channels:畳み込みによって生成されるチャンネル数
- kernel_size:畳み込みのカーネルのサイズ
- stride:畳み込みのストライド（畳み込みの適用間隔のこと）デフォルトは１
- padding:zero_paddingが各次元の両サイドに追加される。デフォルトは０
- output_padding:出力にサイズを追加する（内容がいまいちわからないので調べたら更新します。
　　　多分英語でしか説明されてない気がする...誰か日本語サイト知ってたら教えてください）
- groups:入力のチャンネルから出力のチャンネルへのブロックの数
　（自分の頭では理解が追いつかないので調べてみたところ、
　例えば、入力チャンネルが１６で出力も１６として、仮にgroups=2と設定すると0~８,8~16の２つに分割して並列畳み込みのように
　なるらしい。[こちら](https://github.com/pytorch/pytorch/issues/16222)）[英語] 
- bias:学習可能なバイアスを出力に追加。デフォルトはTrue
- dilation:カーネル要素同士の間隔。デフォルトは１

12/17
## torch.randn(*size, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False) → Tensor
- *size: アウトプットのtensorのサイズを決める。リストやタプルでも指定できる 
- * :　これはなんだ？w
- out=None：アウトプットのtensor (ここはあまり詳しく調べてません)
- dtype=None:返り値のデータのタイプを指定
- layout=torch.strided:解説できるだけの理解力がなかったのでスルー
- requires_grad=False:自動微分の指定

**解説**
平均0分散1の正規分布からランダムな値で満たしたTensorを返してくれます

様々なモジュールを試したり、ランダムな値を生成するときにお世話になるので、
各引数について頭に叩き込みます。
一応数式
$out_i \sim N(0,1)$
Nが正規分布のちょっと曲がった感じにならなくて...

```.py
z = torch.randn(2)
z
# tensor([-1.0899, -0.8052])
#------------------------
z = torch.randn(2,3) # 2 x 3
z
#tensor([[ 1.5442,  0.6762,  1.5586],
#        [-0.1483,  1.0889, -2.7871]])
#-----------------------------------
#4次元にした場合(出力は長いので書きません)
#例：torch.randn(nsamples, nchannels, Height, Width)
z = torch.randn(100,1,28,28) #1チャンネルの28x28の画像を100枚
z

```

## torch.no_grad()
画像認識を勉強中に出てきた。
※このコードは訓練後のモデルの精度を測っている

```
correct = 0
total = 0
with torch.no_grad(): #<-----ここ
    for data in testloader:
        images, labels = data
        outputs = net(images)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

print('Accuracy of the network on the 10000 test images: %d %%' % (
    100 * correct / total))
```
まずはwithこれは開始と終了を必要とする処理の先頭に書くコード
torch.no_grad()はすべてのrequire_gradフラグを一時的にfalseに設定する
この**require_grad**を一時的にFalseにする理由はなんなんでしょうか
まずrequire_gradはなんのフラグなのか。
これは**自動微分**をTrueとするかFalseとするかのフラグです。
この設定にどんな意味があるのか
Trueにすれば自動で微分をしてくれる当然のメリット
ではFalseにする理由は。
それはメモリ使用量が削除され、計算が高速になる
そもそも、自動微分をする理由（微分をする理由）はモデルが予測値と正解値との誤差を最小化するため
なら、テストデータで性能を見るだけなら、微分の設定は不要
なので、torch.no_grad()を使って無駄なメモリ使用量を削除し、計算を高速化させた。って感じですね。


随時更新

## ここから一口メモ集

- Tensor型を微分するにはVariable型にする必要がある




[畳み込みとプーリングについてメモ](https://qiita.com/ai_creater/items/f84ac83d5172f719fe5c)

I should’ve mentioned that you can create the transform as transforms.Resize((224, 224)). If you pass a tuple all images will have the same height and width.


随時更新