ゼロから作る Deep Learning 2 - izudon/izudon.github.io GitHub Wiki

日本語訳

3章 word2vec

準備

you say goodbye and i say hello .

  • 単語は7種類。
  • one-hot 表現 ( 1, 0, 0, 0, 0, 0, 0, 0 )
  • => ●○○○○○○
    • 7つのノードによる層として表現可能。

CBOW

  • 入力層
    • 7ノードのニューロンが2列。
    • 周囲の単語を one-hot 表現にしたもの。
      (前1後1計2(ウィンドウサイズ=1の前提))
  • 中間層(隠れ層)
    • 3ノードのニューロンが1列。
    • 7より小さくしてあるのはより「密な表現」にするため。
  • 出力層
    • 7ノードのニューロンが1列。
    • one-hot 表現の正解ベクトルと答え合わせ。
  • バイアス
    • ないものとする。
  • 重み(入力層->中間層)
    • W_in 2つの入力層で同じ行列を共用。7 x 3 行列。
  • 重み(中間層->出力層)
    • W_out 3 x 7 行列。
  • 単語の分散表現(ベクトル表現)
    • 重み W_in, W_out の各行が、対応する単語のベクトル表現。
    • W_in のみ用いる。W_out は通常用いない。

skip-gram

  • 上記の逆。

比較考察

  • skip-gram
    • 単語の分散表現の精度においては有利。
    • 計算速度は遅い。
      損失関数の計算が周囲の単語分必要となるため。

カウントベースと推論ベース(1)

カウントベースの問題点

  • 共起行列をまず作成するやり方は、単語数増を追随できない。
  • SVD は n x n 行列の処理時間が O ( n^3 ) である。

比較

  • 語彙に新しい単語を追加するケース
    • カウントベース
      • ゼロから計算を行う。
        (共起行列再作成、SVD 一連の計算が必要)
    • 推論ベース
      • パラメータの再学習で済む。
  • 単語の分散表現の性質や精度
    • カウントベース
      • 主に単語の類似性がエンコード
    • 推論ベース( word2vec 特に skip-gram )
      • 類似性に加えて、単語館のパターンも捉えられる。
        (王様 - 男 + 女 = 女王)
  • 但し実際には
    • 明確な優劣はつけられない(らしい)。
    • 双方関連性がある(らしい)。
      (特殊な行列分解をしているのと同じである)

2章 自然言語と単語の分散表現

  • 自然言語(Natural Language)
  • 自然言語処理(Natural Language Processing : NLP)
    • 柔らかい言語 ・・・ 柔軟に意味や形が変わる。
    • <=> プログラミング言語、マークアップ言語 = 固い言語
  • アプリケーションの一つは「質問応答システム」
    代表例が IBM の Watson = クイズ番組「ジェパディ!」で勝利。

単語の意味表現

  • 「深緋(こきあけ)」と言われても(コンピュータには)
    なんのことか分からないが
    「( R, G, B ) = ( 194, 0, 36 )」と言われればわかる。
  • このように、単語の意味をたとえば数値ベクトルのようなかたちで
    表現できないかということ。
    = 単語の分散表現

シソーラス

  • ある種の「辞書」。
  • 同義語や 'is a' といった関係性をグラフとして保持。
  • WordNet(1985- プリンストン大)が最も有名。

欠点

  • 時代の変化に対応できない。
    単語の意味は時代とともに変容する。新語も出る。
    「ヘヴィー」「ヤバい」
  • (関係性を定義づける)人の作業コストが高い。
    テキストから勝手に学ぶわけではない。
  • 単語の細かなニュアンスを定義できない。

カウントベース

  • コーパス(corpus)
    • = 大量のテキストデータ。
    • Wikipedia や Google News はコーパスになりうる。
  • 分布仮説
    • 単語の意味は、文章中でその周囲に分布する単語の分布から、 ある程度推測がつくという考え方。
    • 例えば I drink beer. I drink wine, too. とあれば、
      beer と wine は同種のものだと推測がつく。
    • この仮説をある程度正しいと思った上で、
      単語の意味をベクトルで表現できないか・・・。
  • コンテキスト
    • =その周囲に存在する単語。
  • ウィンドウサイズ
    • =周囲何単語目までを「周囲」とするか。
  • カウントベース とは
    • その単語周囲にどのような単語が表れたかを文字通り「カウント」し、 そのカウント結果をもって単語の分散表現をつくる考え方。

推論ベース(word2vec など)

(次章)

実際論

共起行列(co-occured matrix)

  • you say goodbye and i say hello . <- 単語7種類(ピリオド含)。
    これらを縦横に並べて 6x6 行列を作り、
    前後2単語以内に表れたものは 1、さもなくば 0 を値とする行列。
    • => 共起行列(co-occured matrix)

ベクトルの類似度(similarity)

  • 共起行列の各行ベクトル=各単語の分散表現。
  • 類似度
    • =各単語がどのくらい似通っているかを示す尺度。
    • -> いろいろ考えられる。
      • ユークリッド距離
      • 内積
      • コサイン類似度(cosine similarity)<= これ使う
        similarity( x, y ) := xy / || x || || y ||
        内積を長さの掛け算で割ってる・・・
        • 「なす角」が 0 で最大(+1)、真逆で最小(-1)。
        • 実務上:ゼロベクトルが入ると0割りとなるため
          eps = 1e-8 を分母に足す。
          (普通の値なら丸め誤差として吸収されるはず)。
        • youi の類似度を計算 -> 0.7071...

相互情報量(Pointwise Manual Information : PMI)

  • 単に出現回数の多い単語との相関が大と評価される矛盾。
    例 car は drive より the と関連性が深いと判断される恐れ。
  • PMI = 共起確率を各単語の出現確率で割戻す(そして2の対数)。
    そもそも出現率の高い単語との共起はその分低く評価される。
  • PPMI ( Positive PMI ) = 0 以下の PMI を 0 として評価。
    log 0 = - ∞ となるのを防ぐ。

次元削減

  • PPMI 行列には 0 が多く現れる。
    • 無駄が多い。
    • ノイズの影響を受けやすい。

特異値分解(Singular Value Decompisition : SVD)

  • X = U S V となる U と V を見つけることで次元削減するやり方。
  • 委細省略。

PTB データセット

  • word2vec の発明者 Tomas Miklov からダウンロードできるデータセット。
  • レアな単語は <unk> と表記されるなど利用しやすくなっている。

1章 ニューラルネットワークの復習

ゼロから作る Deep Learning の復習です。(一部新内容)。

  • NumPy による行列演算(テンソル演算?)。バッチ演算時の整合性。
  • 入力層、中間層(隠れ層)、出力層、重み、バイアス。
  • 活性化関数(中間層)=> シグモイド関数、ReLU、tanh
  • 活性化関数(最終出力層)=> 恒等関数(回帰問題)、ソフトマックス関数(分類問題)
  • 損失関数 => 2乗和誤差(回帰問題)、交差エントロピー誤差(分類問題)

計算グラフと順伝播・逆伝播

  • + => そのまま前方へ
  • * => 相手方の grad を掛ける
  • sum => repeat
  • repeat => sum
  • MatMul => 相手方の grad を掛ける。テンソルに拡張されただけで本質は同じ。
  • Sigmoid => y(1-y) シグモイド関数の微分は y だけで書ける(そのように設計した)。
  • Softmax with Loss (Cross Entropy Error) => y-t (t は教師データ)
    これも、このように綺麗に書けるように設計したもの。

学習のさせ方

  1. ミニバッチ
  2. 勾配の算出
  3. パラメータの更新
  4. (繰り返し)

勾配降下法

= GD(Gradient Descent)。

  • SGD (Stochastic Gradient Descent): 確率的勾配降下法 = 原始的
  • 他に Adagrad, Adam など = 効率良

クラスとしての実装上の工夫(レイヤ視点)

forward()backword()

  • 順伝播、逆伝播をそれぞれ担うメソッド名をこの名前で作成しておく。

paramgrad

  • (学習させる)パラメタと、(誤差逆伝播法で用いる)勾配を、
    この名前でインスタンス変数として保持しておくことにする。
  • params は、配列なりN次元配列のインスタンスを要素に持つ配列。

まとめレイヤ

  • 単純レイヤをいくつかまとめてまとめレイヤを作れる。
  • 本章では実際に TwoLayerNet をこのアプローチで作成。
    TwoLayersNet: Affine -> Sigmoid -> Affine
  • forward()backword() も各要素レイヤのそれを使いながら実装。
  • params は、各要素レイヤの params をまとめて保持している。
    • 配列 += 配列 で 配列の連結が( Python では )できる。
    • 数値の実態は各要素レイヤにおいたまままとめレイヤではそれを一望できる。

浅いコピー・深いコピー

  • インスタンスのコピー(=浅いコピー shallow copy )か、
    値のコピー(=深いコピー deep copy )かの違い。
  • 単純な代入の場合、浅いコピーになる。
  • 3点リーダを用いたコピーの場合、深いコピーになる。
  • 各要素レイヤで backword() が実行されるときには、
    paramsgrad に「深いコピー」をおこなう。
  • まとめレイヤの params はそのしくみで自動更新される。

実際に解いてみよう

  • 渦巻問題を TwoLayerNet で実際に解く。
  • 線形分離不可能な問題だが機械学習により非線型に分類がなされている。

ちなみに、ここで用いるデータセット「spiral」は、 データとしてデータが用意されているのではなく、 数式によってデータが生成される仕掛けだった。

Trainer クラス

  • データセット(spiral など)
  • オプティマイザ(SGD など)
  • 学習機械(TwoLayersNet など)

毎回書くのは大変なのでライブラリ化してある。

Trainer クラスにインスタンスを渡せば、 学習を自動的にやってくれる。

データのシャッフル

  • np.random.permutation() に引数 N を与えると、
    0 から N-1 までのランダムな並びを返してくれる。
    これが、データのシャッフルに使える。
>>> import numpy as np
>>> np.random.permutation(10)
array([3, 7, 8, 4, 0, 9, 5, 6, 2, 1])
>>> np.random.permutation(10)
array([2, 3, 0, 7, 1, 8, 6, 9, 4, 5])

ビット精度

  • 64ビット浮動小数点数がデフォルト。
    >>> import numpy as np
    >>> a = np.random.randn(3)
    >>> a.dtype
    dtype('float64')
  • 32ビット浮動小数点数にするには .astype('f') を用いる。
    >>> b = np.random.randn(3).astype(np.float32)
    >>> b.dtype
    dtype('float32')
    >>> c = np.random.randn(3).astype('f')
    >>> c.dtype
    dtype('float32')
  • じつは 16 ビットで十分。
    でも CPU を使うなら 32 ビットに変換されて計算されてしまう。
  • ただ、データ保存の場面では容量節約のメリットがある。
    このため本書ではデータ保存の場合でだけは 16 ビットを用いる。

CuPy

  • GPU を扱える Python ライブラリ。
  • NVIDIA 製 GPU が必要。
  • CUDA という GPU 向け汎用並列コンピューティング・プラットフォームの インストールも必要。
  • NumPy とインターフェイスが同じ このため、
    CPU 向けに書いたコードを最小限の手直しで GPU 上で動かすことができる。
  • 4章で登場。
⚠️ **GitHub.com Fallback** ⚠️