「ニューラルネットワーク自作入門」Swiftで書く
概要
書籍「ニューラルネットワーク自作入門」をSwiftでコーディング。
「Matrix」は別記事参照。
2.4.8 完成版ニューラルネットワークコード」
書籍
172〜174頁
Python
Swiftコード
import Foundation
class neuralNetwork {
var inodes:Int
var hnodes:Int
var onodes:Int
var lr:Double
var wih:Matrix
var who:Matrix
init(inputnodes:Int, hidedennodes:Int, outputnodes:Int, learningrate:Double) {
// 入力層、隠れ層、出力層のノード数の設定
inodes = inputnodes
hnodes = hidedennodes
onodes = outputnodes
// リンクの重み行列 wihとwho
// 行列内の重み w_i_j,ノードIから次の層のノードjへのリンクの重み
// w11 w21
// w12 w22 など
wih = Matrix.rand(rows: hnodes, colums: inodes) - 0.5
who = Matrix.rand(rows: onodes, colums: hnodes) - 0.5
// 学習率の設定
lr = learningrate
}
// ニューラルネットワークの学習
func train(inputs_list:[Double], targets_list:[Double]) {
// 入力リストを行列に変換
var inputs = Matrix()
inputs.matrix = [[Double]](repeating: [Double](repeating: 0.0, count: 1), count: inputs_list.count)
for r in 0..<inputs_list.count - 1{
inputs.matrix[r][0] = inputs_list[r]
}
var targets = Matrix()
targets.matrix = [[Double]](repeating: [Double](repeating: 0.0, count: 1), count: targets_list.count)
for r in 0..<targets_list.count - 1{
targets.matrix[r][0] = targets_list[r]
}
// 隠れ層に入ってくる信号の計算
let hidden_inputs = Matrix.dot(left: wih, right: inputs)
// 隠れ層で結合された信号を活性化関数により出力
let hidden_outputs = activation_function(input: hidden_inputs)
// 出力層に入ってくる信号の計算
let final_inputs = Matrix.dot(left: who, right: hidden_outputs)
// 出力層で結合された信号を活性化関数により出力
let final_outputs = activation_function(input: final_inputs)
// 出力層の誤差 = (目標出力 - 最終出力)
let output_errors = targets - final_outputs
// 隠れ層の誤差おは出力層の誤差をリンクの重みの配合で分配
let hidden_errors = Matrix.dot(left: who, right: output_errors)
// 隠れ層と出力層の間のリンクの重みを更新
who = who + lr * Matrix.dot(left: (output_errors * final_outputs) * (1.0 - final_outputs), right: Matrix.transpose(input: hidden_outputs))
// 入力層と隠れ層の間のリンクの重みを更新
wih = wih + lr * Matrix.dot(left: (hidden_errors * hidden_outputs) * (1.0 - hidden_outputs), right: Matrix.transpose(input: inputs))
}
// ニューラルネットワークへの照会
func query(inputs_list:[Double]) -> Matrix {
var inputs = Matrix()
inputs.matrix = [[Double]](repeating: [Double](repeating: 0.0, count: 1), count: inputs_list.count)
for r in 0..<inputs_list.count - 1{
inputs.matrix[r][0] = inputs_list[r]
}
// 隠れ層に入ってくる信号の計算
let hidden_inputs = Matrix.dot(left: wih, right: inputs)
// 隠れ層で結合された信号を活性化関数により出力
let hidden_outputs = activation_function(input: hidden_inputs)
// 出力層に入ってくる信号の計算
let final_inputs = Matrix.dot(left: who, right: hidden_outputs)
// 出力層で結合された信号を活性化関数により出力
let final_outputs = activation_function(input: final_inputs)
return final_outputs
}
func activation_function(input:Matrix) -> Matrix {
var result = Matrix()
result.matrix = [[Double]](repeating: [Double](repeating: 0.0, count: input.matrix[0].count), count: input.matrix.count)
for r in 0..<input.matrix.count {
for c in 0..<input.matrix[r].count {
// シグモイド関数 1 / (1 + exp(-(x)))
result.matrix[r][c] = 1 / (1 + exp(-(input.matrix[r][c])))
}
}
return result
}
}






