N高校生python備忘録

N高校生python備忘録

python始めたけど一向に勉強しないのでいい加減やります

ゼロから作るDeep Learning 1〜2章まで雑感


とりあえず機械学習やりたいなーと思うだけ思って実行に移さず数ヶ月、ニートだから毎日が夏休み、暇だしとこの界隈でめちゃ評判が高くいろんな方もおすすめしている例の本購入

ゼロから作るDeep Learning


いまいち理解できていない、というか正直さっぱりわからないのでメモ替わりに作業をアウトプットしていきます あとPCに不慣れすぎてかなり苦労したから私みたいな人を減らしたい
自分用メモなので内容が雑そして黒歴史確定ですが、高校生が書いているので簡単かつ幼稚ですので安心してください



0.そもそも機械学習ってなんですか



ここは飛ばしていいです
様々なことを学んでいく上でその対象の定義を明確にすることは重要なことだと思うのですが、機械学習というものが一体全体どのようなものなのかということに未だはっきりとした回答を得ていません
前提として私は現役高校生、ただし頭は中学生から進歩なし
多少人工知能等に関する書籍を漁ってはいるものの、なにか実態があるものを見たわけでもないので機械学習に対して正しい知見は持っていないでしょう

ただ本書を軽く触った上で誤解はしていたな、というのはあって機械学習」は「機械が学習するコト(およびモノ)」ではなく、「学習する機械(を作る)」だと
前者と後者では主体が違う 前者は教師と生徒のように教える側と教えられる側が明白だが、後者の場合は人間が最低限御膳たてをして後は機械に参考書を持たせて勉強させる
みたいな風に現時点で私は思っている
つまりこの程度の浅い理解しか得てない人でもこの本を進めることはできます まだ終わってないけど

間違っていたら教えてください

1.Python下準備



この本の学習に必要な道具はパソコン一台
あとはpythonおよびAnaconda、そしてGithubにあるソースコードをダウンロードするだけです リンク間違ってるかも

ちなみに私は入れるアプリを一括で管理したかったのでAnacondaをパッケージマネージャ経由でインストールしました
Macって少し特殊らしく、Windowsだとそう苦労しないと思いますが一度ホームページから直にインストールしたpythonを消去するのがめっちゃ大変だったのです

参考までにこちらのスペック
MacBook pro late2016
OS High Sierra 10.13
N高校通学コースに入学するとMacBook強制的に買わされるんですよね…おのれカドカワ

複数のサイトを参考にさせていただいたのですがとりあえずひとつ貼っておきます qiita.com 注意事項としてはどうやらhomebrewとanacondaは相性が悪いらしいということ

GitHubからダウンロードしたフォルダは、今後python上でディレクトリ変更をする必要が出てくるのでデスクトップ等わかりやすい場所に展開した方がいいと思います

この本ではpythonのコードが載っており、それを写経していくことでDeep learningの仕組みを理解していこうというものです
ですので最低限pythonの使い方、読み方は習得しておいたほうがいいでしょう
pythonの学習を疎かにし現在進行形で苦労してる私が言うのですから間違いありません

ちなみに私はこの本を買って勉強していました 途中で投げ出したけど 正直オススメしません

わかるPython[決定版] (Informatics&IDEA)

わかるPython[決定版] (Informatics&IDEA)

一応擁護しておくと、何か別言語をすでに習得している方はこの本は非常に分かりやすいものかと思います が、私みたく純度100%の初心者は私の二の舞にならないよう、背伸びせず初歩の初歩から始めましょう

2.パーセプトロン


パーセプトロン(英: Perceptron)は、人工ニューロンニューラルネットワークの一種である。心理学者・計算機科学者のフランク・ローゼンブラットが1957年に考案し、1958年に論文[1]を発表した。モデルは同じく1958年に発表されたロジスティック回帰と等価である。ウィキペディア

こちらの章ではパーセプトロンと呼ばれるアルゴリズムが紹介されています
詳しいコトは書籍を読めばわかると思います

f:id:python_nnn:20180903230650j:plain:w200

二つの入力層とそれぞれと一本線で繋がる出力層
入力層に信号が送られるとそれが入力ワイヤを通して出力層へと流れる
この際入力ワイヤには固有の値(これを重みと呼ぶ weightのW?)が振られており、入力信号と値が乗算されたものが出力層へと送られる つまりその値が信号の強さ(重要度と言い換えてもいいかもしれない)を決めており、高ければ高いほど入力層からの信号が大きく伝わる
そして出力層では送られてきた信号の総和が算出され、その総和がある限界値を超えた場合にのみ1を出力する
この限界値を閾値(いきち)と呼ぶらしい

私の説明が下手なので分かりづらいですね 説明だけ聞いてもわからないのでここでANDゲートと呼ばれるものを実装する

ANDゲートは「〜かつ〜」の場合、つまりx1からの信号も1、x2からの信号も1の場合、y=1になるよという論理ゲート
pythonコード

def AND(x1, x2):
    w1, w2, theta = 0.5, 0.5, 0.7
    tmp = x1*w1 + x2*w2
    if tmp <= theta:
        return 0
    if tmp > theta:
        return 2

x1×w1(0.5) + x2×w2(0.5) の解が0.7以下の場合は0、それより大きい場合は1を返す
確かに計算してみると x1=1,x2=1 の時のみ y=1 になる へー

さて続きの論理ゲートを実装する前に、バイアスと呼ばれるものを導入するようです
先ほど実装したANDゲートにおいて閾値は0.7だったがそれだとどうにも分かりづらい
そこで0以上か、0未満かで区別できるようにバイアス(b)を設定する

先ほどの場合だと右辺に当たるthetaの値を0にしたい  ということは移行の要領で

def AND(x1, x2):
    x = np.array([x1, x2])
    w = np.array([0.5, 0.5])
    b = -0.7
    tmp = np.sum(w*x) + b
    if tmp <= 0:
        return 0
    else:
        return 1

ここでnumpyが出てきます 参考 機械学習でも定番のPythonライブラリ「NumPy」の初心者向け使い方チュートリアル - paiza開発日誌
arrayは行列作成、sumは合計を演算

続いてNANDゲートとORゲートを実装

#NANDゲート
def NAND(x1, x2):
    x = np.array([x1, x2])
    w = np.array([-0.5, -0.5])
    b = 0.7
    tmp = np.sum(w*x) + b
    if tmp <= 0:
        return 0
    else:
        return 1
#ORゲート
def OR(x1, x2):
    x = np.array([x1, x2])
    w = np.array([0.5, 0.5])
    b = -0.2
    tmp = np.sum(w*x) + b
    if tmp <= 0:
        return 0
    else:
        return 1

NANDはNOT AND回路、つまりAND以外で1を返す
ORは「〜または〜」なのでどちらか片方のxが1ならyも1を返す
ANDもNANDもORも結局のところwの重みの値、bのバイアスの値がそれぞれ違うだけで仕組みそのものは一緒なのです 感動ですね! 中学校であのつまらない技術の授業を受けててよかった!

さてここまで三つの回路を作ってきましたが、ではこれら以外も単純パーセプトロンで表現可能なのかというと、残念ながらそうではないようです

XORゲート

XORゲートは排他的論理和とも呼ばれる論理回路です
さて先ほどのORゲートと何が違うのか

例えば、○○さんはアメリまたはイギリスにいます、と言われた場合、彼/彼女はアメリカにいてなおかつイギリスにいる、と言う状況は考えられない
しかし先ほどのORゲートを見ると、x1を米、x2を英とした場合、x1、x2両方が1の場合でもy=1が成立してしまう ということでまたはには二種類あるということ で、いいんですよね先生

XORゲートではx1かx2どちらか片方が1の時(つまり片方は0の時)1を返すゲートです 0,0 もしくは 1,1 の時には0を返します

しかし……これまで見てきた既存のパーセプトロンではこれを表現できません

f:id:python_nnn:20180904003313j:plain:w300

ざっくりと、今までののAND、NAND、ORを回帰直線(図)で表現すると、一本の直線を引きそれで領域を分けていることになる
けどXORゲートは直線では表せない ではどうするか

どうやらパーセプトロン同士を組み合わせることによって解決できるらしい

先ほどの入力層(x)と出力層(y)の間に隠れ層(s)を挟む
x1からs1とs2へ、x2からもs1とs2へワイヤーを結び、s1とs2からゲートを通してyを出力する

def XOR(x1, x2):
    s1 = NAND(x1, x2)
    s2 = OR(x1, x2)
    y = AND(s1, s2)
    return y

s1にNAND、s2にOR、yにANDゲートと、いままで定義してきた関数を流用することで非線形の表現ができるようになった すごい 感動である

次回 python-nnn.hatenadiary.jp