デジタル・デザイン・ラボラトリーな日々

アラフィフプログラマーが数学と物理と英語を基礎からやり直す。https://qiita.com/yaju

ステップ関数を理解してみる

はじめに

活性化関数としてステップ関数がある、ニューラルネットワークの起源となるアルゴリズムのパーセプトロンでAND回路やOR回路の構成に使用されたものです。

yaju3d.hatenablog.jp

過去にシグモイド関数をやってきてるのに、なんで初期の活性化関数であるステップ関数に戻るのかというと、それは微分不可能だから。
活性化関数 Relu も微分不可能なのにディープラーニングの隠れ層では推奨されています。

私の方で活性化関数で「微分不可能」というところに理解が引っかかっているので、原点に戻って整理しようと考えたのです。

あとで追記します。

参考

ステップ関数

形式ニューロン

f:id:Yaju3D:20170528144340p:plain f:id:Yaju3D:20170528154127p:plain
左図が本物の神経細胞(ニューロン) で、右図が形式ニューロンです。
形式ニューロンをWikipediaから引用します。

形式ニューロン(けいしきニューロン、英: formal neuron)や Threshold Logic Unit とは、1943年に神経生理学者・外科医であるウォーレン・マカロックと論理学者・数学者であるウォルター・ピッツが発表した最初の人工ニューロン(英: artificial neuron)[1]。伝達関数としてはヘヴィサイドの階段関数を使い、入出力の値は 0 または 1 の二値だけをとる。

簡単に説明すると、入力が2つあり各入力に対して重みが掛け算され、その値が閾値を超えれば出力は「1」、そうでなければ出力は「0」となります。 たとえば、入力が(1,0)、重みが(0.5, 0.7)だとすると、1×0.5 + 0×0.7 = 0.5 を計算して閾値と比較します。

形式ニューロンの場合、入力が「0」か「1」、重みが「実数」、出力が「0」か「1」となります。

単位ステップ関数

後述するヘヴィサイド関数との違いは、x = 0 の時も1の値を持つものとして定義していること。

f(x) = \begin{cases} 1 & (x \geq 0) \\ 0 & (x < 0) \end{cases}

機械学習のサンプルプログラムで使用されるステップ関数は、x = 0 の時は0の値になっているので用途によって定義が違うんでしょうね。

def step(x): 
    return 1 if x > 0 else 0
f(x) = \begin{cases} 1 & (x > 0) \\ 0 & (x \leq 0) \end{cases}

f:id:Yaju3D:20170603024904p:plain

ヘヴィサイド関数

ヘヴィサイドの階段関数 は、正負の引数に対しそれぞれ 1, 0 を返す階段関数となります。

f(x) = \begin{cases} 1 & (x > 0) \\ 0 & (x < 0) \end{cases}

又は、原点を埋めて

f(x) = \begin{cases} 1 & (x > 0) \\ \frac{1}{2} & (x = 0)  \\ 0 & (x < 0) \end{cases}

パーセプトロン

単純パーセプトロン

単純パーセプトロンの活性化関数としてステップ関数を使用しています。
qiita.com

rightcode.co.jp

多層パーセプトロン

多層パーセプトロンの活性化関数としてステップ関数を使用しています。
rightcode.co.jp

ステップ関数の限界

多層パーセプトロンの精度をよくするための誤差逆伝播(バックプロパゲーション)が生み出されたのですが、ステップ関数は微分が出来ないため、ラメルハートらは誤差を伝播できるような微分可能な活性化関数として、シグモイド関数を用いるようになりました。
rightcode.co.jp

最後に

今の自分は本やWebサイトを見て知識を得ているだけで、本当の意味で理解出来ていないことがあらためて分かったので、ちゃんと理解するようにプログラムを組んでみることにします。

静岡の勉強会の構想を考える

はじめに

2016/4/23に静岡Developers勉強会で「人工知能ハンズオン」を開催しました。 yaju3d.hatenablog.jp

当時はTensorFlowが出始めて人工知能がバズワードでした。TensorFlowに関する本も少ない上に自分自分が機械学習に関する知識が全然なかったです。
ともかくネットで検索しまくって、分かりやすいと評判があった上野山徹さんが作成した八百屋の問題のスライドや定番のMNISTの文字認識をやりました。

いつかリベンジしないと思いつつ時が経ってしまいましたが、3年半の間に何もしていなかったわけではありません。ペースは遅いながらも着実に基礎的な部分の勉強はしてきました。

11月か12月を目処に「人工知能ハンズオン リベンジ」として勉強会を開催しようと思っています。

構想

9月中にTensorFlow 2.0がロードマップを見るとリリース予定になっています。だた、今回はTensorFlowを使うかは考え中です。

例えば画面に円を描きたいといった場合、APIを使えば難なく円を描けるでしょう。しかし、APIを使わないで円を描こうとしたらどうでしょう?
三角関数の知識が必要となりますね。一方でAPIを使えば円も描けて目的の表現が出来るなら別に数学の知識はいらないとも言えます。
以前、人工知能できゅうりの仕分けをしたとして話題がありましたが、TensorFlowの文字認識MNISTのサンプルを改良したら出来てしまったわけで、数学の知識を必要となったわけではありませんが、きゅうりの仕分けをする目的は達成できたのです。誰もが簡単に人工知能を使用して目的を果たせた良い事例となったのです。 数学の知識があっても人工知能ではどうしようもない場合があります。将棋の最強AIであるPonanzaを開発した山本一成さんは東京大学出身です。山本一成さんのドキュメンタリーを観たことがありますが、行き着くところまでいったPonanzaではパラメーターをいじることでしかより強くすることが出来ません。そして、そのパラメーターをどういじっていいのかは、もはや開発者本人にも分からない状態なのです。

パラメーターをいじって試すのにコストがあまりかからない場合はいいでしょうが、物によっては1回試して動かすのに数百万かかるとしたらどうでしょう? 人工知能がこういってますからと言ってもクライアントに納得行く説明ができないと駄目だったりします。例えば半導体とか試すだけでも何千万かかかります。

ちょっと話が行き過ぎました。そこまでいかなくても、最低限の数学の知識があった上で人工知能を使えるようになりたいわけです。

目標

「ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装」という名著があります。

この本に挫折した人が、勉強会を受けた後で読み直したら少しは理解が出来るようになったと言えるようにしたいのが今回の勉強会の目標としたいわけです。

予定

これから考えていきます。
1次方程式から傾きや切片、微分や確率など数学の基礎的なところからとなりますね。だから昨今の人工知能の派手さなんてものはありません。

Google Colaboratory と Google スプレッドシートを使用する予定なので、GoogleアカウントがあればPCにインストールは不要です。
タブレット端末とキーボードがあればいいような感じにしたいです。

ちなみに料金は無料です。会費は1万円くらい余っているので会場費がまかなえる。

最後に

この記事は少しずつ書き換えていきます。

瞬間英作文で調べたこと

はじめに

英語の勉強として瞬間英作文のiPhoneアプリ版を使用して、何回も繰り返しています。
その中で疑問に思ったことはネットで調べたりしています。その履歴を辿って一覧にしてみました。

単語・熟語

英単語

英単語 意味
always いつも
Although けれど
among ~の中で
asleep 眠っている
beautifully 見事
boiled egg ゆで玉子
boring 退屈
brush 磨く
cradle ゆりかご
dragonfly とんぼ
drow 絵(線画っぽい)
dish 料理
excite 興奮
fluently 流暢
good-looking ハンサム
independent 独立
let ~させる
necessary 必要(形容詞)
need 必要(他動詞)
make ~したい
noticed 気付いた
paint 絵(水彩画っぽい)
pleased 喜ぶ
rains 雨が降る
respect 尊敬
shake 揺れる
sing 歌う動作
song
sorry 残念
spicy 辛い
strong 濃い
such そんな
tried ~しようとした
until ~ まで
useful 役に立つ
veterinarian 獣医
weak 薄い

英熟語

英熟語 意味
a lot たくさん
a lot of fun とても楽しいこと
a lot of things 多くのこと
all fell asleep 皆眠った
As 文頭 ~なので 理由
around the world 世界中
ask you to ~するように頼む
at once すぐに
at the night 夜に
at your home あなたの家では
best way of 一番いい手法
broke down 故障した
come home 帰宅
decided not to 〜しないことにした
every evening 毎晩
for many hour every day 毎日何時間も
give up 諦めた
give me ~して ください
go abroad 海外へ
good at 得意です
in the dress ドレスを着ている
in the morning 朝に
is covered with snow 雪で覆われた
I’d like to ~したいのですが
late for ~に遅れる
lift it 持ち上げる
look interesting 面白そう
look like ~のように見える
looking for you 探している
make some coffee コーヒーを入れる
more often もっと頻繁
much higher ずっと 高い
near here この近く
of them all 彼らみんなの中で
some day いつか
stay up late 遅くまで起きて
such a thing そんなこと
spoken to us 僕たちに話しかけた
take off 離陸
the day after tomorrow 明後日
to be happy 幸せになる
very strong 丈夫
want to ~したがっている
want to be なりたがる
without working 働かない
will soon be able to じきに?出来るようになる
Will you please ~してくれますか
Will you please tell me 教えてもらえる?

検索したこと

最後に

英語って難しい、何も繰り返してもまだピンとこない。でも、しっくりくるまで繰り返していこう。

なぜ数式には2乗が多いのかを理解してみる

はじめに

機械学習を学ぶようになり数学や統計の本やサイトに出てくる数式をみると2乗をよく見かけます。同じ数を2回掛けるってだけなのになんでなんだろう。

ネットで調べると下記のピッタシの本がありました。

ドラゴン堀江で堀江貴文さんに講師として共演していた教育系YouTuberのヨビノリたくみさんとの動画の中で、堀江貴文さんがなぜ2乗をするのかという質問に対し、たくみさんが積分の次数の話をしてちょっとだけ説明しています。
www.youtube.com

内容

今回は、Qiita側に記事を書きました。 qiita.com

勾配降下法の可視化を解析してみる

はじめに

今回は下記サイトの記事を見ていきます。
qiita.com

最急降下法(Gradient Descent)のみとなります。

データ

dataは下記サイトから100件
https://raw.githubusercontent.com/pandas-dev/pandas/master/pandas/tests/data/iris.csv

# 2 クラスにするため、setosa, versicolor のデータのみ抽出
data = iris[:100]

# 説明変数は 2つ = 2 次元
columns = ['PetalWidth', 'PetalLength']

x = data[columns]     # データ (説明変数)
y = data['Name']      # ラベル (目的変数)
PetalLength,PetalWidth,Name
1.4,0.2,Iris-setosa
1.4,0.2,Iris-setosa
1.3,0.2,Iris-setosa
 ︙
4.7,1.4,Iris-versicolor
4.5,1.5,Iris-versicolor
4.9,1.5,Iris-versicolor

ロジスティクス回帰なので、0 と 1 の2値にします。

y = (y == 'Iris-setosa').astype(int)
PetalLength,PetalWidth,y
1.4,0.2,1
1.4,0.2,1
1.3,0.2,1
 ︙
4.7,1.4,0
4.5,1.5,0
4.9,1.5,0

ロジスティック回帰

def p_y_given_x(x, w, b):
    # x, w, b から y の予測値 (yhat) を計算
    def sigmoid(a):
        return 1.0 / (1.0 + np.exp(-a))
    return sigmoid(np.dot(x, w) + b)

ロジスティック回帰は、以下の数式で表現できます。
y=\displaystyle \frac {1} {1+exp(-(b_{1}X_{1}+b_{2}X_{2}+b_{3}X_{3}+ \cdots  + b_{i}X{i}+b_{0}))}

シグモイド関数 f(x)=\displaystyle \left(\frac {1}{1+exp(-x)}\right) と同じ形であり、exp内に重回帰を入れた形式となります。

今回のプログラムは、\hat{y}=\sigma (xw+b) で計算となり、上記式を変数に合わせて変更したのが下記の数式となります。
\hat{y}=\displaystyle \frac {1} {1+exp(-(x_{0}w_{0}+x_{1}w_{1}+b))}

  • \hat{y} : 真のラベル y の予測値ベクトル。次元は (入力データ数, 1)
  • \sigma : シグモイド関数。計算結果を (0, 1) 区間写像する
  • x : 入力データ。次元は (入力データ数, 説明変数の数)
  • w : 係数ベクトル。次元は(クラス数 = 2)
  • b : バイアス (スカラー)

内積

np.dot(x, w) は、内積です。

AB として次の例を考えます。
A=(1,2)B=(3,4)
この場合、次の式の計算を行います。
A1B1+A2B2 = 1 \times 3 + 2 \times 4 = 3 + 8 = 11

勾配計算

勾配(gradient) を計算します。

def grad(x, y, w, b):
    # 現予測値から勾配を計算
    error = y - p_y_given_x(x, w, b)
    w_grad = -np.mean(x.T * error, axis=1)
    b_grad = -np.mean(error)
    return w_grad, b_grad

np.mean は平均を求めます。axis=1とすると、行ごとに平均値を計算します。
x.Tは転置行列にします。これにより100行2列から2行100列になります。

  • error : 誤差 … y の値は 0 から 1 であり、 p_y_given_x関数の戻り値は0.0~1.0の値を返します。
  • w\_grad :重みの勾配。100個分に対し重みを計算します。
  • b\_grad : バイアスの勾配。切片なので変数は1つです。

データ件数が多くなると件数に比例して値が大きくなってしまうので平均を取ることでデータ件数の影響をなくします。

最急降下法(Gradient Descent)

def gd(x, y, w, b, eta=0.1, num=100):
    for i in range(1, num):
        # 入力をまとめて処理
        w_grad, b_grad = grad(x, y, w, b)
        w -= eta * w_grad
        b -= eta * b_grad
        e = np.mean(np.abs(y - p_y_given_x(x, w, b)))
        yield i, w, b, e
  • eta : 学習係数\eta = 0.1 です。
  • w : 勾配w_gradを用いて現在の重み w を更新します。
  • b : 勾配b_gradを用いて現在の重み b を更新します。
  • e : 誤差の平均です。一般的な2乗誤差ではないです。

yieldを使用してジェネレータを実行し、勾配法 1ステップごとの結果を得てアニメーションとして生成しています。

英語の勉強を継続して半年経過

はじめに

yaju3d.hatenablog.jp

ということで、毎年数ヶ月もすれば何もしないで終わっていた英語の勉強ですが、今年は続けることが出来ています。
やはり習慣化することが大事ですね、平日の会社終わりにコワーキングの「エニシア静岡 丸井店」に行って、そこで英語の勉強をしています。

ただ時間が30分~40分くらいです。確かに短いかなと思いつつも、無理なく継続することの方が大切かなと思っています。
せっかく習慣化できるようになってきたので、6月から英語以外の勉強を30分追加していきます。

何をしているか

瞬間英作文のiPhoneアプリ版を使用しており、中学3年生が終わって繰り返す段階です。
回答をノートに書いて一致しているか確認し、何か違っているのか、何でこうなるのか考えたり調べながらやっています。
まだ過去形とか複数形など見落としがありつつも正解に近づいている実感があります。

ひたすらこれをやり続けて、さっと出るようにしたいです。「例文のおかわり」の購入も考えたんですが、まだ後回しとします。
5/27からiPhoneに瞬間英作文CD2枚を入れて、通勤の車の中で聴いています。もっと早くやれば良かったかな。

英文法の整序問題で正しい順序にして英文法を作成する「英語組み立てTOWN」もやるのですが、瞬間英作文で気分が乗らない時くらいでやる頻度は落ちています。こんな簡単な英単語だらけなのに考え込みます。

次の展開

瞬間英作文と英語組み立てTOWNは引き続きやります。
今後は自宅で発音の練習をしていきます。幾つかの英語学習の本を読むと、発音が分かると聴き取りができるようになるって書いてあるので信じてやっていきます。

TOEICのテストは1回くらいは受験しておきたいので、今の予定は12月くらいですかね。
英語に慣れてきてTOEIC用の英単語を覚えるとか徐々に準備していこうかな。

海外ドラマの「フレンズ」がいいという情報がありますが、TOEIC700点レベルってことなので今の段階でやっても仕方ないかと思っていて、代わりに中身もだいたい分かるAudio版「Doraemon」を購入してみました。

books.apple.com

これは音声だけなのでAudio版「Doraemon」の本は楽天で別個に購入してあります。

8年ぐらい前に「Doraemon」のコミック版は5巻まで購入してあったんですが、これは音声がないんですよね。
Audio版「Doraemon」と内容が同じかとおもいきや違ったんです。

「Doraemon」は勉強って感じではなく、気分転換で読むイメージですね。

最後に

英語学習の記事を今後は増やしていきます。
瞬間英作文をやってて何でこうなるのか調べたりしたことをブログで書いていく予定です。

機械学習に使われる微分の数式を理解してみる(勾配降下法:確率的勾配法)

はじめに

前回の記事の続きとなります。
yaju3d.hatenablog.jp

最急降下法確率的勾配降下法の違いについては、以前に記事を書きました。
yaju3d.hatenablog.jp

参考

やる夫で学ぶ機械学習 - 多項式回帰と重回帰 - · けんごのお屋敷

パラメーター更新の式

最急降下法

前回、重回帰で求めたパラメーター更新の式です。
\displaystyle \theta_j := \theta_j - \eta \sum_{i=1}^n \Biggl(f_{\theta}(x^{(i)})-y^{(i)}\Biggr)x_j^{(i)}

最急降下法は学習データのすべての誤差の合計を取ってからパラメーターを更新します。学習データが多いと計算コストがとても大きくなってしまいます。また、学習データが増えるたびに全ての学習データで再学習が必要となってしまいます。

確率的勾配法

\theta_j := \theta_j - \eta \Biggl(f_{\theta} ({x}^{(k)}) - y^{(k)}\Biggr){x_j}^{(k)}
(式中のkは、パラメーター更新毎にランダムに選ばれたインデックス)

大きな違いとして、確率的勾配降下法ではシグマ\sum (1~nまで合計)が取れています。
その分、計算コストは少なくなる。

確率的勾配降下法は学習データをシャッフルした上で学習データの中からランダムに1つを取り出して誤差を計算し、パラメーターを更新をします。勾配降下法ほどの精度は無いが増えた分だけの学習データのみで再学習する(重みベクトルの初期値は前回の学習結果を流用)ため再学習の計算量が圧倒的に低くなります。

ミニバッチ確率的勾配降下法

\displaystyle \theta_j := \theta_j - \eta \sum_{k\in K} \Biggl(f_{\theta} ({x}^{(k)}) - y^{(k)}\Biggr){x_j}^{(k)}

ここでシグマが付くのですが、これはインデックスの集合となります。
たとえば学習データが100個あると考えた時に、m=10 だったら、K={61,53,59,16,30,21,85,31,51,10} みたいにランダムに10個のインデックスの集合を作って、パラメーターの更新を繰り返すことになります。

ミニバッチ確率的勾配降下法最急降下法確率的勾配降下法の間を取ったような形となります。 最急降下法では時間がかかりすぎ、確率的勾配降下法では一つ一つのデータにかなり揺さぶられることになるので、学習データの中からランダムにいくつかのデータを取り出して誤差を計算、パラメーターを更新をします。このときの一回に取り出すデータの数をバッチサイズと呼びます。

視覚化

※注意 これまでやってきたのは最小2乗法を用いたものでした。この視覚化についてはロジスティクス回帰となっています。
最急降下法と確率的勾配法とミニバッチ確率的勾配降下法の違いを知るだけならいいのですが、プログラムの中身はパラメーター更新と一致しないです。

下記サイトでは、最急降下法と確率的勾配法とミニバッチ確率的勾配降下法の違いを視覚化されています。
sinhrks.hatenablog.com

これを、組み直ししてみました。 qiita.com

最後に

視覚化を組み直してみたのですが内容を見ないで単純に移植してみたようなものなので、今後は視覚化したのを説明していきたいですね。
その前に、内積ロジスティクス回帰などをやっていきます。
まだ数式とプログラムを組むイメージが頭の中で一致してないので理解度が足りてないですな。

スポンサーリンク