【ラビットチャレンジ】実装演習レポート⑥深層学習day3

<script type="text/javascript" async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.2.2/es5/tex-mml-chtml.min.js">
</script>
<script type="text/x-mathjax-config">
 MathJax.Hub.Config({
 tex2jax: {
 inlineMath: [['$', '$'] ],
 displayMath: [ ['$$','$$'], ["\\[","\\]"] ]
 }
 });
</script>

# 概要
E資格受験のための認定講座「ラビットチャレンジ」の実装演習レポート、深層学習day3編です。
確認テストと実装演習は省略しています。情報の網羅性は低いですがご理解ください。
外部資料からの内容は※をつけています。
※１：「ゼロから作るDeep Learning」
※２：「JAX/Flaxで学ぶディープラーニングの仕組み」

# Section1 再帰型ニューラルネットワークの概念
* RNN
  * 時系列データに対応できるニューラルネットワーク
  * 音声、テキストなど時間的順序があり相互依存するデータ
  * 過去の時間t-1の状態を保持し次の時間tを再帰（循環）的に求める
  * 中間層からの出力を次の中間層の入力に使う
* BPTT
  * RNNにおけるパラメータ調整方法
  * 誤差逆伝播法の一種
  * 時系列を遡れば遡るほど勾配が消失していく
  * Truncated BPTT※１
    * 大きな時系列データを扱うときに、ネットワークを細かくして誤差逆伝播法を行う
    * 順伝播の流れは維持
    * 逆伝播は断ち切る

# Section2 LSTM
* ゲート付きRNN（３つ）
* 記憶セルで情報を保持
* Long Short-Term Memory 短期記憶を長い時間継続できる
* 勾配消失および勾配爆発問題を解消する
* ゲートは流れる水の量を調整するバルブのイメージ※１
* CEC
  * 勾配を１にする
  * 入力データの重みが一律で学習特性がない
  * 入力・出力ゲートを追加して重みを可変可能に
* 忘却ゲート
  * CECにおいて保管されている過去の情報を然るべきタイミングで忘却する
* 覗き穴結合
  * CEC自身の値に重み行列を介して伝播可能にした構造
  * 保存された過去の情報を任意のタイミングで他ノードに伝播させたり忘却させたりする
* 多層化によって精度向上が可能※１
* 多層化すると過学習が起きやすい（RNNは過学習しやすい）ため、Dropoutなど正則化が有効※１

# Section3 GRU
* ゲート付きRNN（２つ）
* LSTMではパラメータ数が多く計算負荷が高くなる問題があった
* LSTMのパラメータを削減した構造
* 計算負荷が低い
* 記憶セルを必要としない※１
* リセットゲート
  * 過去の隠れ状態をどれだけ無視するか
* 更新ゲート
  * 隠れ状態を更新する
  * 忘却と入力ゲートの役割
* LSTMとGRUの性能差はタスクやハイパーパラメータによる※１
  * GRUはパラメータが少なく計算量も小さいため、データセットが小さい場合や繰り返し試行が必要な場合に適している
* LSTMの課題
  パラメータ数が多く計算負荷が高くなりやすい
* CECの課題
  入力データの重みが一律であり学習特性がないこと
* LSTMとGRUの違い
  ゲート数が違い、パラメータ数が違うため計算負荷に差が出る

# Section4 双方向RNN
* 過去だけでなく未来の情報も加味して精度を向上させるモデル
* 各時刻で二つの隠れ状態を連結し、最終的な隠れ状態ベクトル（特徴量）とする
* 文章の推敲や機械翻訳などに活用される
  * 時系列データ（文章）が全て与えられているため、右から左へも読んで繋がりや解釈を捉えるイメージ※１
  * ひとつの単語の周囲の情報をバランスよく含ませられる※１

# Section5 Seq2Seq
* Encoder-Decoderモデルの一種
* 機械対話や機械翻訳などに使用される
* Encoder RNN
  * インプットしたテキストデータを単語等のトークンに区切って渡す構造
  * Taking：トークンごとのIDに分割
  * Enbedding：IDから、そのトークンを表す分散表現ベクトルに変換
  * Encoder RNN：ベクトルを順番にRNNに入力
* Decoder RNN
  * アウトプットデータを単語等のトークンごとに生成する構造
  * Sampling：Encoder RNNから得られる生成確率に基づいてトークンを選ぶ
  * Enbedding：トークンをEnbeddingしてDecoder RNNの次の入力とする
* HRED
  * 過去n-1個の発話から次の発話を生成する
  * Seq2Seqの一問一答しかできないという課題を解決
  * Seq2Seq + Context RNN
  * 会話の「流れ」に疎い
  * 短く情報量に乏しい答えをしがち
* VHRED
  * HREDにVAEの潜在変数の概念を追加
* オートエンコーダ
  * 教師なし学習
  * ニューラルネットワーク
  * エンコーダとデコーダからなる
  * 潜在変数を抽出し、データを再構築して誤差を元にパラメータ更新
  * 次元削減や特徴抽出に使用される
* VAE
  * オートエンコーダの潜在変数に確率分布を導入したもの
* HREDは過去の発話から生成することでSeq2Seqの一問一答しかできない課題を解決したもの、VHREDはHREDにVAEの潜在変数の概念を追加して流れのある会話ができるようにしたもの

# Section6 word2vec
* 推論ベースの手法
  * モデルはコンテキスト情報を入力として受け取り、各単語の出現するであろう確率を出力
* 固定長形式で単語を表してニューラルネットワークに与える
* 学習データからボキャブラリを作成する
* one-hotベクトル
  * 特定の単語が１、それ以外が０のベクトル
  * 単語数分の要素を持つ
  * 単語を固定長のベクトルに変換したことになる
* CBOW※１
  * word2vecで提案されているモデル
  * コンテキスト（周囲の単語）からターゲットを推測するニューラルネットワーク
  * 中間層は各入力層の変換後の値の平均
  * 出力層のニューロンは各単語のスコアに対応している（Softmax関数に通して確率に）
  * 入力から中間の全結合層の重みが分散表現である
* skip-gram
  * ひとつの単語（ターゲット）から周囲の複数の単語を推測する
  
# Section7 Attention Mecanism
* 入力と出力のどの単語が関連しているのかの関連度を学習する仕組み
* seq2seqは単語数に関わらず固定次元ベクトルに入力するため長い文章への対応が難しい
* 各単語のベクトルに重みをつけるレイヤ※１
  * DecoderのLSTMレイヤの隠れ状態ベクトルと、Encoderの出力との類似度を内積で求める
  * Softmax関数で正規化し、重みになる
* 重み付き和を求めてコンテキストベクトルを出力するレイヤ※１
  * 行列の積を求める
* RNNは時系列データを処理するのに適したネットワークであり、word2vecは単語の分散表現ベクトルを得る手法。
* seq2seqはひとつの時系列データから別の時系列データを得る手法であり、Attention Mecanismは時系列データのそれぞれの関連性に重みをつける手法。

# VQ-VAE
* VAEの派生技術にあたる生成モデル
* 潜在変数が潜在変数が離散値となるように学習が行われる
  * EncoderとDecoderの間でベクトル量子化処理を行う
  * 離散的な表現の方がより簡潔にデータの特徴を捉えられる
  * データの特徴（輪郭など）をうまく捉えられなくなる”posterior collapse”を防ぐ
* VQ-VAE2では階層構造にすることでさらに高解像度画像が生成できる
* 量子化誤差※
  * 元のデータと量子化されたデータとの間で一部の情報が失われる可能性がある
* コードブックのベクトルも学習過程で更新されるため、全体としての学習負荷が高くなる可能性がある※
* 音声合成、自然言語処理、強化学習などに活用できる※

# フレームワーク演習 双方向RNN/勾配のクリッピング
* 勾配爆発の回避策
* 勾配のL2ノルムが閾値を超えた場合に修正する
$$
if ||\hat{g}|| \geqq threshold:\\ \hat{g} = \frac{threshold}{||\hat{g}||}\hat{g}
$$
（ニューラルネットワークで使われる全てのパラメータに対する勾配をひとつにまとめて$\hat{g}$と表現している）
* LSTMのモデルをコンパイルするタイミングで、クリッピングの指定をする
* クリッピング指定以外は変更する必要なし
* 上の修正式を定義（実装）するとき、０除算とならないように分母に微小な値（1e-6）を加算する※１
* 単純だが多くの場合うまくいく※１
* rateが1の時は勾配に変化がないため計算しない方が効率がいい※１

# フレームワーク演習 Seq2Seq
* エンコーダとデコーダはコンテキスト以外につながりのない分離したモデル構造となっている
* 推論時には逐次それまでに推論した結果を次の推論に用いるが、ステート（コンテキスト）はモデルの外に保持しておき、デコーダの入力として渡される
* Reverse※１
  * 入力データを反転させることで勾配の伝播がスムーズになると考えられる
  * 問題によって、学習速度と精度アップ
* Peeky※１
  * 全ての時刻のLSTMレイヤにエンコーダの出力を与える
  * 重みパラメータが増えるため計算量は増える

# フレームワーク演習 data-augumentation
画像
* Crop
  * 画像内の一部を切り抜く
  * 物体検出やセグメンテーションに有用
* Contrast
  * 画像データの明るさと暗さの差
  * 高いと特徴が強調され、低いと画像全体が均一
* Brightness
  * 画像の光度や輝度のレベル
  * 明るくするには全てのピクセル値を増加させる
* Hue（色相）
  * 色環の中で特定の色がどの位置にあるかを示し、色の種類やトーンを表す
  * モデルが異なる照明条件や色のバリエーションに適応できるようになる
* Gaussian Filter
  * 画像のノイズを減少させたりぼかして滑らかにしたりする
  * ガウシアンカーネルを用いて画像に畳み込み操作を適用する
  $$
  G(x,y) = \frac{1}{2\pi \sigma^2}e^{-\frac{x^2+y^2}{2\sigma^2}}
  $$
  $G$は2次元のガウス関数、$x,y$は座標、$σ$は標準偏差
  * $σ$を小さくしてカーネルを大きくするとぼかしが強くなる
* RandAugument
  * 最適なデータ拡張を探索する方法
  * 複数のデータ拡張操作からランダムに$n$回サンプルし、強さ$m$で順番に適用していく
* Random Erasing
  * 画像の中にランダムに一部の矩形領域にマスクを行う

テキスト
「EDA」
* SR
  * ランダムにn個の単語を選んで任意に選択した類義語に変える
* RI
  * ランダムに選んだ単語の類義語を任意に定め、任意の位置に入れることをn回繰り返す
* RS
  * ランダムに二つの単語を選び、位置を変えることをn回繰り返す
* RD
  * 確率pで各単語を削除する
  
https://arxiv.org/abs/2110.01852 によると※
* paraphrasing
  * あるデータとなるべく近いデータを新たに生成する
* noising
  * あるデータにノイズをかけて新たなデータを生成する
* sampling
  * 複数のデータをもとに完全に新たなデータを生成する

# フレームワーク演習 activate_functions
* 一般に、ニューラルネットワークの学習（パラメータ探索）では誤差逆伝播法が用いられるため、活性化関数には微分可能かつ渡された値から直接的に微分値を求める導関数が利用できるという要件がつく。
* 中間層に用いる活性化関数
  * ステップ関数
  * シグモイド関数
  * tanh
  * ReLU
  * Leaky ReLU
    * 入力が０以下のとき$αx$をとる（微少）
  * Swish
    * ReLUの代替候補

  $$
  f(x) = x\sigma(\beta x)=\frac{x}{1+e^{-\beta x}}
  $$

* 出力層に用いる活性化関数
  * 二値分類：シグモイド関数
  * 多値分類：ソフトマックス関数
    * シグモイド関数を多値分類用に拡張したもの
    * 出力値の総和が１
  * 回帰：恒等関数
* ロジット※２
  * シグモイド関数で確率に変換する前の一次関数の出力値のこと
  * 誤差関数を計算する際に使用する（対数をとったクロスエントロピーの計算などにおいて、個々の確率値が非常に小さいと計算精度が落ちる）