0

私はニューラル ネットワークの背後にあるアイデアを (完全に) 把握しようとしているので、独自の単純なパーセプトロンアルゴリズムを作成することから始めています。

これが私のコードです(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])

結果に一貫性がありません (学習には AND アルゴリズムを使用しています)。
プロットは次のようになります。
http://puu.sh/44eIY/401f63cde7.png
しかし、通常は次のようになります。
http://puu.sh/44eAJ/75488a05eb.png

ここで何か小さなことが欠けていると確信しています
。よろしくお願いします。

4

1 に答える 1

1

コードには少なくとも 3 つの問題があります。

  • エラー変数を再宣言しています。最初は要約されたエラーを意味していましたが、出力ニューロンごとのエラーとして再度宣言すると、プロセス全体に関する情報が失われます。
  • あなたの停止基準は悪いです-それはエラーの合計ではなく、エラーの平均絶対値でなければなりません-ラベルの1つのトレーニング例を として分類する単純なネットワークを検討0てください。終わりには程遠いのに1
  • でトレーニングした後、それは真実ではありません

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

    が得られますがf( [1,0] ) == 0、これはパーセプトロンの仕組みではありません。2次元平面でそのような線を見つけるだけです。つまり、一方の側と[1,1]もう一方の側にあります。がとと同じ側にあるという保証はなく、これは予想される動作です。提供されたデータを使用すると、パーセプトロンがデータを完全に分離するの垂直線を使用しない理由はありませんが、 . トレーニング データは「定義」および操作ではなく、無限の数の分類子が従う単純な一連のルールです。[0,0][0,1][1,0][0,0][0,1]x=0.5f( [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 
于 2013-08-19T06:41:53.020 に答える