pikesaku’s blog

個人的な勉強メモです。記載内容について一切の責任は持ちません。

相乗平均と相加平均の違い

参考

【対数】インデックス | 大人が学び直す数学

相加平均とは?

和の平均。算術平均と呼ばれる。

例) 試験の平均点等

相乗平均とは?

積の平均。幾何平均とも言われる。

積の平均。対象データを乗じた値の累乗根が相乗平均になる

例) 複利計算

http://www.globis.jp/1515

n√x1 * x2 * xn 

※上記のx1~2は数列

ポイント

必ず以下になる
算術平均 > 相乗平均

指数関数と対数関数について

ポイント

対数関数の式は以下の通り

y = log2(x)

グラフの特徴(グラフの形は参考URLを参照)
・xは0より大きな値になる。
 →2乗のため真数はマイナスにならない。
 →log2(0)は成立しない。
・右肩上がり

指数関数の式は以下の通り

y = 2^x

グラフの特徴(グラフの形は参考URLを参照)
・yは0より大きな値になる。
 →x乗のためyはマイナスにならない。
・右肩上がり

対数関数と指数関数は「逆関数

以下は同じことを意味する。

y = log2(x)
x = 2^y

逆関数のグラフは、y=xのグラフを基準とすると対象的な値を取る。

詳細は参考URLを見ること。

逆関数の表記

y = f(x)の場合

y = f(^-1)(x)

※-1は指数ではない

指数関数の微分の公式

証明方法は参考URL参照

(a^x)' = a^x * loge(a)

対数関数の微分の公式

証明方法は参考URL参照

                  1
(loga(x))' = -----------
             x * loge(a)

感想

指数関数の微分は不思議だらけ。
ただ証明できる事から、そういう性質を持っていると考えよう。
以下を覚えておく。
・指数や対数関数の微分に処理の過程にeが潜んでいる
・定数aがeであった場合に、微分結果がシンプルに変化する点
・公式があるってこと

対数の勉強

シグモイド関数を理解しようと思ったら、対数も勉強する必要があった。もうやけくそです。高校時代にしっかり数学勉強しておけばよかった。。。。

参考

【対数】インデックス | 大人が学び直す数学

唯一の救いは、上記のような素晴らしいページがあったこと。大変参考にさせて頂きました。有難うございます。

本ページは、自分の理解向上のため、上記URL記載内容を自分の言葉で書いたものです。対数を学びたい人は、上記URLを見た方がいいです。

指数と対数とは?

・指数は、2^3 = 8の3の部分
 対数表記だと3 = log2(8)

・指数と同じものを意味するもの。

 ※指数の別表記

・キーワード
 【指数表記の場合】
 x = a^p
 pは指数(冪指数)

 【対数表記の場合】
 p = loga(x)
 loga(x)は対数(指数pと同じもの。表記によって呼び方が変わる)
 aは底(base)
 xは進数
 式の意味は、aを何乗したらxになるか?答えはp

 ★指数の加減算は、真数に対する乗除算になる。これが重要なポイント★

常用対数とは?

・底が10の対数
・省略表記が可能
 例) log10(100) = log100 = 2

累乗根とは?

・rootと呼ばれる
 指数と逆の計算をするもの

・キーワード
 累乗(冪乗) = 指数
 累乗根(冪乗根) = 底

・数式は以下の通り

 2乗したら4になる数値は何か?
 √4 = 2
 以下表記も可能
 2√4 = 2
 ※√の前の2は小字

 3乗したら8になる数値は何か?
 3√8 = 2
 ※√の前の3は小字
 
平方根/立方根も累乗根の一部
 2乗根は平方根、3乗根は立方根と呼ばれる。

指数の拡張とは?

log2(4)=2

上記は簡単。指数が整数で表わせる為。
だけど以下はどうか?

log2(5)

指数の拡張の考えで上記は算出できる。
指数の拡張とは、指数を整数以外で表すこと
※これが大発見であった!

指数の拡張は以下の通り

①ゼロの指数

a^0 = 1

指数が一つあがると、底の掛け算が発生する。
指数が一つ下がると、底の割り算が発生する。
この関係性でいくと、2^0は1になる。
純粋に直感で0乗=1もしっくりくる。

②マイナスの指数

           1
a^(-p) = -----
          a^p

③分数/少数の指数

以下の定義があり。

a^(1/n) = n√a

※上記の√の前のnは小字

この定義を理解する為の図。(参考URLから引用)

例) 2^(1/2) = 2√2

※上記の√の前の2は小字

http://oto-suu.up.n.seesaa.net/oto-suu/image/0044_f001.gif?d=a0

指数を減算する時は、除算が行われる。

※底が2の場合
 指数が1減ったら2で除算される。
 指数が1増えたら2で乗算される。
 指数が1/2増えるとは、√2で乗算すること。
 指数に対して1/2の加算を2回すると、1加算した場合と同じ効果を与える。
 指数を1/2加算した場合は、√2が乗算される。もう一回指数を1/2すると、更に√2が乗算される。
 →√2 * √2 = 2
 →1加算した場合と同じ効果になる

a^(1/n) = n√a
上記は、aのn乗根ともいえる。

a^(0.5) = a^(1/2) = n√a
指数が少数である場合も、分数と同じ考えでOK

指数法則

①a^m * a^n = a^(m+n)

②a^m / a^n = a^(m-n)

③(a^m)^n = a^(m*n)

④(a*b)^m = a^m * b^m

指数法則 使用例

ゼロの指数

a^3 / a^3 = a^(3-3) = a^0 = 1

マイナスの指数

                                    1
a^2 * a^(-4) = a^(2-4) = a^(-2) = -----
                                   a^2

分数の指数

(a^(1/3))^3 = a^(1/3 * 3) = a^1 = a

(a^(1/3))^3 = (3√a)^3 = a

おまけ

(a^2)^(1/3) = a^(2*1/3) = a^(2/3) = 3√a^2

指数の分子が1以外の時は上記の計算が可能。
→aの2/3乗 = aの2乗の3乗根

対数公式

これ重要!

①loga(B*C) = loga(B) + loga(C)

証明

a^m = B
a^n = C
とすると

B*C = a^m * a^n = a^(m+n)

上記はB*Cはaをm+n乗したものを意味する

上記を対数表記すると
loga(B*C) = m + n

更にmとnを展開する
mは前提であるa^m = Bより、m = loga(B)
nも前提であるa^n = Cより、m = loga(C)
よって、

loga(B*C) = loga(B) + loga(C)
②loga(B/C) = loga(B) - loga(C)

証明

B = a^m
C = a^n
とすると、

loga(B/C) = loga(a^m/a^n) = loga(a^(m-n)) = m-n
mとnを展開すると、
= loga(B) - loga(C) 
③loga(B^c) = c * loga(B)

★真数の指数は対数の外に出せる★

証明

B = a^m
とすると。

loga(B^c) = loga((a^m)^c) = loga(a^(m*c)) = m*c
mを展開すると、
= loga(B) * c
④logb(c) = loga(c)/loga(b)

★底の返還公式★
任意の対数を常用対数に変換できる!

証明

           loga(c)
logb(c) = ---------
           loga(b)

左辺をxとする。

     loga(c)
x = ---------
     loga(b)

両辺にloga(b)を掛ける
              
x * loga(b) = loga(c)

外のxを対数公式を適用して指数に戻す

loga(b^x) = loga(c)
底はどちらもa。そのため、上記式が成立するということは真数部分が同じ。

b^x = c

上記を以下に展開

x = logb(c)

上記xを最初に定義した以下式に代入すると

     loga(c)
x = ---------
     loga(b)

以下のように公式が証明される

           loga(c)
logb(c) = ---------
           loga(b)

aを10にすれば、任意の対数(logb(c))を常用対数に変換することができる!
⑤loga(b) * logb(a) = 1

★底と真数をひっくり返した対数同士を掛け合わせると1になる★

以下の公式も成り立つ

              1
loga(b) = ---------
           logb(a) 

証明

底の返還を使う!
                    logc(b)   logc(a)
loga(b) * logb(a) = ------- * ------- = 1
                    logc(a)   logc(b)  

鮮やかすぎる!

対数をとる」とは?

対数を含まない式を対数化すること!

a = b

であれば、

logc(a) = logc(b)

も成立する。

対数計算の中で、常用されるテクニック

対数表とは?

※以下図は参考URLより引用

http://oto-suu.up.n.seesaa.net/oto-suu/image/0053_f001.gif?d=a1

対数表は、常用対数の対応表のこと

※常用対数は、底が10の対数

対数表は広く対応値を記載する必要はなしOK。
対数公式で展開して、整数に変換しきれない部分のみ対応表に記載されていれば結果を算出可能である為。

例) log200の場合

対数公式で展開
log200 = log10(200) = log10(2) + log10(100) = log10(2) + 2

→log10(2)が対応表に記載されていれば結果算出が可能。上記の対応表ではlog10(2)は真数部分が2の為、0.301。

例) log0.07の場合

対数公式で展開
log0.07 = log10(0.07) = log10(7/100) = log10(7) - log10(100) = log10(7) - 2

対数と桁数

対数計算で数式の桁数の算出が可能

例) 2^105の桁数は?

桁数に親和性のある常用対数を使って表現する。

桁数 = log10(2^105)

対数公式で展開
log10(2^105) = 105 * log10(2) = 105 * 0.301 = 31.61

log10(100)は2。真数100は3桁。

上記より対数の整数部分+1で32桁が答え。

対数のいい点!

・小さな数で大きな数を扱える
 巨大・極小な数値を、指数/対数表記によりシンプルに扱える。
 数値の規模感も直感的に可能

・加算算で乗除算ができる

おまけ

この法則がない時代の天文学者は、多大な数値の乗除算をまじめにやっていた為、計算だけで研究人生が終わっていたらしい。この発見のおかげで、「天文学者の寿命を2倍にした」と言われるほど、画期的な発見であったよう

合成関数の微分とは?

やってられねえっす。。。
ニューラルネットの勉強」→「シグモイド関数の勉強」→「微分の勉強」→「合成関数の微分の勉強」

もう何を勉強しようとしているのか分からなくなってきた。。。。

ただ、ひとまずシグモイド関数を理解するには、これが最後っぽい。

合成関数とは?

合成関数は、関数の中に関数が入れ子ではいっている関数

例)

y = f(u)
u = g(x)

上記の場合

y = f(g(x))

上記が合成関数

合成関数の微分の公式

合成関数の微分を求める公式があるよう。
以下の通り。

dy   dy   du
-- = -- * --
dx   du   dx

パーツ毎に説明すると、、、

dy
--
dx

はy = f(x)の導関数の表記
xでyを微分するってこと。

dy
-- 
du

はy = f(u)の導関数の表記
uでyを微分するってこと

du
-- 
dx

はu = g(x)の導関数の表記
xでuを微分するってこと

上記より合成関数の導関数は、、、

「それぞれの関数レベルで微分して得られた導関数を掛け合わせたもの」ってこと?

合成関数の微分の公式の証明

前提となる合成関数と各関数は以下の表記とする。

y = f(u)
u = g(x)
y = f(g(x))

まずは以下の形から

lim  f(g(x + h)) - f(g(x))
h→0 --------------------- 
               h

これを変形する為に、以下を掛ける。

g(x + h) - g(x)
---------------
g(x + h) - g(x)

↓

lim  f(g(x + h)) - f(g(x))   g(x + h) - g(x)
h→0 --------------------- * ---------------
               h             g(x + h) - g(x)

↓

lim  f(g(x + h)) - f(g(x))   g(x + h) - g(x)
h→0 --------------------- * ---------------
        g(x + h) - g(x)            h

これが???と思ったが、計算上は成立する。

例)
 2     2     3     2     3
--- = --- * --- = --- * --- →計算結果は変わらない。
 4     4     3     3     4

ここで以下の表記を決めて、、、、
j = g(x + h) - g(x)

前提条件でもある以下表記を使うと、、、
u = g(x)

こうなって
j = g(x + h) - u

こうなる
j + u = g(x + h)

これを利用して展開すると、、、、

↓

lim  f(j + u) - f(u)   g(x + h) - g(x)
h→0 --------------- * ---------------
        j + u - u            h

となり、

↓

lim  f(j + u) - f(u)   g(x + h) - g(x)
h→0 --------------- * ---------------
            j                h

となる
この時、h→0を考慮すると
j = g(x + h) - g(x)
の為、h→0の時は、j→0になる。

これを踏まえてると、以下表記が可能。

↓

lim lim  f(j + u) - f(u)     g(x + h) - g(x)
h→0 j→0 -----------------  * ---------------
                j                    h

↓

lim  f(j + u) - f(u)      lim  g(x + h) - g(x)
j→0 -----------------  *  h→0 ---------------
           j                        h

こうなると、

↓

f'(u)*g'(h)

になる。
これをdを使って表記すると、

dy du
--*--
du dx

なんかだまされた気分。。。。。。

合成関数の微分の例

例1) y = (x + 1)^2

合成関数の微分の公式を用いず、普通の公式を使った場合

y = x^2 + 2x + 1
y' = 2x + 2

合成関数の微分を使った場合

以下の手順でやる

①以下の2つの関数に分ける
u = x + 1
y = u^2

②それぞれを微分する
u'(x) = 1
y'(u) = 2u

③掛け合わせる

1 * 2u = 2u

④uをxで展開する。

2u = 2(x + 1) = 2x + 2

同じだ!

おまけ

こんな表記でやる場合もあるみたい。

合成関数を微分する手順

例) y = (logx)^3

y' = {(logx)^3}' * (logx)' 
y' = 3{logx}^2 * (logx)'
y' = 3{logx}^2 * (logx)'

※(logx)'は1/xになるらしい。
対数(logX)’=1/Xの微分は、どう証明するのでしょうか? - awangue1_272... - Yahoo!知恵袋

y' = 3{logx}^2 * 1/x
y' = 3{logx}^2
     ---------
         x

微分の勉強2

参考

微分積分入門

このサイトは、更に深い内容を分かりやすく教えてくれる!ありがとうございます!

極限値とは

極限値

関数f(x)がある場合
xがaに限りなく近づいた場合の、関数f(x)の結果を、以下で表わす

lim  f(x)
x→a

この場合、aを極限値という。

極限値を含む数式の展開は、基本的に代入すればOK

以下の場合

lim  x^2
x→2

xに2を代入して以下となる

2^2 = 4

代入でダメな場合もあり。

以下の場合

lim  x^2 + 2x
x→0 --------
        x

xに0を代入すると、分母が0となり計算できない。
この場合は、別の式に変形してから代入する。

x^2 + 2x
--------
   x

↓

x + 2

↓ xに0を代入して

2

関数の傾き

f(x) = 2x
関数の傾きは2で固定

f(x) = x^2の傾きは不定。グラフにすると曲線になる。

極限値を使うと、x^2のグラフの特定地点の傾きを数式で表せる。

hをxの増加分とすると、、、

lim  (x+h)^2 - x^2
h→0 -------------
           h

xが1の場合、上記数式を展開すると

lim  (1+h)^2 - 1^2
h→0 -------------
            h

↓

lim  1 + 2h + h^2 - 1
h→0 -------------
            h

↓

lim  2h + h^2
h→0 --------
        h

↓

lim  2 + h
h→0

↓

2

たとえば、以下の関数のx=2の時の傾きは
f(x) = x^3 - 1

lim  ((2 + h)^3 - 1) - (2^3 - 1)
h→0 ---------------------------
                 h

↓

lim  {(2 + h)(2 + h)(2 + h) - 1} - 7
h→0 -------------------------------
                h

↓

lim  {(4 + h^2 + 4h)(2 + h) - 1} - 7
h→0 ------------------------------
                h

↓

lim  {(8 + 2h^2 + 8h) + (4h + h^3 + 4h^2) - 1} - 7
h→0 -----------------------------------------------
                        h

↓

lim  6h^2 + 12h + h^3
h→0 -----------------
           h

↓

lim  6h + 12 + h^2
h→0 

↓

12

関数の傾きを算出する数式

xに値を代入せずに数式を展開すると、、、(任意の値x時の傾き)

f(x) = x^3 - 1の場合

lim  {(x + h)^3 - 1} - (x^3 - 1)
h→0 -------------------------
                 h

↓

lim  {(x + h)(x + h)(x + h) - 1} - (x^3 - 1)
h→0 ---------------------------------------
                 h

↓

lim  {(x^2 + 2xh + h^2)(x+h) - 1} - (x^3 - 1)
h→0 ----------------------------------------
                 h

↓

lim  {(x^3 + hx^2) + (2hx^2 + 2xh^2) + (xh^2 + h^3) - 1} - (x^3 - 1)
h→0 --------------------------------------------------------------
                 h

↓

lim  (x^3 + 3hx^2 + 3xh^3 + h^3 - 1) - (x^3 - 1)
h→0 -------------------------------------------
                 h

↓

lim  3hx^2 + 3xh^3 + h^3
h→0 -------------------
                 h

↓ あと、もうちょい。

lim  3x^2 + 3xh^2 + h^2
h→0 

↓ 

3x^2

これが、f(x) = x^3 - 1の任意の点xの傾きを表わす数式となる。

x=2の時は、3*2^2=12

さっきの算出結果とあっている!

微分とは?

f(x)の任意のxの値における傾きを算出する数式を求めること

「f(x)を微分する」

とは、

さっきの数式を導きだすこと。

また、

微分によって求められた数式を導関数

と呼び

元の関数を原始関数

と呼ぶ

導関数の表記

f(x)の導関数は、、、

lim   f(x+1) - f(x)
h→0  -------------
             h


で表わせる。

他にも以下の表記があり。

f'(x)

また

・
f(x)

またまた

d           df(x)
-- f(x) or ----
dx          dx

この

d
--
dx

は、後に記載する関数をxで微分するって意味のよう。
このdは記号みたいなもの。
※英語で微分はdefferentialらしく、そこからdかも?との情報があり。

微分の公式

上記より関数f(x)の微分(導関数の算出)は、以下式から算出できる。

lim  f(x + h) - f(x)
h→0 ---------------
             h

だけど面倒臭い。微分をする為の公式がある。

公式その1

(x^n)' = nx^(n-1)

例)
(x^3)' = 3x^2
(x^2)' = 2x
(x)' = 1

※x^3を()'でくくる=x^3の導関数

公式その2

(af(x))' =af'(x)

aは定数
(af(x))' = af'(x)

例) (4x^3)' = 12x^2

公式その3

aは定数
a' = 0

aは定数の為、変わらない。よって傾きは常に0。

(f(x) + g(x))' = f'(x) + g'(x)
(f(x) - g(x))' = f'(x) - g'(x)

例1) (x^3 + x^2)' = 3x^2 + 2x
例2) (x^3 - x^2)' = 3x^2 - 2x
例3) (x^3 + x^2 - x)' = 3x^2 + 2x - 0

これらの公式を使えば、複雑な式も微分できる。

例)
a,b,cは定数
f(x) = ax^2 + bx + c

f'(x) = 2ax + b + 0 = 2ax + b

微分係数とは?

導関数に値を代入した結果

例)さっきの式では

原始関数が f(x) = x^3 -2 の場合、導関数は、3x^2

x=2の時、3*2^2=12

この12が微分係数となる。

微分の使い道

グラフの形が想像できる!

微分係数がプラスの値の時は、グラフは右肩上がり
微分係数がプラスの値の時は、グラフは右肩下がり

微分で求められた導関数を見れば、なんとなくグラフの形(グラフの概形)が分かる!

例) f(x) = x^2 の場合

導関数は2x

xがプラスならば、微分係数がプラスになる→右肩上がり
xがマイナスならば、微分係数がマイナスになる→右肩上がり
xが0の時は、微分係数が0になる→平行線

おまけ

原始関数→導関数を導く処理を微分

積分は、
導関数→原始関数
をする処理のよう。

微分の勉強1

目的

高校時代についていけなくなった数式について、ぼんやり何を示しているのか理解すること!

微分とはズバリ簡単に説明すると

微分とは何か? - 中学生でも分かる微分のイメージ

ある関数の各点における傾き(変化の割合)のこと

参考にした上記のURLすっごい分かりやすい!感動しました!!ありがとうございます!!!

y = 2x

の傾きはxがどの数値でも"2"で常に変わらず。
→グラフは直線

関数 y=x^2を微分(点における傾き)した値は、2x
xの値によって可変する。
→グラフは曲線

正しくは以下

・ある関数の任意の点における傾きを導く式を導関数とよぶ
導関数を求めることを、一般に微分とよぶ

微分の証明

y = x^2

微分が2xである事を以下で証明できる。

xとx+h間の傾きは以下で示せる。

【最初の式】

(x+h)^2-x^2
--------
(x+h)-x

【展開1】

(x+h)(x+h)-x^2
--------
h

【展開2】

x(x+h)+h(x+h)-x^2
--------
h

【展開3】

2xh+h^2
--------
h

【展開4】

2x+h


【展開5】
hは極限まで0に近づける事を想定した式(lim)

→2x
h->0

※正しい表記は参考にしたURLを見ること!

導関数の表記

y=x^2を微分して得られた導関数
y′=2x
と書く

読み方は、yダッシュ or yプライム

また以下のような別の書き方もあり。

d
--y
dx
d
-- x^2 
dx


上記の書き方は、以下の表記ルールによるもの。

d
-- この記号を関数の前につけると、その関数をxで微分するという意味になるよう
dx

人工知能(AI)勉強メモ ニューラルネットワーク

本題!まずはメモ!

ニューラルネットとは?

神経細胞(neuron)をモデル化した計算素子である人工ニューロンを複数組み合わせたもの

構成単位である人工ニューロンとは?

ニューロンは、電気信号を受けてしきい値を超えたら、次のニューロンに電気信号を送る


f:id:pikesaku:20160919153359p:plain


これを数式では以下のように表現している。

u = Σxi・wi - v
  i

z = f(u)

Σはシグマ。数列の和を示す記号
詳細は以下を参照

わかりやすくΣ(シグマ)の意味を説明 / 数学B by となりがトトロ |マナペディア|

人工ニューロンの計算詳細は以下の通り

①入力x×重みwをx1~xnで計算する。
②①を足す
③②から閾値vを引く
④関数fでuを処理した結果をzとして、出力する

①~④の処理をシグマで記述したのが、上記記述。

関数fは色々なものが利用される。

良く利用されるのは、
①ステップ関数
 入力が0以上であれば1を返す
 入力が0未満であれば0を返す

シグモイド関数
 f(u) = 1 / 1(1 + e-u)
 ※-uは右上添字

良く分からないけど、0 or 1、0~1を返す関数と覚える
ステップ関数は非線形
シグモイドは緩やかな線形

人工ニューロンは重みと閾値を変える事で、出力を調整できる。
人工ニューロンの学習は、この重み・閾値を適切に調節する事

ニューラルネットワークとは?

ニューラルネットワークは、人工ニューロンを複数つなぎ合わせること。
人工ニューロンと同様に、この重み・閾値を適切に調節する事が学習になる。
※単体より複雑なパターンを表現できるって事でしょう。
論理回路(AND,OR等)と同じ動きも可能。

f:id:pikesaku:20160919162039p:plain

人工ニューロンの接続方法により種類が分かれるあり

フィードフォワード型ネットワーク(左から右へ)
階層型ネットワーク(左から右へ)
リカレントネットワーク(ループ構成)

ニューラルネットワークの学習の流れ(教師ありの場合)

①全ての重みと閾値をランダムに初期化
②以下を適当な回数繰り返す
1) 学習データセットから一つの学習例を選び、ニューラルネットに与えて出力を計算する
2) 教師データとニューラルネットの出力を比較し、誤差が小さくなるよう重みと閾値を調整する。

教師データとニューラルネットの出力が一致すれば学習は終了

ポイントはこの重みと閾値の調整方法
遺伝的アルゴリズムを使っても調整は可能(?)
 しかし、バックプロパゲーションが最も効率的な手法として知られている。

バックプロパゲーションとは?

階層型ネットワークで良く用いられる手法
パーセプトロンという手法をベース
パーセプトロンでは最後の出力層の重み・閾値しか調整できない
中間層の重み・閾値も調整できるのが、バックプロパゲーション
バックプロパゲーションはback propagetionの略で「逆向きに何かを伝える」の意味
バックプロパゲーションは誤差を逆向きに伝える。

*

人工ニューロンサンプルプログラム

参考書籍のneuton.cをPython化。少しはしょったかも。

# coding: utf-8

import sys

W1 = 10
W2 = 10
TH = 15

def main():
    inputs = sys.stdin.readlines()
    for i in inputs:
      i = i.strip()
      inp1, inp2 = i.strip().split()
      ret = forward(int(inp1),int(inp2))
      print("Inp1:" + inp1 + " Inp2:" + inp2 + " Out:" + ret)

def forward(inp1,inp2):
    u = (inp1 * W1 + inp2 * W2) - TH

    # Step関数処理
    if u >= 0:
      return "1"
    else:
      return "0"

main()

人工ニューロンサンプルプログラム実行結果

# echo -e "0 0\n0 1\n1 0\n1 1" | python ./an.py 
Inp1:0 Inp2:0 Out:0
Inp1:0 Inp2:1 Out:0
Inp1:1 Inp2:0 Out:0
Inp1:1 Inp2:1 Out:1

この場合は、AND論理素子と同じ動き

ニューラルネットサンプルプログラム

参考書籍のnn.cをPython化。

# coding: utf-8

import sys
import math

n1_omomi = [-2.0, 3.0]
n1_shikii = -1.0

n2_omomi = [-2.0, 1.0]
n2_shikii = 0.5

n3_omomi = [-60.0, 94.0]
n3_shikii = -1.0


def main():
    inputs = sys.stdin.readlines()
    num = 1
    for line in inputs:
        data = line.strip().split()
        data = change_float(data)

        n1_out = forward(data, n1_omomi, n1_shikii)
        n2_out = forward(data, n2_omomi, n2_shikii)
        n3_out = forward([n1_out, n2_out], n3_omomi, n3_shikii)
        print('Num: %d Data1: %f Data2: %f Output: %f' % (num, data[0], data[1], n3_out))
        num += 1


def change_float(data):
    ret = list()
    for i in data:
        ret.append(float(i))
    return ret


def forward(data, omomi, shikii):
    out_src = (data[0] * omomi[0]) + (data[1] * omomi[1]) - shikii
    return dentatsu_kansu(out_src)


def dentatsu_kansu(out_src):
    # Step関数
    if out_src >= 0.0:
        return 1.0
    else:
        return 0.0

#    # シグモイド関数
#    out_src = out_src * -1.0
#    return 1.0 / (1.0 + math.exp(out_src))

main()

ニューラルネットサンプルプログラム実行結果

STEP関数の時

# cat ./data 
0 0
0 1
1 0
1 1
# python ./nn.py < ./data 
Num: 1 Data1: 0.000000 Data2: 0.000000 Output: 0.000000
Num: 2 Data1: 0.000000 Data2: 1.000000 Output: 1.000000
Num: 3 Data1: 1.000000 Data2: 0.000000 Output: 1.000000
Num: 4 Data1: 1.000000 Data2: 1.000000 Output: 0.000000
# 

この場合は、AND論理素子と同じ動き
処理を手計算でやると、以下の通り

########## 入力1処理 #############
0 0

  # 中間層1
  # -2 3 -1
  0 * -2 = 0
  0 *  3 = 0
  (0 + 0) - -1 = 1
  f(1) = 1

  # 中間層2
  # -2 1 0.5
  0 * -2 = 0
  0 *  1 = 0
  (0 + 0) - 0.5 = -0.5
  f(-0.5) = 0

  # 出力層
  # -60 94 -1
   1 * -60 = -60
   0 *  94 = 0
  (-60 + 0) - -1 = -59

  # f伝達関数
  u >= 0 => 1
  else      0

  # 出力結果
  0

########## 入力2処理 #############
0 1

  # 中間層1
  # -2 3 -1
  0 * -2 = 0
  1 *  3 = 3
  (0 + 3) - -1 = 4
  f(4) = 1

  # 中間層2
  # -2 1  0.5
  0 * -2 = 0
  1 *  1 = 1
  (0 + 1) - 0.5 = 0.5
  f(0.5) = 1

  # 出力層
  # -60 94 -1
   1 * -60 = -60
   1 *  94 = 94
  (-60 + 94) - -1 = 35

  # f伝達関数
  u >= 0 => 1
  else      0

  # 出力結果
  1

########## 入力3処理 #############
1 0

  # 中間層1
  # -2 3 -1
  1 * -2 = -2
  0 *  3 = 0
  (-2 + 0) - -1 = -1
  f(-1) = 0

  # 中間層2
  # -2 1  1
  1 * -2 = -2
  0 *  1 = 0
  (-2 + 0) - 1 = -3
  f(-3) = 0

  # 出力層
  # -60 94 -1
   0 * -60 = 0
   0 *  94 = 0
  (0 + 0) - -1 = 1

  # f伝達関数
  u >= 0 => 1
  else      0

  # 出力結果
  1

########## 入力4処理 #############
1 1

  # 中間層1
  # -2 3 -1
  1 * -2 = -2
  1 *  3 = 3
  (-2 + 3) - -1 = 2
  f(2) = 1

  # 中間層2
  # -2 1  1
  1 * -2 = -2
  1 *  1 = 1
  (-2 + 1) - 1 = -2
  f(-2) = 0

  # 出力層
  # -60 94 -1
   1 * -60 = -60
   0 *  94 = 0
  (-60 + 0) - -1 = -59

  # f伝達関数
  u >= 0 => 1
  else      0

  # 出力結果
  0

シグモイド関数の時

# python ./nn.py < ./data 
Num: 1 Data1: 0.000000 Data2: 0.000000 Output: 0.000627
Num: 2 Data1: 0.000000 Data2: 1.000000 Output: 0.643445
Num: 3 Data1: 1.000000 Data2: 0.000000 Output: 0.000333
Num: 4 Data1: 1.000000 Data2: 1.000000 Output: 0.000000

動きが変わる。