LoginSignup
2
3

More than 1 year has passed since last update.

ゼロから作るDeep LearningをJuliaで実装してみる (3)3層ニューラルネットワークの実装

Last updated at Posted at 2021-10-06

:red_car: この記事の目的

本記事は、Deep Learningの入門書「ゼロから作るDeep Learning」を参考に、Juliaを用いて同書の内容を実装してみる、という試みです。

※これはあくまで筆者の一つの試みと提案で、必ずしも内容が正解ではありませんのでご了承お願い致します。
また、より良いアドバイスや協力のご提案などありましたら、お気軽にお声がけ頂けますと幸いです。

:red_car: 今回取り組むこと

本記事は、参考書の3.4章「3層ニューラルネットワークの実装」にあたります。
特に、3.4.3の実装を確認したいと思います。

参考書のソースでは、init_network()関数の冒頭でnetwork変数を辞書型で宣言しています。Juliaでもこれと同じように、network変数を辞書型で宣言します。
さらに、networkの内容も併せて多次元配列で定義します。

3_multidimensional_array
network = Dict()
network["W1"] = [0.1 0.3 0.5; 0.2 0.4 0.6]
network["b1"] = [0.1 0.2 0.3]
network["W2"] = [0.1 0.4; 0.2 0.5; 0.3 0.6]
network["b2"] = [0.1 0.2]
network["W3"] = [0.1 0.3; 0.2 0.4]
network["b3"] = [0.1 0.2]

networkは以下のような行と列を持つ多次元配列となります。

行列 行と列の数
network["W1"] 2行3列
network["b1"] 1行3列
network["W2"] 3行2列
network["b2"] 1行2列
network["W3"] 2行2列
network["b3"] 1行2列

Juliaでは、行列同士の掛け算や足し算、引き算はそのまま記述すれば良いです。
ただし、行数と列数が次の条件を満たしていることが必要です。

掛け算
 条件:行列Aと行列Bをかけるとき、Aの列数とBの行数が同じであること。
 例えば、l,m,nを整数とするとき、AとBのそれぞれの行数と列数が以下を満たすときです。
  ・Aはl行m列の行列
  ・Bはm行n列の行列

足し算、引き算
 条件:二つの行列のそれぞれの行数と列数が等しいこと。

以下の計算を行う際のソースを作成します。
xを1行2列の行列、W1を2行3列の行列、b1を1行3列の行列とするとき、
 a1 = x * W1 + b1
を求めるソースは、

3_multidimensional_array
x = [1.0 0.5]
W1 = [0.1 0.3 0.5; 0.2 0.4 0.6]
b1 = [0.1 0.2 0.3]

a1 = x * W1 + b1

上記の記載で行列の計算が行われます。

以降、参考書のソースに従うと、
関数init_network()を宣言し、辞書型の変数networkを取得する処理を作成します。

3_multidimensional_array
function init_network()
    network = Dict()
    network["W1"] = [0.1 0.3 0.5; 0.2 0.4 0.6]
    network["b1"] = [0.1 0.2 0.3]
    network["W2"] = [0.1 0.4; 0.2 0.5; 0.3 0.6]
    network["b2"] = [0.1 0.2]
    network["W3"] = [0.1 0.3; 0.2 0.4]
    network["b3"] = [0.1 0.2]

    return network
end

前回の記事で作成した[前回の記事]、シグモイド関数を引用します。
ソースは以下となります。

3_multidimensional_array
function sigmoid_function(x)
    return map(i -> 1 / (1 + exp(-i)), x)
end

また、恒等関数を定義します。
参考書の通り、恒等関数は以下となります。

3_multidimensional_array
function identify_function(x)
    return x
end

さらに、シグモイド関数及び恒等関数を用いて、ニューラルネットワークの各層の計算を行う以下のようなforward()関数を定義します。

3_multidimensional_array
function forward(network, x)
    W1, W2, W3 = network["W1"], network["W2"], network["W3"]
    b1, b2, b3 = network["b1"], network["b2"], network["b3"]

    a1 = x * W1 + b1
    z1 = sigmoid_function(a1)
    a2 = z1 * W2 + b2  
    z2 = sigmoid_function(a2)
    a3 = z2 * W3 + b3
    y = identify_function(a3)

    return y
end

これらの関数を用いて、以下の手順で行列の計算を行います。

手順(1) init_network()を実行し、行列network変数を取得する。
手順(2) 行列xを宣言する。
手順(3) 引数にnetworkとxを設定してforwar()関数を呼び出す。
  forwar()関数の中でシグモイド関数や恒等関数を用いた行列の計算を行う。
手順(4) 解として得られる行列yを表示する。

全ソースは以下となります。

3_multidimensional_array
function init_network()
    network = Dict()
    network["W1"] = [0.1 0.3 0.5; 0.2 0.4 0.6]
    network["b1"] = [0.1 0.2 0.3]
    network["W2"] = [0.1 0.4; 0.2 0.5; 0.3 0.6]
    network["b2"] = [0.1 0.2]
    network["W3"] = [0.1 0.3; 0.2 0.4]
    network["b3"] = [0.1 0.2]

    return network
end


# シグモイド関数の定義
function sigmoid_function(x)
    return map(i -> 1 / (1 + exp(-i)), x)
end


# 恒等関数の定義
function identify_function(x)
    return x
end


function forward(network, x)
    W1, W2, W3 = network["W1"], network["W2"], network["W3"]
    b1, b2, b3 = network["b1"], network["b2"], network["b3"]

    a1 = x * W1 + b1
    z1 = sigmoid_function(a1)
    a2 = z1 * W2 + b2  
    z2 = sigmoid_function(a2)
    a3 = z2 * W3 + b3
    y = identify_function(a3)

    return y
end

network = init_network()  # 手順(1)
x = [1.0 0.5]             # 手順(2)
y = forward(network, x)   # 手順(3)
println(y)                # 手順(4)

実行結果です。
image.png

参考書と同じ結果を得ました。
次は、ソフトマックス関数の実装を行ってみたいと思います。

:red_car: もくじ

(1)論理回路
(2)活性化関数
(3)3層ニューラルネットワークの実装
(4)ソフトマックス関数
(5)MNIST手書き数字認識 その①画像表示
(5)MNIST手書き数字認識 その②推論

:red_car: 関連情報

:paperclip: Julia早引きノート[01]変数・定数の使い方
https://qiita.com/ttabata/items/a1ada2c0cba03672e105

:paperclip: Julia - 公式ページ
https://julialang.org/

:paperclip: Julia - 日本語公式ドキュメント
https://julia-doc-ja.readthedocs.io/ja/latest/index.html

:paperclip: 初めてのJuliaとインストール (Windows & Linux)
https://qiita.com/ttlabo/items/b05bb43d06239f968035

:red_car: 出典

■参考書
「ゼロから作るDeep Learning ~ Pythonで学ぶディープラーニングの理論と実装」
 斎藤康毅 著/オライリー・ジャパン
image.png

:red_car: ご意見など

ご意見、間違い訂正などございましたらお寄せ下さい。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3