0

我想抓住神經網絡背後的想法(完全),所以我開始創建我自己的simple perceptron算法。簡單/單層感知器算法不起作用

這裏是我的代碼(在JavaScript):

var lr = 0.1;//learning rate 

//Initiate the weights randomly 
function initWeights(weights, trainingSets){ 
    for(var i=0; i<trainingSets[0].in.length; i++){ 
     weights[i] = Math.random()*2 - 1; 
    } 
    weights.push(Math.random()*2 - 1); //b 
} 


//Return the raw activation value for a giving trainingSet 
function getSum(weights, trainingSet){ 
    var sum = 0; 
    for(var i=0; i < trainingSet.in.length; i++){ 
     sum += weights[i]*trainingSet.in[i]; 
    } 
    sum += 1 * weights[weights.length-1]; 
    return sum; 
} 

//Activation function 
function activate(value){ 
    return (value >= 0)? 1 : 0; 
} 

function train(weights, trainingSets){ 
    var error = 0; 
    for(var i=0; i<trainingSets.length; i++){ 
     var currentSet = trainingSets[i]; 
     var activationValue = getSum(weights, currentSet); 
     var error = currentSet.out - activate(activationValue); 
     error += error; 
     for(var j=0; j<weights.length-1; j++){ 
      var deltaW = error * lr * currentSet.in[j]; 
      weights[j] += deltaW; 
     } 
     weights[weights.length-1] += error * lr * 1; 
    } 
    return error/(weights.length); 
} 

var inp = [ 
    {in:[1,1], out:1}, 
    {in:[0,0], out:0}, 
    {in:[0,1], out:0}, 
]; 
var w = []; 
initWeights(w, inp); 
//for(var j = 0; j < inp.length; j++){ 
    var error = 1; 
    while(error >= 0.01){ 
     error = train(w, inp); 
    } 
//} 
console.log("===") 
var tester = {in:[1,0], out: NaN}; 
console.log(getSum(w, tester)) //should be negative 
console.log("y=("+w[1]+"*x+"+w[2]+")/"+w[1]) 

的結果並不一致,(我使用的是與算法學會)。
情節應該是這樣的:
http://puu.sh/44eIY/401f63cde7.png
但通常是這樣的:
http://puu.sh/44eAJ/75488a05eb.png

我敢肯定,我失去了一些東西在這裏小,
在此先感謝。

回答

1

至少有三個問題與您的代碼:

  • 重新聲明錯誤變量,它首先意味着是一個總結錯誤,那麼你再次聲明爲以每個輸出神經元的錯誤,這導致了失去的信息reagarding全過程
  • 你停止標準是壞的 - 它應該是錯誤的平均絕對價值,而不僅僅是錯誤的總和 - 考慮簡單的網絡,其中classyfies一個培訓示例o ˚F標籤01,它會導致你的代碼錯誤,所以訓練停止,即使它是遠未結束
  • 這是不正確的,即訓練後

    var inp = [ 
        {in:[1,1], out:1}, 
        {in:[0,0], out:0}, 
        {in:[0,1], out:0}, 
    ]; 
    

    你會得到f([1,0]) == 0,這不是感知器的工作原理。它將簡單地在二維平面中找到這樣一條線,即[1,1]位於其一側,另一側則爲[0,0][0,1]。不保證,[1,0][0,0][0,1]位於同一側,並且這是預計的行爲。利用提供的數據,感知器沒有理由不使用與您的數據完全分離的x=0.5垂直線,而是使用f([1,0]) == 1。您的培訓數據不會「定義」操作,只是一組簡單的規則,這些規則由無數個分類器服從。

    function train(weights, trainingSets){ 
    var error = 0; 
    for(var i=0; i<trainingSets.length; i++){ 
        var currentSet = trainingSets[i]; 
        var activationValue = getSum(weights, currentSet); 
        var error_current = currentSet.out - activate(activationValue); 
        error += Math.abs(error_current); 
        for(var j=0; j<weights.length-1; j++){ 
         var deltaW = error_current * lr * currentSet.in[j]; 
         weights[j] += deltaW; 
        } 
        weights[weights.length-1] += error_current * lr * 1; 
    } 
    return error/(weights.length); 
    } 
    

如評論所說,如果你與價值觀培養你的網絡點(1,0),(0,1)和(1,1),它會推斷值(0, 0)本身

var inp = [ 
    {in:[1,1], out:1}, 
    {in:[0,1], out:0}, 
    {in:[1,0], out:0}, 
]; 

var w = []; 
initWeights(w, inp); 
//for(var j = 0; j < inp.length; j++){ 
    var error = 1; 
    while(error >= 0.01){ 
     error = train(w, inp); 
    } 
//} 
console.log("===") 

var test = [ 
    {in:[1,1], out:1}, 
    {in:[0,0], out:0}, 
    {in:[0,1], out:0}, 
    {in:[1,0], out:0}, 
]; 

for(var i=0; i<test.length; ++i){ 
console.log(test[i].in + " out: " +test[i].out + " nn: " + activate(getSum(w, test[i]))); 
} 

產生

1,1 out: 1 nn: 1 
0,0 out: 0 nn: 0 
0,1 out: 0 nn: 0 
1,0 out: 0 nn: 0 
+0

嘿,我正要寫我的回答相同的結果。 – tsiki

+0

是的,錯誤被重新宣佈,我的壞(我不是故意這樣做)。另外,最後一點讓我感到困惑,並不是給出一套基本的規則(不是全部)和(希望)網絡會相應的行爲的整個想法? – funerr

+0

但它的行爲相應。只是你的規則集很小,以期望如此大的泛化。有太多可能的模型,**完全適合**你期望的規則集,它會奇妙地選擇你感興趣的唯一一個。 – lejlot