ラビット・チャレンジ（深層学習 後編 day3&4）

# 参考図書

- 斎藤 康毅 (2016) 『ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装』, オライリー・ジャパン. 
- 斎藤 康毅 (2018) 『ゼロから作るDeep Learning❷ ―自然言語処理編』, オライリー・ジャパン. 
- 斎藤 康毅 (2020) 『ゼロから作るDeep Learning❸ ―フレームワーク編』, オライリー・ジャパン. 
- Aurélien Géron, 下田倫大 監訳, 長尾高弘 訳 (2020)『scikit-learn、Keras、TensorFlowによる実践機械学習 第2版』, オライリー・ジャパン.
- 小縣 信也, 斉藤 翔汰, 溝口 聡, 若杉 和幸 (2020), 『徹底攻略ディープラーニングE資格エンジニア問題集
』, インプレス.

# [day3-1] 再帰型ニューラルネットワークの概念

## RNN全体像

RNNとは、**時系列データ**に対応可能なニューラルネットワークである。

時系列データとは、時間的順序を追って一定間隔ごとに観察され、しかも相互に統計的依存関係が認められるようなデータの系列（例えば、音声データ、テキストデータ）

![RNN.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/2bb5aa83-d358-dd5a-70e2-b4bdacae90bc.png)

## RNNの数学的記述

### 入力層

入力層から中間層へ向かう値を $x^t$ で表す。

### 中間層

中間層の活性化関数 f に入る前の値を u , 通過後の値を z で表すと以下のようになる。

```math
u^t=W_{(in)}x^t+Wz^{t-1}+b\\
z^t=f(u^t)=f(W_{(in)}x^t+Wz^{t-1}+b)
```

### 出力層

出力層の活性化関数 g に入る前の値を v , 通過後の値を y で表すと以下のようになる。

```math
v^t=W_{(out)}z^t+c\\
y^t=g(v^t)=g(W_{(out)}z^t+c)
```

## BPTT (Backpropagation Through Time)

### BPTTとは

RNNにおけるパラメータ調整方法であり、逆誤差伝播法の一種である。


### BPTTの全体像

![RNN.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/2bb5aa83-d358-dd5a-70e2-b4bdacae90bc.png)

```math
\begin{aligned}
E^t&=loss\bigl(y^t,d^t\bigr)\\
&=loss\bigl(g(W_{(out)}z^t+c),d^t\bigr)\\
&=loss\Bigl(g\bigl(W_{(out)} \ f(W_{(in)} \ x^t+W z^{t-1}+b)+c\bigr),d^t\Bigr)
\end{aligned}
```

```math
W_{(in)}x^t+Wz^{t-1}+b\\
W_{(in)}x^t+Wf(u^{t-1})+b\\
W_{(in)}x^t+Wf(W_{(in)}x^{t-1}+Wz^{t-2}+b)+b
```

## 確認テスト

[Page.11] 
問題：サイズ5×5の入力画像を、サイズ3×3のフィルタで畳み込んだ時の出力画像のサイズを答えよ。なおストライドは2、パディングは1とする。
解答：3x3

[Page.23] 
問題：RNNのネットワークには大きくわけて3つの重みがある。1つは入力から現在の中間層を定義する際にかけられる重み、1つは中間層から出力を定義する際にかけられる重みである。残り1つの重みについて説明せよ。
解答：中間層から中間層への重み

[Page.26] 
問題：以下は再帰型ニューラルネットワークにおいて構文木を入力として再帰的に文全体の表現ベクトルを得るプログラムである。ただし、ニューラルネットワークの重みパラメータはグローバル変数として定義してあるものとし、_activation関数はなんらかの活性化関数であるとする。木構造は再帰的な辞書で定義してあり、rootが最も外側の辞書であると仮定する。（く）にあてはまるのはどれか。
![スクリーンショット 2021-07-20 1.27.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/803ed7f3-f545-adaa-0e88-40a657919c95.png)
（1）W.dot(left + right)
（2）W.dot(np.concatenate([left, right]))
（3）W.dot(left * right)
（4）W.dot(np.maximum(left, right))

解答：（２）

[Page.36] 
問題：連鎖律の原理を使い、dz/dxを求めよ。

```math
z = t^2 \\
t = x+y
```
解答：

```math
\dfrac{dz}{dt}\dfrac{dt}{dx}=2t\cdot1=2(x+y)
```

[Page.45] 
問題：下図のy1をx・s0・s1・win・w・woutを用いて数式で表せ。※バイアスは任意の文字で定義せよ。※また中間層の出力にシグモイド関数g(x)を作用させよ。
![スクリーンショット 2021-07-20 1.37.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/d5c15718-f149-d5a7-2d32-330eb5442e0f.png)
解答：$y_1=\{ w_{out}(w_{in}x_1 + ws_0 + b) + c \}$

[Page.53] 
問題：左の図はBPTTを行うプログラムである。なお簡単化のため活性化関数は恒等関数であるとする。また、calculate_dout関数は損失関数を出力に関して偏微分した値を返す関数であるとする。（お）にあてはまるのはどれか。（1）delta_t.dot(W)（2）delta_t.dot(U)（3）delta_t.dot(V)（4）delta_t* V
![スクリーンショット 2021-07-20 1.53.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/592a74f4-9aa2-e44d-6954-2d7d85d039d4.png)

解答：２

## 参考動画

https://youtu.be/NJdrYvYgaPM

https://youtu.be/IcCIu5Gx6uA

## 実装演習

以下は、「simple RNN バイナリ加算」の実行結果である。

```
iters:0
Loss:2.155606799741352
Pred:[0 0 0 0 0 0 0 0]
True:[1 1 1 0 1 0 1 0]
115 + 119 = 0
------------
iters:100
Loss:1.0385181263657943
Pred:[1 1 1 1 1 1 1 0]
True:[1 0 0 1 1 0 1 1]
127 + 28 = 254
------------

（ iters:200 から iters:9700 まで省略 ）

------------
iters:9800
Loss:0.008517473842651268
Pred:[1 1 0 0 0 1 1 0]
True:[1 1 0 0 0 1 1 0]
127 + 71 = 198
------------
iters:9900
Loss:0.0023781526081967518
Pred:[0 1 1 1 0 1 0 0]
True:[0 1 1 1 0 1 0 0]
19 + 97 = 116
------------
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/7e9dd550-e58d-e81b-da1b-9ce936ff8536.png)

x軸は lists 0~1000まで100ステップごと、y軸は all_losses 時系列全体の誤差

何度か試した結果が以下である。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/9dcfc7d6-234f-287d-3e0f-202d294ae27c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/8323f770-b4bc-cb63-9971-b16607c948c4.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/493bbc18-76fb-c250-f910-ab1d2f98c6bc.png)

# [day3-2] LSTM

## LSTMの全体図

![スクリーンショット 2021-07-01 17.09.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/2f37d944-dd35-c360-aa24-540a4b10a74b.png)

### CEC

勾配消失及び勾配爆発の解決方法として、勾配が１であれば解決できるが．．．

CECは入力データについて、時間依存度に関係なく重みが一律である。
つまり、CECは覚えるだけ・・・

CECのまわりに学習機能を配置する

１）CECに何を覚えてもらうか
２）CECかが覚えている知識をどう使うか

CECの取り巻きとして入力ゲートと出力ゲートを導入する

### 入力ゲート

入力された情報をこんな感じで覚えてくださいねってCECに渡して覚えてもらう
入力ゲートが学習する

### 出力ゲート

どんな感じにCECの出力を利用するかを出力ゲートが決める
出力ゲートも学習する

### 忘却ゲート
CECは過去の情報を覚えていて、それに新しい情報を追加して覚えつづけて
いらなくなっても削除できず、保管されつづける。

過去のいらなくなった情報を忘れさせる__忘却ゲート__を導入

$c(t)$：CECが覚えている情報
$f(t)$：忘却ゲートがどれくらい忘れてくださいと制御する値

### 覗き穴結合
CEC自身の値に重み行列を介して伝播可能にした構造

判断材料が増えたということにはなるが・・・
実際には覗き穴結合を使ったところであまり大きな効果、改善は見られなかったとのこと。

## 確認テスト

[Page.62] 
問題：シグモイド関数を微分した時、入力値が0の時に最大値をとる。その値として正しいものを選択肢から選べ。
（1）0.15
（2）0.25
（3）0.35
（4）0.45
解答：（２）

[Page.64] 
問題：RNNや深いモデルでは勾配の消失または爆発が起こる傾向がある。勾配爆発を防ぐために勾配のクリッピングを行うという手法がある。具体的には勾配のノルムがしきい値を超えたら、勾配のノルムをしきい値に正規化するというものである。以下は勾配のクリッピングを行う関数である。（さ）にあてはまるのはどれか。
![スクリーンショット 2021-07-02 15.15.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/165e74cd-6646-ce69-f500-6a2b431416e7.png)
（1）gradient * rate
（2）gradient / norm
（3）gradient / threshold
（4）np.maximum(gradient, threshold)

解答：1

[Page.78] 
問題：以下の文章をLSTMに入力し空欄に当てはまる単語を予測したいとする。文中の「とても」という言葉は空欄の予測においてなくなっても影響を及ぼさないと考えられる。このような場合、どのゲートが作用すると考えられるか。

「映画おもしろかったね。ところで、とてもお腹が空いたから何か____。」

解答：忘却ゲート

[Page.79] 
問題：以下のプログラムはLSTMの順伝播を行うプログラムである。ただし_sigmoid関数は要素ごとにシグモイド関数を作用させる関数である。（け）にあてはまるのはどれか。
![スクリーンショット 2021-07-02 15.09.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/39614924-ceda-3f41-b090-13033db4c329.png)
（1）output_gate* a + forget_gate* c
（2）forget_gate* a + output_gate* c
（3）input_gate* a + forget_gate* c
（4）forget_gate* a + input_gate* c
解答：3

## 参考動画

https://youtu.be/oxygME2UBFc

## 実装演習

なし

# [day3-3] GRU

![スクリーンショット 2021-07-01 17.06.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/27a69465-f627-6e6c-7dfd-b903cf7bacd3.png)

## LSTMの課題

LSTMの改良版？LSTMはやりすぎた！

課題：LSTMでは、パラメータ数が多く、計算負荷が高い（大きい）
（入力ゲート、忘却ゲート、出力ゲート、CECで構成されるため）

### GRU

GRUで改善した点：LSTMで多かったパラメータを大幅に削減しつつ、
精度は同等もしくはそれ以上望めるようになった構造

メリット：計算負荷が低い


### リセットゲート

隠れ層の状態をどのような状態で保持しておくかを制御する。

### 更新ゲート

どのように今覚えてることを使って出力を得るか

## 確認テスト

[Page.88] 
問題：LSTMとCECが抱える課題について、それぞれ簡潔に述べよ。
解答：
LSTM：入力ゲート、出力ゲート、忘却ゲート、CECの４つの部品を持つことで構成されているため、パラメータ数が非常に多くなり、計算量が多くなる
CEC：勾配が１、学習能力がない

[Page.90] 
問題：GRU(Gated Recurrent Unit)もLSTMと同様にRNNの一種であり、単純なRNNにおいて問題となる勾配消失問題を解決し、長期的な依存関係を学習することができる。LSTMに比べ変数の数やゲートの数が少なく、より単純なモデルであるが、タスクによってはLSTMより良い性能を発揮する。以下のプログラムはGRUの順伝播を行うプログラムである。ただし_sigmoid関数は要素ごとにシグモイド関数を作用させる関数である。（こ）にあてはまるのはどれか。
![スクリーンショット 2021-07-02 14.58.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/3494bb29-b3c5-c51e-d15d-6ae4d0022668.png)
（1）z * h_bar
（2）(1-z) * h_bar
（3）z * h * h_bar
（4）(1-z) * h + z * h_bar
解答：4

[Page.92] 
問題：LSTMとGRUの違いを簡潔に述べよ。
解答：
__コンポーネント__
　　LSTM（入力ゲート、忘却ゲート、出力ゲート）、CECあり
　　GRU（リセットゲート、更新ゲート）、CECなし
__パラメータ数__
　　LSTM（多い）
　　GRU（少ない）
__計算負荷__
　　LSTM（高い）
　　GRU（低い）

## 参考動画

https://youtu.be/K8ktkhAEuLM

## 実装演習

## predict_word.ipynbの実行結果

![スクリーンショット 2021-07-01 18.00.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/29e0a33a-6502-7643-367f-d2a7c136631b.png)
（中略）
![スクリーンショット 2021-07-01 17.59.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/2e8bcdbf-35e8-a9c8-add6-1c305f9218a3.png)

# [day3-4] 双方向RNN

過去の情報だけでなく、未来の情報を加味することで、精度を向上させるためのモデル
文章の推敲、機械翻訳などは、文章の最初から最後まで（これを過去から未来と表現）の全文が一度に入ってくるので、文章の逆方向からの処理も加えた。

![スクリーンショット 2021-07-02 11.52.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/3a405fbb-3655-48c1-d98c-bc52ed253299.png)

## 確認テスト

[Page.95] 
問題：以下は双方向RNNの順伝播を行うプログラムである。順方向については、入力から中間層への重みW_f, 一ステップ前の中間層出力から中間層への重みをU_f、逆方向に関しては同様にパラメータW_b, U_bを持ち、両者の中間層表現を合わせた特徴から出力層への重みはVである。_rnn関数はRNNの順伝播を表し中間層の系列を返す関数であるとする。（か）にあてはまるのはどれか
![スクリーンショット 2021-07-02 14.50.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/faa2d4ef-99fc-20ba-333e-8e9b092ae3fd.png)
（1）h_f + h_b[::-1]
（2）h_f * h_b[::-1]
（3）np.concatenate([h_f, h_b[::-1]], axis=0)
（4）np.concatenate([h_f, h_b[::-1]], axis=1)
解答：4

## 実装演習

なし

# [day3-5] Seq2Seq

２つのネットワークがドッキングして使われている、自然言語処理用のネットワーク

![スクリーンショット 2021-07-02 12.21.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/e59ea1fe-b3cd-f1f2-be42-8981f23e7933.png)

## Seq2seqとは

Encoder-Decoderモデルの一種
具体的な用途は、機械対話や機械翻訳などに使用されている

時系列データを入力にとって、時系列データを出力するモデル

## Encoder RNN

文の意味を集約する

ユーザがインプットしたテキストデータを、単語などのトークンに区切って渡す構造

![スクリーンショット 2021-07-02 12.31.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/3af01ead-4c1f-77b3-68bf-71aef016d2a8.png)

全部の単語が入力し終えると、文の全体の意味がひとつのベクトル表現として保存される

通常、数万個程度の単語を使う

１万単語の場合で考えるとこんな感じ
![スクリーンショット 2021-07-02 12.45.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/d4848590-f50d-393d-5624-96fcc529342b.png)

## Encoder RNN処理手順

・vec1をRNNに入力し、hidden stateを出力。このhidden stateと次の入力vec2をまたRNNに入力してきたhidden stateを出力という流れを繰り返す。

・最後のvecを入れたときのhidden stateをfinal stateとしてとっておく。このfinal stateがthroughout vectorと呼ばれ、入力した文の意味を表すベクトルとなる。

### MLM: Masked Language Model

![スクリーンショット 2021-07-02 13.09.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/c5959c85-165b-d946-11cc-342cd7df49c5.png)

## Decoder RNN

システムがアウトプットデータを単語などのトークンごとに生成する構造。

![スクリーンショット 2021-07-02 13.11.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/81eac5e2-4dc1-33b1-b39b-2d86528f394a.png)

1. Decoder RNN：Encoder RNNのfinal state (throughout vector)から、各tokenの生成確率を出力していきます。final stateをDecoder RNNのinitial stateとして設定し、Embeddingを入力。
1. Sampling：生成確率にもとづいてtokenをランダムに選びます。
1. Enmbedding：2で選ばれたtokenをEmbeddingしてDecoder RNNへの次の入力とします。
1. Detokenize：1-3を繰り返し、2で得られたtokenを文字列に直します。

## HRED

HREDとは、過去n-1個の発話から次の発話を生成する。
Seq2seqでは、会話の文脈無視で応答がなされたが、
HREDでは、前の単語の流れに則して応答されるため、
より人間らしい文章が生成される。

システム：インコかわいいよね。
ユーザ：うん
システム：インコかわいいのわかる。

### HREDの課題

HREDは確率的な多様性が字面にしかなく、会話の「流れ」のような多様性がない。
⇨同じコンテキスト（発話リスト）を与えられても、答えの内容が毎回会話の流れとしては同じものしか出せない。

HREDは短く情報量に乏しい答えをしがちである。
⇨短いよくある答えを学ぶ傾向がある。
　ex) 「うん」「そうだね」「・・・」など

## VHRED

HREDにVAEの潜在変数の概念を追加したもの
↓
HREDの課題を、VAEの潜在変数の概念を追加することで解決した構造。

## オートエンコーダ

教師なし学習のひとつ。
そのため学習時の入力データは訓練データのみで教師データは利用しない。

具体例）
MNISTの場合、28x28の数字の画像を入れて、同じ画像を出力するニューラルネットワークということになります。

![スクリーンショット 2021-07-02 13.44.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/54dd25ee-ba43-936b-8bda-1f0f1d1bd52c.png)

## VAE

通常のオートエンコーダの場合、何かしら潜在変数Zにデータを押し込めているものの、その構造がどのような状態かわからない。
↓
VAEはこの潜在変数Zに、確率分布$z\sim N(0,1)$を仮定したもの。

⇨VAEはこの潜在変数zの確率分布という構造に押し込めることを可能にします。

潜在変数zを作るときに正則化（L2正則化のようなもの）を行う。
平均が０で、分散が１の確率分布に従うように潜在変数zをつくりだすようにEncoderが学習する。

## 確認テスト

[Page.109] 
問題：下記の選択肢から、seq2seqについて説明しているものを選べ。
（1）時刻に関して順方向と逆方向のRNNを構成し、それら2つの中間層表現を特徴量として利用するものである。
（2）RNNを用いたEncoder-Decoderモデルの一種であり、機械翻訳などのモデルに使われる。
（3）構文木などの木構造に対して、隣接単語から表現ベクトル（フレーズ）を作るという演算を再帰的に行い（重みは共通）、文全体の表現ベクトルを得るニューラルネットワークである。
（4）RNNの一種であり、単純なRNNにおいて問題となる勾配消失問題をCECとゲートの概念を導入することで解決したものである。
解答：（２）

[Page.111] 
問題：## 演習チャレンジ

機械翻訳タスクにおいて、入力は複数の単語から成る文（文章）であり、それぞれの単語はone-hotベクトルで表現されている。Encoderにおいて、それらの単語は単語埋め込みにより特徴量に変換され、そこからRNNによって（一般にはLSTMを使うことが多い）時系列の情報をもつ特徴へとエンコードされる。以下は、入力である文（文章）を時系列の情報をもつ特徴量へとエンコードする関数である。ただし_activation関数はなんらかの活性化関数を表すとする。（き）にあてはまるのはどれか。
![スクリーンショット 2021-07-02 14.49.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/097d124f-1abe-ad4a-be99-5828b20bd9f9.png)
（1）E.dot(w)
（2）E.T.dot(w)
（3）w.dot(E.T)
（4）E * w
解答：1

[Page.119] 
問題：seq2seqとHRED、HREDとVHREDの違いを簡潔に述べよ。
解答：
seq2seq：一文の一問一答に対して処理ができるある時系列データから、ある時系列データを作り出すネットワーク
HRED：seq2seqの機構に、それまでの文脈の意味ベクトルを解釈に加えられるようにすることで、文脈の意味を汲み取った文の変換EncodeとDecodeをできるようにしたもの
VHRED：HREDが文脈に対して当たり障りのない回答しか作れなくなったことに対しての解決策。オートエンコーダVAEの考え方を取り入れて短い当たり障りのない単語以上の出力を出せるように改良を施したモデル・

[Page.128] 
問題：VAEに関する下記の説明文中の空欄に当てはまることはを答えよ。
自己符号化器の潜在変数に_____を導入したもの。
解答：確率分布

## 参考動画

https://youtu.be/IcCIu5Gx6uA

## 実装演習

なし

# [day3-6] Word2vec

課題：RNNでは単語のような可変長の文字列をNNに与えることはできない。
⇨固定長形式で単語を表す必要がある。

学習データからボキャブラリを作成
※わかりやすく７語のボキャブラリを作成したら、本来は辞書の単語数だけで出来上がる。

Ex) 
I want to eat apples. I like apples.
↓
{apples, eat, I, like, want}

applesを入力する場合は、入力層には以下のベクトルが入力される。
※本来は辞書の単語数だけone-hotベクトルが出来上がる。

1,,,apples
0,,,eat
0,,,I
0,,,like
0,,,to
…

メリット：大規模データの分散表現の学習が、現実的な計算速度とメモリ量で実現可能にした。
⇨✖️：ボキャブラリ×ボキャブラリだけの重み行列が誕生
　○：ボキャブラリ×任意の単語ベクトル次元で重み行列が誕生

![スクリーンショット 2021-07-02 14.13.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/9d4cb049-6e21-b31d-9fac-2705a71bfd4d.png)

## 確認テスト

なし

## 参考動画

https://youtu.be/0CXCqxQAKKQ

https://youtu.be/jlmt4nY0-o0

## 実装演習

# [day3-7] Attention Mechanism

課題：Seq2seqの問題は長い文章への対応が難しいです。
Seq2seqでは、２単語でも１００単語でも、固定次元ベクトルの中に入力しなければならない。

解決策：文章が長くなるほどそのシーケンスの内部表現の次元も大きくなっていく仕組みが必要になります。
↓
Attention　Mechanism
↓
「入力と出力のどの単語が関連しているのか」の関連度を学習する仕組み。

## 具体例

![スクリーンショット 2021-07-02 14.21.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/b131ae31-525f-6c28-bf1a-a6538d3c3336.png)

※「a」については、そもそも関連度が低く、「I」については「私」との関連度が高い。

## 確認テスト

[Page.137] 
問題：RNNとword2vec、seq2seqとAttentionの違いを簡潔に述べよ。
解答：
RNN：時系列データを処理するのに適したネットワーク
word2vec：単語の分散表現ベクトルを得る手法
seq2seq：ひとつの時系列データから別の時系列データを得るネットワーク
Attention Mechanism：時系列データの中身に対して関連性に重みをつける手法

## 参考動画

https://youtu.be/bPdyuIebXWM

## 実装演習

# [day4-1] 強化学習

## 強化学習

### 強化学習とは

- 長期的に報酬を最大化できるように環境のなかで行動を選択できるエージェントを作ることを目標とする機械学習の一分野
    - 行動の結果として与えられる利益（報酬）をもとに、行動を決定する原理を改善していく仕組み。

### 強化学習のイメージ
![スクリーンショット 2021-07-19 8.41.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/0c8f0fb2-f792-edc8-46fe-a2938ee36e82.png)

### 探索と利用のトレードオフ

強化学習の場合、不完全な知識を元に行動しながら、データを収集。最適な行動を見つけていく。

__トレードオフの関係性__

|　　　　　探索が足りない状態　　　　　|　　　　　利用が足りない状態　　　　　|
|:-:|:-:|
|過去のデータでベストとされる行動のみ<BR>を常に取り続ければ、他にもっとベストな<BR>行動を見つけることはできない。|未知の行動のみを常に取り続ければ、<BR>過去の経験が活かせない。|

### 「教師あり学習／教師なし学習」との違い
「強化学習」と通常の「教師あり学習／教師なし学習」は目的が異なる。

|種別|目的|
|:-|:-|
|強化学習|・優れた方策を見つける|
|教師あり学習<BR>／教師なし学習|① データに含まれるパターンを見つけ出す<BR>② そのデータから予測する|

## 価値関数
価値を表す関数としては、状態価値関数と行動価値関数の２種類がある。

- __状態価値関数__:ある状態の価値に注目する場合
    - 環境の状態だけが価値を決める対象
- __行動価値関数__:状態と価値を組み合わせた価値に注目する場合(通常はこっち)
    - __Q 学習__では、行動価値関数を使う。

## 方策関数
エージェントがとる行動を決定するための関数。
（方策ベースの強化学習手法において、ある状態でどのような行動を採るのかの確率を与える関数。）

__方策関数__：$~\pi(s)=a~$

### 関数の関係

エージェントは方策にもどづいて行動する。

- $~\pi(s,a)~$
    - V や Q をもとにどういう行動をとるか。（経験を活かす、チャレンジなど）
    - その瞬間、その瞬間の行動をどうするか。
- $~V^\pi(s)~$：状態関数、$~Q^\pi(s,a)~$：状態＋行動関数
    - ゴールまで今の方策を取り続けた時の報酬の予測値が得られる。
    - やり続けたら最終的にどうなるか。



## 方策勾配法

- __方策反復法__:方策をモデル化して最適化する手法
    - __方策勾配法__：$\theta^{(t+1)} = \theta^{(t)} + \epsilon \nabla J(\theta)$
- Jとは？
    - 方策の良さ（期待収益）：定義しなければならない

- 定義方法
    - 平均報酬
    - 割引報酬和

上記の定義に対応して、行動価値関数$~Q(s,a)~$の定義を行い、方策勾配定理が成り立つ。

```math
\begin{align}
\nabla_\theta J(\theta)
&= \nabla_\theta \sum_{a\in A} \underset{ある行動をとるときの報酬}{\underline{\pi_\theta(a~|~s)Q^\pi(s,a))}} \\
&= \mathbb{E}_{\pi_\theta} \big[ (\nabla_\theta\log\pi_\theta(a~|~s)Q^\pi(s,a)) \big] \\
\end{align}
```

# [day4-2] Alpha Go

## Alpha Go (Lee)
### Alpha Go (Lee) の PolicyNet
畳み込みニューラルネットワークでできている方策関数
![スクリーンショット 2021-07-19 12.26.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/beb45abc-8ff4-91f4-868a-8966c87427eb.png)

- SoftMax Layer:多次元を総和１の確率分布に変換するレイヤ
- 出力は、19×19マスの着手予想確率が出力される

### Alpha Go (Lee) の ValueNet
畳み込みニューラルネットワークでできている価値関数
![スクリーンショット 2021-07-19 12.28.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/40b99adf-49bc-8a4f-05d4-c1f51f96df82.png)

- TanH Layer：$\infty$～$\infty$ の値を -1～1 までに変換するレイヤ
- 出力は、現局面の勝率を -1～1 で表したものが出力される

### Policy Net、ValueNet の入力
![スクリーンショット 2021-07-19 12.35.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/e1a2cbdb-baf7-f112-d634-15bf43d07763.png)

### RollOutPolicy
NNではなく線形の方策関数
探索中に高速に着手確率を出すために使用される。
![スクリーンショット 2021-07-19 12.36.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/728228b1-8008-bd8c-2176-7288af89eeac.png)
上記の特徴が 19×19 マス分あり、出力はそのマスの着手予想確率となる。

### Alpha Go の学習ステップ

1. 教師あり学習による RollOutPolicy と PolicyNet の学習
1. 強化学習による PolicyNet の学習
1. 強化学習による ValueNet の学習

#### PolicyNet の教師あり学習

- KGS Go Server（ネット囲碁対局サイト）の棋譜データから 3000 万局面分の教師を用意し、教師と同じ着手を予測できるよう学習を行った。
    - 具体的には、教師が着手した手を1とし残りを 0 とした 19×19 次元の配列を教師とし、それを分類問題として学習した。

この学習で作成した PolicyNet は 57% ほどの精度である。

#### PolicyNet の強化学習

- 現状の PolicyNet と PolicyPool からランダムに選択された PolicyNet と対局シミュレーションを行い,その結果を用いて方策勾配法で学習を行った。
    - PolicyPool とは、PolicyNet の強化学習の過程を 500 Iteration ごとに記録し保存しておいたものである。
    - 現状の PolicyNet 同士の対局ではなく、PolicyPool に保存されているものとの対局を使用する理由は、対局に幅を持たせて過学習を防ごうというのが主である。

この学習を minibatch size 128 で 1 万回行った。

#### ValueNet の学習

PolicyNet を使用して対局シミュレーションを行い、その結果の勝敗を教師として学習した。

教師データ作成の手順は、

1. まず SL PolicyNet（教師あり学習で作成した PolicyNet ）で N 手まで打つ。
1. N+1 手目の手をランダムに選択し、その手で進めた局面を S (N+1) とする。
1. S (N+1) から RL PolicyNet（強化学習で作成したPolicyNet）で終局まで打ち、その勝敗報酬を R とする。

S (N+1) と R を教師データ対とし、損失関数を平均二乗誤差とし、回帰問題として学習した。

この学習を minibatch size 32 で 5000 万回行った

N 手までと N+1 手からの PolicyNet を別々にしてある理由は、過学習を防ぐためであると論文では説明されている。

### Alpha Go (Lee) のモンテカルロ木探索
Alpha Goのモンテカルロ木探索は、下図の４つのステップで構成される。

1. 選択
1. 評価
1. バックアップ
1. 成長

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/959d95ef-b5cf-db97-515b-0f8d4797cebb.png)

## Alpha Go Zero

### AlphaGo(Lee) と Alpha Go Zero の違い

1. 教師あり学習を一切行わず、強化学習のみで作成
1. 特徴入力からヒューリスティックな要素を排除し、石の配置のみにした
1. PolicyNetとValueNetを１つのネットワークに統合した
1. Residual Net（後述）を導入した
1. モンテカルロ木探索からRollOutシミュレーションをなくした

### Alpha Go Zero の PolicyValueNet
![スクリーンショット 2021-07-19 13.17.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/253f7195-ad3e-471c-bc10-94b9f2c01f9e.png)

### Residual Network

- 基本構造は下図のブロックを１単位にして積み重ねる形となる
![スクリーンショット 2021-07-19 13.18.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/2a600141-637a-97ae-a447-db5f43987f22.png)

- ネットワークにショートカット構造を追加して,勾配の爆発,消失を抑える効果を狙ったもの。
    - Residula Network を使うことにより、100 層を超えるネットワークでの安定した学習が可能となった。
- また,Residual Network を使うことにより層数の違う Network のアンサンブル効果が得られているという説もある。
    - 通常の経路とショートカット経路をもつこのブロックが 39 個連なっているので、さまざまな組合せの経路ができ、それにより層数の異なる経路がたくさんできるということ。

#### Residual Network の派生形

__Residual Blockの工夫__

- Bottleneck
    - 1×1 Kernel の Convolution を利用し、1層目で次元削減を行って３層目で次元を復元する３層構造にし、２層のものと比べて計算量はほぼ同じだが１層増やせるメリットがある、としたもの
- PreActivation
    - ResidualBlock の並びを BatchNorm → ReLU → Convolution → BatchNorm → ReLU → Convolution → Add とすることにより性能が上昇したとするもの

__Network構造の工夫__

- WideResNet
    - Convolution の Filter 数を k 倍にした ResNet。１倍 → k倍 ｘブロック → 2*k倍 yブロックと段階的に幅を増やしていくのが一般的。Filter 数を増やすことにより、浅い層数でも深い層数のものと同等以上の精度となり、また GPU をより効率的に使用できるため学習も早い
- PyramidNet
    - WideResNet で幅が広がった直後の層に過度の負担がかかり精度を落とす原因となっているとし、段階的にではなく、各層で Filter 数を増やしていく ResNet 。

#### Residual Network の性能
性能は従来の VGG-16 と比較して Top5 で 4% 程度ものエラー率の低減に成功している。

### Alpha Go Zero のモンテカルロ木探索
Alpha Go のモンテカルロ木探索は、以下の３つのステップで構成される。

1. 選択
1. 評価および成長
1. バックアップ

### Alpha Go Zero の学習法
Alpha Go の学習は、以下のの３ステップで構成される。

1. 自己対局による教師データの作成
1. 学習
1. ネットワークの更新

## 参考 URL

https://www.slideshare.net/hatanakaakihiro/alphago-mijs-20161011

https://www.slideshare.net/yuk1yoshida/alphago-61311712

# [day4-3] 軽量化・高速化技術

## 高速化技術（分散深層学習）

- 深層学習は多くのデータを使用したり,パラメータ調整のために多くの時間を使用したりするため,高速な計算が求められる。
    - 複数の計算資源（ワーカー）を使用し、並列的にニューラルネットを構成することで、効率の良い学習を行いたい。
    - データ並列化、モデル並列化、GPU による高速技術は不可欠である。

### データ並列化

- 親モデルを各ワーカーに子モデルとしてコピー
- データを分割し,各ワーカーごとに計算させる

![スクリーンショット 2021-07-19 14.31.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/4b19364f-94eb-19ca-48aa-36b960d862a7.png)

#### 同期型と非同期型の比較
データ並列化は各モデルのパラメータの合わせ方で、同期型か非同期型か決まる。

|![スクリーンショット 2021-07-19 14.33.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/9f161735-d963-b686-5d37-a2120a493fd3.png)|![スクリーンショット 2021-07-19 14.33.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/547eddba-ebad-e19a-4349-f7fe0af792af.png)|
|:-:|:-:|
|__同期型__|__非同期型__|
|同期型のパラメータ更新の流れ。各ワーカーが計算が終わるのを待ち、全ワーカーの勾配が出たところで勾配の平均を計算し、親モデルのパラメータを更新する。|非同期型のパラメータ更新の流れ。各ワーカーはお互いの計算を待たず、各子モデルごとに更新を行う。学習が終わった子モデルはパラメータサーバにPushされる。新たに学習を始める時は、パラメータサーバからPopしたモデルに対して学習していく。|

### モデル並列化

- 親モデルを各ワーカーに分割し,それぞれのモデルを学習させる。全てのデータで学習が終わった後で,一つのモデルに復元。
- モデルが大きい時はモデル並列化を,データが大きい時はデータ並列化をすると良い。
- モデルのパラメータ数が多いほど,スピードアップの効率も向上する。
![スクリーンショット 2021-07-19 14.37.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/fba6726e-5b2f-b2b1-052b-3c20287992a9.png)

### GPU による高速化

|種類|概要|
|:-|:-|
|GPGPU|元々の使用目的であるグラフィック以外の用途で使用されるGPUの総称|
|CPU|高性能なコアが少数•複雑で連続的な処理が得意|
|GPU|比較的低性能なコアが多数•簡単な並列処理が得意•ニューラルネットの学習は単純な行列演算が多いので、高速化が可能|

## モデルの軽量化

モデルの精度を維持しつつパラメータや演算回数を低減する手法の総称.

#### モデルの軽量化の利用

- モデルの軽量化はモバイル, IoT 機器において有用な手法
- モバイル端末や IoT はパソコンに比べ性能が大きく劣る
    - 主に計算速度と搭載されているメモリ

モデルの軽量化は計算の高速化と省メモリ化を行うためモバイル、IoT 機器と相性が良い手法になる。

### 代表的な３つの手法

|イメージ|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/ee7a0bdd-b5e1-d16a-8bff-0d33faa5661a.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/73552445-ff8c-8be1-511b-4b83c235f3a1.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/388f1f00-7024-2516-c24b-00944ed41909.png)|
|:-:|:-:|:-:|:-:|
|手法|量子化|蒸留|プルーニング|
|概要|重みの精度を下げることにより計算の高速化と省メモリ化を行う技術|複雑で精度の良い教師モデルから軽量な生徒モデルを効率よく学習を行う技術|寄与の少ないニューロンをモデルから削減し高速化と省メモリ化を行う技術|
|利点|高速化、省メモリ化|少ない学習回数でより精度の良いモデルを作成する|高速化、省メモリ化|
|欠点|精度の低下| － | － |

# [day4-4] 応用モデル

## MobileNet

- 論文タイトル
    - MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications
- __ディープラーニングモデルの軽量化・高速化・高精度化を実現__

### Depthwise Separable Convolution

- 空間方向とチャネル方向の計算を Depthwise Convolution と Pointwise Convolution と呼ばれる演算によって個別に行う。
![スクリーンショット 2021-07-19 16.22.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/a48dfd11-7ae2-b3ee-9e51-f97319094242.png)

### Depthwise Convolution

チャネルごとに空間方向へ畳み込む。

チャネルごとに$~D_k\times D_k\times 1~$のサイズのフィルターをそれぞれ用いて計算を行うため、その計算量は$~H\times W\times C\times K\times K~$となる。
![スクリーンショット 2021-07-19 15.59.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/d7d0c6fb-8148-5f95-7c6d-11c7283a42c3.png)

- 仕組み
    - 入力マップのチャネルごとに畳み込みを実施
    - 出力マップをそれらと結合（入力マップのチャネル数と同じになる）
- 通常の畳み込みカーネルは全ての層にかかっていることを考えると計算量が大幅に削減可能
- 各層ごとの畳み込みなので層間の関係性は全く考慮されない。通常はPW畳み込みとセットで使うことで解決

### Pointwise Convolution

Depthwise Convolution の出力を Pointwise Convolution によってチャネル方向に畳み込む。

出力チャネルごとに$~1\times 1\times M$サイズのフィルターをそれぞれ用いて計算を行うため、その計算量は$~H\times W\times C\times M~$となる。
![スクリーンショット 2021-07-19 16.00.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/1a969997-981c-3fdc-7ee3-fe798b6e7f65.png)

- 仕組み
    - 1 x 1 convとも呼ばれる（正確には1 x 1 x c）
    - 入力マップのポイントごとに畳み込みを実施
    - 出力マップ（チャネル数）はフィルタ数分だけ作成可能（任意のサイズが指定可能）

## DenseNet

- 論文タイトル
    - Densely Connected Convolutional Networks. G. Huang et., al. 2016
- 概要
    - Dense Convolutional Network（以下、DenseNet）は、畳込みニューラルネットワーク（以下、CNN）アーキテクチャの一種である。ニューラルネットワークでは層が深くなるにつれて、学習が難しくなるという問題があったが、Residual Network（以下、ResNet）などのCNNアーキテクチャでは前方の層から後方の層へアイデンティティ接続を介してパスを作ることで問題を対処した。DenseBlockと呼ばれるモジュールを用いた、DenseNetもそのようなアーキテクチャの一つである。

### 全体像

- Initial Convolution(初期の畳み込み)
- Dense Block(Denseブロック)
- Transition Layer(変換レイヤー)
- Classification Layer(判別レイヤー)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/36316930-8b19-1a40-1a67-134c125529e7.png)
https://arxiv.org/pdf/1608.06993.pdf

### Dense Block

出力層に前の層の入力を足しあわせる
    - 層間の情報の伝達を最大にするために全ての同特徴量サイズの層を結合する
![スクリーンショット 2021-07-19 17.18.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/59866e19-7197-d927-31f6-cdbee8f40246.png)

#### Dense Block 内のレイヤ処理概要

1. 特徴マップの入力に対し、下記の処理で出力を計算
    - Batch 正規化
    - Relu 関数による変換
    - 3x3 畳み込み層による処理
![スクリーンショット 2021-07-19 17.18.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/02af4f47-ba8a-e495-f1bd-f733b9b44dc5.png)

1. 前スライドで計算した出力に入力特徴マップを足し合わせる
    - 入力特徴マップのチャンネル数が$~l\times k~$だった場合、出力は$~(l+1)\times k~$となる
    - 第$~l~$層の出力を$~x_l=H_l([x_0,x_1,\cdots ,x_{l-1}])~$とすると
![スクリーンショット 2021-07-19 17.19.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/7c4ed94e-bd3f-e65d-b77b-dcde50f0d204.png)

#### growth rate（成長率）
- k をネットワークの growth rate と呼ぶ。(ハイパーパラメータ)
    - k が大きくなるほどネットワークが大きくなるため、小さな整数に設定するのがよい。
![スクリーンショット 2021-07-19 17.26.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/e56dde59-cf77-f526-3d4d-53c724d12dae.png)

### Transition Layer

- 1x1 畳み込みと 2x2 の Average Pooling の処理をする。
- CNNでは中間層でチャネルサイズを変更し○特徴マップのサイズを変更し,ダウンサンプリングを行うため,Transition Layerと呼ばれる層でDence blockをつなぐ
![スクリーンショット 2021-07-19 17.27.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/ac818f7b-094b-a84f-a251-91b850a12a58.png)

## Batch Normalization とその派生
- __Batch Normalization__
    - ミニバッチに含まれる sample の同一チャネルが同一分布に従うよう正規化
- __Layer Normalozation__
    - それぞれのsampleの全てのpixelsが同一分布に従うよう正規化
- __Instance Normalization__
    - さらにchannelも同一分布に従うよう正規化
![スクリーンショット 2021-07-19 18.05.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/965686a5-c936-39c2-a464-746643d644fb.png)

## Batch Normalization
![スクリーンショット 2021-07-19 18.09.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/6205b3bf-ff41-117c-b7ed-265731902046.png)

- H x W x C の sample が N 個あった場合に、N 個の同一チャネルが正規化の単位
- ミニバッチのサイズを大きく取れない場合には,効果が薄くなる。

## Layer Normalozation
![スクリーンショット 2021-07-19 18.09.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/4e55cf13-b2da-e538-2f02-60e6adecbe25.png)

- N 個の sample のうち一つに注目。H x W x C の全ての pixel が正規化の単位。
- ミニバッチの数に依存しないので,上記の問題を解消できていると考えられる。

Layer Normalozation は、入力データや重み行列に対して、以下の操作を施しても出力が変わらないことが知られている。

- 入力データのスケールに関してロバスト
- 重み行列のスケールやシフトに関してロバスト

## Instance Normalization
![スクリーンショット 2021-07-19 18.09.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/da77bcb1-d902-8e18-19c1-9a9b0d3ac0f5.png)

- 各サンプルの各チャネルごとに正規化
    - Batch Normalization のバッチサイズ 1 の場合と同じ
- コントラストの正規化に寄与
- 画像のスタイル転送やテクスチャ合成タスクなどで利用

## Wavenet
生の音声波形を生成する深層学習モデル

- 時系列データに対して畳み込み（Dilated Convolution）を適用する。

### Dilated Convolution

- そうが深くなるにつれて畳み込むリンクを離す。
- 受容野を簡単に増やすことができる。

![スクリーンショット 2021-07-19 18.22.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/6728515f-296d-4f93-8894-1afd9b3a633e.png)
https://arxiv.org/pdf/1609.03499.pdf

## テキスト内の問題
[Page.86]
解答：（い）$~H\times W\times C\times K\times K~$、（う）$~H\times W\times C\times M~$

[Page.106-107]
解答：（あ）Dilated causal convolution、（い）パラメータ数に対する受容野が広い

# [day4-5] Transformer

## Seq2seq
系列（Sequence）を入力として、系列を出力するもの。

- Encoder-Decoderモデルとも呼ばれる。
- 入力系列がEncode（内部状態に変換）され、内部状態からDecode（系列に変換）する。
- 系列データの例
    - 翻訳 （英語 → 日本語）
    - 音声認識（波形 → テキスト）
    - チャットボット（テキスト → テキスト）

#### Seq2seq

- ２つの RNN が連結されたもので、１つめの RNN が Encoder、２つめの RNN が Decoder である。
![スクリーンショット 2021-07-19 19.59.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/0ec0b827-9d21-1104-1921-4c15b49552a7.png)
    - Encoder
        - 自然文をあたえると、内部状態ベクトル h を出力する。
    - Decoder
        - Encoder から受け取った内部状態ベクトル h を受け取って、文章を生成する。


- Decoderのoutput側に正解を当てれば教師あり学習がEnd2endで行える。
![スクリーンショット 2021-07-19 20.02.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/ef069949-d175-2b58-c2d0-e7da841d693a.png)

## Transformer

- Encoder-Decoder モデルは長い文章に弱い
    - 翻訳元の文章をひとつの固定長のベクトルに変換するのて、長い文章ほど不利になるため。
- 解決策としての Attention
    - 情報量が多くなってきたときに、何に注意を払って、何に注意を払わないべきかを学習で決めていく方法
- Attention を使って発表されたのが Transformer
    - 2017年6月に登場
    - RNNを使わない
        - 必要なのはAttentionだけ
![スクリーンショット 2021-07-19 22.59.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/75d859c2-f3ce-df06-d263-887ba7c12fee.png)

### Transformer-Encoder

自己注意機構により文脈を考慮して各単語をエンコード

- Self-Attention:入力を全て同じにして学習的に注意箇所を決めていく
- Position-Wise Feed-Forward Networks:位置情報を保持したまま順伝播させる
- Scaled dot product Attention:全単語に関するAttentionをまとめて計算する
- Multi-Head Attention:重みパラメタの異なる８個のヘッドを使用
    - ８個のScaled Dot-Product Attentionの出力をConcat
    - それぞれのヘッドが異なる種類の情報を収集

### Decoder

- Encoderと同じく6層
    - 各層で二種類の注意機構
    - 注意機構の仕組みはEncoderとほぼ同じ
- 自己注意機構
    - 生成単語列の情報を収集
        - 直下の層の出力へのアテンション
    - 未来の情報を見ないようにマスク
- Encoder-Decoder Attention
    - 入力文の情報を収集
        - Encoderの出力へのアテンション

### Add & Norm

- Add (Residual Connection)
    - 入出力の差分を学習させる
    - 実装上は出力に入力をそのまま加算するだけ
    - 効果：学習・テストエラーの低減
- Norm (Layer Normalization)
    - 各層においてバイアスを除く活性化関数への入力を平均０、分散１に正則化
    - 効果：学習の高速化

### Position Encoding

RNNを用いないので単語列の語順情報を追加する必要がある

## 参考動画

https://youtu.be/IcCIu5Gx6uA

https://youtu.be/bPdyuIebXWM

https://youtu.be/50XvMaWhiTY


## 実装演習

### 演習 Sequence-to-Sequence (Seq2Seq) モデル
lecture_chap1_exercise_public.ipynb

__データセットの確認__

```:train.en
i can 't tell who will arrive first .
many animals have been destroyed by men .
i 'm in the tennis club .
emi looks happy .
please bear this fact in mind .
she takes care of my children .
we want to be international .
you ought not to break your promise .
when you cross the street , watch out for cars .
i have nothing to live for .
```

```:train.ja
誰 が 一番 に 着 く か 私 に は 分か り ま せ ん 。
多く の 動物 が 人間 に よ っ て 滅ぼ さ れ た 。
私 は テニス 部員 で す 。
エミ は 幸せ そう に 見え ま す 。
この 事実 を 心 に 留め て お い て 下さ い 。
彼女 は 私 たち の 世話 を し て くれ る 。
私 達 は 国際 人 に な り た い と 思 い ま す 。
約束 を 破 る べ き で は あ り ま せ ん 。
道路 を 横切 る とき は 車 に 注意 し なさ い 。
私 に は 生き 甲斐 が な い 。
```

__入力と教師データ__

```
train data ['where', 'shall', 'we', 'eat', 'tonight', '?']
valid data ['you', 'may', 'extend', 'your', 'stay', 'in', 'tokyo', '.']
```

__単語辞書の語彙数__

```
入力言語の語彙数： 3725
出力言語の語彙数： 4405
```

__入力と教師データ（IDへの変換後）__

```
train data [132, 321, 28, 290, 367, 12, 2]
valid data [8, 93, 3532, 36, 236, 13, 284, 4, 2]
```

__各サンプルの系列長__

```
各サンプルの系列長: [4, 3, 2]

paddingされたテンソル:
 tensor([[1, 2, 3, 4],
        [5, 6, 7, 0],
        [8, 9, 0, 0]])
padding & 転置されたテンソル:
 tensor([[1, 5, 8],
        [2, 6, 9],
        [3, 7, 0],
        [4, 0, 0]])
padding & 転置されたテンソルのサイズ:
 torch.Size([4, 3])
```

__PackedSequenceのインスタンス__

```
PackedSequenceのインスタンス:
 PackedSequence(data=tensor([1, 5, 8, 2, 6, 9, 3, 7, 4]), batch_sizes=tensor([3, 3, 2, 1]), sorted_indices=None, unsorted_indices=None)
```

__PADを含む元のテンソル、各サンプルの系列長__

```
PADを含む元のテンソル:
 tensor([[1, 5, 8],
        [2, 6, 9],
        [3, 7, 0],
        [4, 0, 0]])
各サンプルの系列長: tensor([4, 3, 2])
```

__学習__

```
Epoch 1: train_loss: 52.58  train_bleu: 3.15  valid_loss: 48.89  valid_bleu: 4.13
--------------------------------------------------------------------------------
Epoch 2: train_loss: 44.55  train_bleu: 7.62  valid_loss: 44.79  valid_bleu: 8.27
--------------------------------------------------------------------------------
Epoch 3: train_loss: 40.39  train_bleu: 11.00  valid_loss: 42.36  valid_bleu: 11.22
--------------------------------------------------------------------------------
Epoch 4: train_loss: 36.98  train_bleu: 14.46  valid_loss: 41.34  valid_bleu: 14.71
--------------------------------------------------------------------------------
Epoch 5: train_loss: 34.87  train_bleu: 16.93  valid_loss: 40.27  valid_bleu: 15.01
--------------------------------------------------------------------------------
Epoch 6: train_loss: 33.01  train_bleu: 19.11  valid_loss: 40.35  valid_bleu: 16.49
--------------------------------------------------------------------------------
Epoch 7: train_loss: 31.60  train_bleu: 21.04  valid_loss: 40.03  valid_bleu: 16.20
--------------------------------------------------------------------------------
Epoch 8: train_loss: 29.85  train_bleu: 23.44  valid_loss: 40.01  valid_bleu: 16.86
--------------------------------------------------------------------------------
Epoch 9: train_loss: 28.78  train_bleu: 25.10  valid_loss: 40.64  valid_bleu: 17.78
--------------------------------------------------------------------------------
Epoch 10: train_loss: 27.82  train_bleu: 26.70  valid_loss: 40.61  valid_bleu: 17.08
--------------------------------------------------------------------------------
```

__評価モデル__

```
EncoderDecoder(
  (encoder): Encoder(
    (embedding): Embedding(3725, 256, padding_idx=0)
    (gru): GRU(256, 256)
  )
  (decoder): Decoder(
    (embedding): Embedding(4405, 256, padding_idx=0)
    (gru): GRU(256, 256)
    (out): Linear(in_features=256, out_features=4405, bias=True)
  )
)
```

__生成（1回目）__

```
src: i can 't swim at all .
tgt: 私 は 少し も 泳げ な い 。
out: 私 は は 泳げ な い 。
without trim: 私 は は 泳げ な い 。 </S> </S> </S> </S> </S> </S> </S> </S> </S> </S> </S> </S> </S>
```

__生成（2回目）__

```
src: show your own business .
tgt: 自分 の 事 を しろ 。
out: よけい の 仕事 で は を し 。
without trim: よけい の 仕事 で は を し 。 </S> </S> </S> </S> </S> </S> </S> </S> </S> </S> </S> </S>
```

__生成（3回目）__

```
src: he lived a hard life .
tgt: 彼 は つら い 人生 を 送 っ た 。
out: 彼 は 一生 い 生活 を 送 っ た 。
without trim: 彼 は 一生 い 生活 を 送 っ た 。 </S> </S> </S> </S> </S> </S> </S> </S> </S> </S>
```

__生成（4回目）__

```
src: no . i 'm sorry , i 've got to go back early .
tgt: ごめん なさ い 。 早 く 帰 ら な く ちゃ 。
out: ごめん て 、 、 、 、 り ま せ せ 。
without trim: ごめん て 、 、 、 、 り ま せ せ 。 </S> 。 </S> </S> </S> </S> </S> </S> </S>
```

__生成（5回目）__

```
src: she wrote to me to come at once .
tgt: 彼女 は 私 に すぐ 来 い と の 便り を よこ し た 。
out: 彼女 は 私 に に に よう に に に た た 。
without trim: 彼女 は 私 に に に よう に に に た た 。 </S> </S> </S> </S> </S> </S> </S>
```

__BLEUの評価__

```
17.29355646
```

### 演習 Transformerモデル
lecture_chap2_exercise_public.ipynb

__データセットの中身を確認__

```
train_X: [['where', 'shall', 'we', 'eat', 'tonight', '?'], ['i', 'made', 'a', 'big', 'mistake', 'in', 'choosing', 'my', 'wife', '.'], ['i', "'ll", 'have', 'to', 'think', 'about', 'it', '.'], ['it', 'is', 'called', 'a', 'lily', '.'], ['could', 'you', 'lend', 'me', 'some', 'money', 'until', 'this', 'weekend', '?']]
train_Y: [['今夜', 'は', 'どこ', 'で', '食事', 'を', 'し', 'よ', 'う', 'か', '。'], ['僕', 'は', '妻', 'を', '選', 'ぶ', 'の', 'に', '大変', 'な', '間違い', 'を', 'し', 'た', '。'], ['考え', 'と', 'く', 'よ', '。'], ['ｌｉｌｙ', 'と', '呼', 'ば', 'れ', 'て', 'い', 'ま', 'す', '。'], ['今週末', 'まで', 'いくら', 'か', '金', 'を', '貸', 'し', 'て', 'くれ', 'ま', 'せ', 'ん', 'か', '。']]
```

__Position Encodingを可視化__
![スクリーンショット 2021-07-20 0.36.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/481992d6-d72b-7161-3154-1b9c2aa95c1e.png)

__key側の系列のPADトークンに対してAttentionを行わないようにするマスク__

```
query:
 tensor([[1, 2, 3]])
key:
 tensor([[4, 5, 6, 7, 0]])
mask:
 tensor([[[False, False, False, False,  True],
         [False, False, False, False,  True],
         [False, False, False, False,  True]]])
```

__Decoder側でSelf Attentionを行う際に、各時刻で未来の情報に対するAttentionを行わないようにするマスク__

```
seq:
 tensor([[1, 2, 3, 4]])
mask:
 tensor([[[0, 1, 1, 1],
         [0, 0, 1, 1],
         [0, 0, 0, 1],
         [0, 0, 0, 0]]], device='cuda:0', dtype=torch.uint8)
```

__学習__

```
Epoch 1 [0.4min]: train_loss: 79.50  train_bleu: 4.04  valid_loss: 43.11  valid_bleu: 9.72
--------------------------------------------------------------------------------
Epoch 2 [0.4min]: train_loss: 41.06  train_bleu: 10.94  valid_loss: 33.29  valid_bleu: 16.03
--------------------------------------------------------------------------------
Epoch 3 [0.4min]: train_loss: 33.08  train_bleu: 16.90  valid_loss: 28.67  valid_bleu: 21.57
--------------------------------------------------------------------------------
Epoch 4 [0.4min]: train_loss: 28.79  train_bleu: 21.23  valid_loss: 25.98  valid_bleu: 25.09
--------------------------------------------------------------------------------
Epoch 5 [0.4min]: train_loss: 26.15  train_bleu: 24.04  valid_loss: 24.41  valid_bleu: 26.68
--------------------------------------------------------------------------------
Epoch 6 [0.4min]: train_loss: 24.22  train_bleu: 26.44  valid_loss: 23.19  valid_bleu: 28.84
--------------------------------------------------------------------------------
Epoch 7 [0.4min]: train_loss: 22.73  train_bleu: 28.32  valid_loss: 22.54  valid_bleu: 29.08
--------------------------------------------------------------------------------
Epoch 8 [0.4min]: train_loss: 21.50  train_bleu: 29.86  valid_loss: 21.67  valid_bleu: 31.04
--------------------------------------------------------------------------------
Epoch 9 [0.4min]: train_loss: 20.48  train_bleu: 31.31  valid_loss: 20.99  valid_bleu: 32.24
--------------------------------------------------------------------------------
Epoch 10 [0.4min]: train_loss: 19.58  train_bleu: 32.64  valid_loss: 20.52  valid_bleu: 33.09
--------------------------------------------------------------------------------
Epoch 11 [0.4min]: train_loss: 18.76  train_bleu: 33.78  valid_loss: 20.14  valid_bleu: 34.08
--------------------------------------------------------------------------------
Epoch 12 [0.4min]: train_loss: 18.05  train_bleu: 34.91  valid_loss: 19.90  valid_bleu: 33.79
--------------------------------------------------------------------------------
Epoch 13 [0.4min]: train_loss: 17.42  train_bleu: 35.78  valid_loss: 19.31  valid_bleu: 35.03
--------------------------------------------------------------------------------
Epoch 14 [0.3min]: train_loss: 16.83  train_bleu: 36.84  valid_loss: 19.19  valid_bleu: 35.19
--------------------------------------------------------------------------------
Epoch 15 [0.4min]: train_loss: 16.28  train_bleu: 37.77  valid_loss: 19.10  valid_bleu: 35.93
--------------------------------------------------------------------------------
```

__生成（1回目）__

```
src: the water was cut off yesterday . </S> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD>
tgt: 昨日 水道 を 止め られ た 。 </S> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD>
out: 昨日 水 は 昨日 昨日 <UNK> を 切 っ て い た 。
```

__生成（2回目）__

```
src: i should like to see you this afternoon . </S> <PAD> <PAD> <PAD> <PAD>
tgt: 今日 の 午後 お 会 い し た い の で す が 。 </S> <PAD>
out: 今日 の 午後 は 君 に は 必ず お 目 を 見 る べ き だ 。
```

__生成（3回目）__

```
src: i gave him a call . </S> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD>
tgt: 私 は 彼 に 電話 を し た 。 </S> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD>
out: 全て は 彼 に 電話 を かけ た 。
```

__生成（4回目）__

```
src: show your own business . </S> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD>
tgt: 自分 の 事 を しろ 。 </S> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD>
out: お 子 子 さん は 自分 の 仕事 を し なさ い 。
```

__生成（5回目）__

```
src: the water was cut off yesterday . </S> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD>
tgt: 昨日 水道 を 止め られ た 。 </S> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD>
out: 昨日 水 は 昨日 昨日 <UNK> を 切 っ て い た 。
```

__BLEUの評価__

```
22.83017571
```

# [day4-6] 物体検知・セグメンテーション

## 広義の物体認識タスク

|![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/a6166c23-bd5b-8a0d-6b5a-c52efe10ea3c.png)<BR>分類|![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/b9b5b559-a8c4-717a-71f1-43f413d32ec3.png)<BR>物体検知|![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/125f73e8-cff9-01e8-b8f4-94ccbc21207b.png)<BR>意味領域検知|![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/9ba13504-3ccb-3fee-7843-4b62f0b6fd49.png)<BR>個体領域分割|
|:-:|:-:|:-:|:-:|
|（画像に対し単一または複数の）<BR>クラスラベル|Bounding Box<BR>[bbox/BB]|各ピクセルに対し単一の）<BR>クラスラベル|（各ピクセルに対し単一の）<BR>クラスラベル|

## 代表的データセット
![スクリーンショット 2021-07-20 4.30.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/a9025f83-449b-d009-b98d-37c8e3e14e67.png)

## 評価指標

### 分類問題における評価指標
![スクリーンショット 2021-07-20 4.39.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/572e2717-216b-6f3b-da4b-e3a693de82f4.png)

### IoU：Intersection over Union
物体検出においてはクラスラベルだけでなく, 物体位置の予測精度も評価
Confusion Matrixの要素を用いて表現：$IoU=\dfrac{TP}{TP+FP+FN}$


![スクリーンショット 2021-07-20 4.54.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/16a3567f-d7e3-93e5-68ab-cc84cc8736ff.png)

### Average Precision / mean Average Precision
- $AP$：Average Precision

```math
AP=\int_0^1P(R)dR~
```

- $mAP$：mean Average Precision

```math
mAP=\dfrac{1}{C}\sum_{i=1}^CAP_i~
```

- $mAP_{COCO}$：MS COCOで導入された指標
    - ここまで, IoU閾値は0.5で固定
        - 0.5から0.95まで0.05刻みでAP＆mAPを計算し算術平均を計算

```math
mAP_{COCO}=\dfrac{mAP_{0.5}+mAP_{0.55}+\cdots+mAP_{0.95}}{10}~
```

### FPS：Flames per Second
［物体検知］応用上の要請から, 検出精度に加え検出速度も問題となる

## 物体検知の大枠

### 物体検知のフレームワーク
- ２段階検出器（Two-stage detector）
    - 候補領域の検出とクラス推定を別々に行う
    - 相対的に精度が高い傾向
    - 相対的に計算量が大きく推論も遅い傾向
- １段階検出器（One-stage detector）
    - 候補領域の検出とクラス推定を同時に行う
    - 相対的に精度が低い傾向
    - 相対的に計算量が小さく推論も早い傾向

## SSD: Single Shot Detector
![スクリーンショット 2021-07-20 5.08.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/842d78ba-4483-0eec-8fa2-73c7436cc02d.png)

### SSDのネットワークアーキテクチャ
![スクリーンショット 2021-07-20 5.09.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/0b2af316-ddff-52c7-85e9-61def2d886f0.png)

## Semantic Segmentation

### ざっくり分かるSemantic Segmentationの肝
「Up-samplingの壁」
![スクリーンショット 2021-07-20 5.17.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/49c7f94b-68cf-a693-6b7d-7b8ac65dd947.png)

- 受容野を広げる典型
    - ① 深いConvolution層
    - ② プーリング＆ストライド

### FCN（Fully Convolutional Network）の基本アイディア
![スクリーンショット 2021-07-20 5.22.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/e67efbd9-bfa5-c496-dd30-5104135a39d7.png)

### Deconvolution/Transposed convolution
処理手順

1. 特徴マップのpixel間隔を stride だけ空ける
1. 特徴マップのまわりに (kernel size-1)-padding だけ余白を作る
1. 畳み込み演算を行う

kernel size = 3, padding = 1, stride = 1のDeconv.により 3×3の特徴マップが5×5にUp-samplingされる様子
![スクリーンショット 2021-07-20 5.25.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/49600b24-e1e6-31db-bc95-e0888a56d1c4.png)
https://github.com/vdumoulin/conv_arithmetic

※逆畳み込みと呼ばれることも多いが畳み込みの逆演算ではないことに注意
  → 当然、__poolingで失われた情報__が復元されるわけではない

### 輪郭情報の補完
![スクリーンショット 2021-07-20 5.29.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/cd4492fd-0c30-14db-ad8c-9251a5344e78.png)
https://arxiv.org/pdf/1411.4038.pdf

### U-Net
Input から MaxPooling をもちいて特徴量サイズが小さくなり、さらに upconvolution をもちいて特徴量のサイズを元と同じサイズに大きくする。
![スクリーンショット 2021-07-20 5.56.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/5c317317-c716-f003-e9fc-4991f591a57a.png)
https://arxiv.org/pdf/1505.04597.pdf

- FCN との違い
    - FCN は、upsampling したものと低レイヤの情報を要素ごとに足し算をして、それを新たな特徴マップにしていた。
    - U-netは、upsampling によって 52x52 から 104x104 と特徴量サイズは大きくなっているが、チャネル方向が256（104x104x256）あくまで右半分だけ、左半分については低レイヤから Skip-connection で持ってきておりサイズは 104x104x256 である。この２つをチャネル方向に結合して 512 チャネルにしている。


### Unpooling
![スクリーンショット 2021-07-20 5.39.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/3e30969d-f031-3be5-6bab-f527548d409e.png)
https://arxiv.org/pdf/1505.04366.pdf

### Dilated Convolution
![スクリーンショット 2021-07-20 5.41.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670908/06dbef91-4a41-a6f1-da1a-25b9f1ea15a2.png)
https://arxiv.org/pdf/1511.07122.pdf

## 確認テスト

なし

## 実装演習

なし