簡體   English   中英

無法將11行玩具神經網絡代碼轉換為JavaScript

[英]trouble translating 11-line toy neural network code to JavaScript

我將在星期二向我的同學Web開發人員做一個關於神經網絡的簡短演講。 我希望將這段代碼 (在第1部分中,一個很小的玩具神經網絡:2層網絡)轉換為JavaScript,以使我的讀者更容易理解。

import numpy as np

# sigmoid function
def nonlin(x,deriv=False):
    if(deriv==True):
        return x*(1-x)
    return 1/(1+np.exp(-x))

# input dataset
X = np.array([  [0,0,1],
                [0,1,1],
                [1,0,1],
                [1,1,1] ])

# output dataset            
y = np.array([[0,0,1,1]]).T

# seed random numbers to make calculation
# deterministic (just a good practice)
np.random.seed(1)

# initialize weights randomly with mean 0
syn0 = 2*np.random.random((3,1)) - 1

for iter in xrange(10000):

    # forward propagation
    l0 = X
    l1 = nonlin(np.dot(l0,syn0))

    # how much did we miss?
    l1_error = y - l1

    # multiply how much we missed by the 
    # slope of the sigmoid at the values in l1
    l1_delta = l1_error * nonlin(l1,True)

    # update weights
    syn0 += np.dot(l0.T,l1_delta)

print "Output After Training:"
print l1

這是我現在的JavaScript代碼。 我只是取消了ES6的版本使其可以在我的IDE中運行:

const _ = require('lodash')
const m = require('mathjs')

const sigmoid = function(z) { return 1.0 / (1.0 + Math.exp(-z)) }

const sigmoid_prime = function(z) { return sigmoid(z) * (1 - sigmoid(z)) }

var X = m.matrix([ [0,0,1],[0,1,1],[1,0,1],[1,1,1] ])
var y = m.transpose(m.matrix(([[0,1,1,0]])))

var syn0 = m.random([3, 1], -1, 1)

var l0, l1, l1_delta, l1_error

_.range(10000).forEach(function() {

    l0 = X;
    l1 = m.map(m.multiply(l0, syn0), sigmoid)
    l1_error = m.subtract(y, l1)
    l1_delta = m.dotMultiply(l1_error, m.map(l1, sigmoid_prime))
    syn0 = m.multiply(m.transpose(l0),l1_delta)
})

console.log("Output After Training:")
console.log(l1)

如您所見,我正在使用mathjs代替numpy。 我試圖仔細查看mathjs和numpy的文檔,而不是將矩陣乘法和元素乘法相混淆,但是有些地方很破損,每個輸出都得到0.5。 我在調試器中逐步執行了程序,並在python暫存文件中並排比較了值,從python開始使用JavaScript程序生成的syn0值,似乎在這里,反向傳播線,它們略有差異(並且在迭代中可能會更多): l1_delta = m.dotMultiply(l1_error, m.map(l1, sigmoid_prime)) 但是我不明白為什么。

編輯:我應該在發布之前更新代碼,以反映在上一版本中我將y定義更改為var y = m.matrix([ [0], [0], [1], [1]])和它稍微修改了問題,因為輸出從所有的.5切換為從.5稍微浮動。

第二次編輯:Brent在注釋中正確地指出了我有一個錯誤,因為要模仿從S型素數素函數中移植的代碼,只需要z *(1-z)。 我錯過了那皺紋。 可悲的是,這沒有什么區別。 控制台在最后一次迭代中記錄字符串化函數和syn0的值:

sigmoid prime is function (z) {return sigmoid(z) * (1 - sigmoid(z))}
syn0 is Matrix {
  _data: 
   [ [ 0.21089543115482337 ],
     [ -0.010100491415226356 ],
     [ -0.021376195229226028 ] ],
  _size: [ 3, 1 ],
  _datatype: undefined }

現在更改功能:

sigmoid prime is function (z) { return z * (1 - (z)) }
syn0 is Matrix {
  _data: 
   [ [ 0.2235282818415481 ],
     [ -0.010714305064562765 ],
     [ -0.022890185954402634 ] ],
  _size: [ 3, 1 ],
  _datatype: undefined }

看起來您非常接近,這是一個不錯的港口。

認為這是您翻譯nonlin函數時的一個小錯誤。 在其中的情況下deriv參數為真時,方程是x * (1 - x) 在您的版本中,您正在使用sigmoid(x) * (1 - sigmoid(x)) 我認為您不需要從sigmoid_prime內部調用sigmoid

希望對您有所幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM