blog.tmp.tokyo

No Promises Await at Journey's End

「ゼロから作るDeep Learning」をiPhoneのPythonistaだけで学ぶ(5)

本は一通り読んだので、一応は完結したつもりだったのですが、ちょっとしたきっかけがあって再燃してます。

tomohiko37-i.hatenablog.jp

読書論を読んだ

森博嗣という作家のファンです。理系の推理小説で有名ですが、S&Mシリーズが一番好きです。というかほとんどこれしか読んでませんが。

読書の価値 (NHK出版新書)

読書の価値 (NHK出版新書)

その人の読書に関する本です。どんな内容かは読んで貰えばわかるのであえて書きませんが、読書をする際に何を読んだら良いのか、という問いには「自分で選べ」という回答をする著者が好きですね。

特に心を動かされたのが本を読む際に行う「展開」の話です。文字を表面的に読むだけで終わってしまっているのが多くの人の読書の仕方で、著者は書かれている内容を一つずつ自分なりに頭の中でイメージし、考え、わからなければ納得するまで調べる。小説ならその場の情景を思い浮かべて物語の世界を頭の中に作り上げる行為を「展開」と呼んでます。

私も好きな小説についてはやっていました。最近新作アニメが始まって速攻で見逃した「銀河英雄伝説」などは代表的で、小説のすべてのシーンで頭の中に映像を思い浮かべることができます。

他にも「デルフィニア戦記」や「創竜伝」「薬師寺涼子の怪奇事件簿」「七都市物語」など本を手放した今でも頭の中に物語の映像が残っているものは多いです。

もちろん、森博嗣著のS&Mシリーズでも全部できます。著者はゆっくり時間をかけて読むことで展開していくと書かれていますが、私の場合は何度も読むことでイメージを具体化して定着させている感じですね。

その展開を技術書にも

そして、AIの本を読む際にも展開を意識して読まないと表面的に読むだけで終わってしまうというわけです。再び本を手に取りました。

そして、「ゼロから作るDeep Learning」の本を再び買いました。

本は持っているのですが、案外誤植や内容の誤りなど多く、HP見ながら書き込みをするのも面倒なので新たに買いました。

「第2章 パーセプトロン」から

一通り読んでわかった気にはなっていたのですが、改めて読んでみると理解が浅く、思い浮かんだ疑問に自分で答えられないところも多く、頭を使わずに読んでいたことがわかります。

進みは遅いですが、一つ一つ考えながら読んでいきます。記事では私が疑問に思ったことや解決して行く途中でやったことを記録していきます。内容について興味がある方は本を読んでください。

ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装

ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装

ORゲートのパラメータを求める

パーセプトロンのアルゴリズムを使ってORゲートのパラメータを求めます。本文中には考えてみてください、とあるので頭を使うのが億劫な私は最初に読んだ時にスルーしていたのですが、こういう細かいところをきちんとやっておかないと後で訳が分からなくなるんだろうな、と反省して考えてみることにしました。

y = 0 (w1 * x1 + w2 * x2 <= theta)
y = 1 (w1 * x1 + w2 * x2 > theta)

パーセプトロンのアルゴリズムは上の通り。ORゲートはx1, x2のどちらか一つが1ならyは1を出力します。それを満たすw1, w2, thetaの値を求めてみようという問題です。

適当に数字を羅列して式が成り立つ値を考えるのも手ですが、せっかくプログラムを書くことを仕事にしてるのでプログラムを書いて算出します。

# coding: utf-8
import numpy as np

def is_fire(w1, w2, theta):
  ret = []
  for x in [(0,0),(1,0),(0,1),(1,1)]:
    x = np.array([x[0], x[1]])
    w = np.array([w1, w2])
    if np.sum(x * w) <= theta:
      ret.append(0)
    else:
      ret.append(1)
  return ret
  
def is_or_gate(w1, w2, theta):
  ret = is_fire(w1, w2, theta)
  if len(ret) == 4 and \
     ret[0] == 0 and \
     ret[1] == 1 and \
     ret[2] == 1 and \
     ret[3] == 1:
    return True
  else:
    return False
    
if __name__ == '__main__':
  w1 = 0.0
  while w1 < 1.0:
    w2 = 0.0
    while w2 < 1.0:
      theta = 0.0
      while theta < 1.0:
        if is_or_gate(w1, w2, theta):
          print("w1:",  format(w1,'.1f'), \
                " w2:", format(w2,'.1f'), \
                " θ:", format(theta,'.1f'))
        theta = theta + 0.1
      w2 = w2 + 0.1
      theta = 0.0
    w1 = w1 + 0.1
    w2 = 0.0
    theta = 0.0

ベタなコードですが、w1, w2, thetaをそれぞれ0から1の間で0.1感覚で端から探していきます。時間はかかりますが、とりあえず本を読み進める上で値が求まれば良いので動くことを重視しています。

厳密にテストしていないので間違いがあっても責任は負い兼ねます。ご利用は計画的に。算出した答えは多分あってると思います。

あと書き忘れましたが、iPhoneX上で動くPythonista3でコーディングと実行をしています。記事になるとコードが折り返して見にくいですが、iPhoneなら横に傾けるなど幅広い画面で見ていただくと折り返しなくみれます。

w1: 0.5  w2: 0.6  θ: 0.3

実行すると答えはたくさん出てきますが、とりあえずこんな感じの数値が取れます。

それでは気長にお付き合いください。