将XOR神经网络修改为其他类型的神经网络

时间:2014-08-08 02:25:13

标签: php html machine-learning neural-network

我下载了一个用PHP编写的神经网络程序。这是XOR门。我想将其修改为适用于其他数据集的程序。是否可以通过更改训练数据集来实现。

我改变了这一部分。我使用了数据集(1,2,1) - (3),(1,4,1) - (5),(2,2,1) - (4),(2,4,1)-6而不是XOR门的训练数据集。

代码以前工作,但只是更改训练数据集,它对我没用。每个数据集生成的输出为1。你能帮帮我吗?

        <?php
require_once ("class_neuralnetwork.php");

// Create a new neural network with 3 input neurons,
// 4 hidden neurons, and 1 output neuron
$n = new NeuralNetwork(3, 4, 1);
$n->setVerbose(false);

// Add test-data to the network. In this case,
// we want the network to learn the 'XOR'-function
$n->addTestData(array (-1, -1, 1), array (-1));
$n->addTestData(array (-1,  1, 1), array ( 1));
$n->addTestData(array ( 1, -1, 1), array ( 1));
$n->addTestData(array ( 1,  1, 1), array (-1));

// we try training the network for at most $max times
$max = 3;

echo "<h1>Learning the XOR function</h1>";
// train the network in max 1000 epochs, with a max squared error of 0.01
while (!($success = $n->train(1000, 0.01)) && ++$i<$max) {
    echo "Round $i: No success...<br />";
}

// print a message if the network was succesfully trained
if ($success) {
    $epochs = $n->getEpoch();
    echo "Success in $epochs training rounds!<br />";
}

echo "<h2>Result</h2>";
echo "<div class='result'>";
// in any case, we print the output of the neural network
for ($i = 0; $i < count($n->trainInputs); $i ++) {
    $output = $n->calculate($n->trainInputs[$i]);
    echo "<div>Testset $i; ";
    echo "expected output = (".implode(", ", $n->trainOutput[$i]).") ";
    echo "output from neural network = (".implode(", ", $output).")\n</div>";
}
echo "</div>";
//echo "<h2>Internal network state</h2>";
//$n->showWeights($force=true);

// Now, play around with some of the network's parameters a bit, to see how it 
// influences the result
$learningRates = array(0.1, 0.25, 0.5, 0.75, 1);
$momentum = array(0.2, 0.4, 0.6, 0.8, 1);
$rounds = array(100, 500, 1000, 2000);
$errors = array(0.1, 0.05, 0.01, 0.001);

echo "<h1>Playing around...</h1>";
echo "<p>The following is to show how changing the momentum & learning rate, 
in combination with the number of rounds and the maximum allowable error, can 
lead to wildly differing results. To obtain the best results for your 
situation, play around with these numbers until you find the one that works
best for you.</p>";
echo "<p>The values displayed here are chosen randomly, so you can reload 
the page to see another set of values...</p>";

for ($j=0; $j<10; $j++) {
    // no time-outs
    set_time_limit(0);

    $lr = $learningRates[array_rand($learningRates)];
    $m = $momentum[array_rand($momentum)];
    $r = $rounds[array_rand($rounds)];
    $e = $errors[array_rand($errors)];
    echo "<h2>Learning rate $lr, momentum $m @ ($r rounds, max sq. error $e)</h2>";
    $n->clear();
    $n->setLearningRate($lr);
    $n->setMomentum($m);
    $i = 0;
    while (!($success = $n->train($r, $e)) && ++$i<$max) {
        echo "Round $i: No success...<br />";
        flush();
    }

    // print a message if the network was succesfully trained
    if ($success) {
        $epochs = $n->getEpoch();
        echo "Success in $epochs training rounds!<br />";

        echo "<div class='result'>";
        for ($i = 0; $i < count($n->trainInputs); $i ++) {
            $output = $n->calculate($n->trainInputs[$i]);
            echo "<div>Testset $i; ";
            echo "expected output = (".implode(", ", $n->trainOutput[$i]).") ";
            echo "output from neural network = (".implode(", ", $output).")\n</div>";
        }
        echo "</div>";
    }
}
?>
        </div>
    </body>
</html>

1 个答案:

答案 0 :(得分:1)

如果没有看到神经网络实现的代码,很难给出确定的答案。但看起来实现可能正在使用tanh激活函数,这会将神经元输出约束到范围(-1,1)。此外,似乎实现不使用隐式偏置输入,这就是为什么XOR函数的示例使用第三个输入,该输入在所有情况下都显式设置为1.

因此,基本问题是所有目标输出都超出了激活功能的范围。您需要重新构建网络,但如何执行此操作取决于您要完成的任务。从您的问题来看,目前尚不清楚您是在尝试训练分类器还是插入函数。

如果您的四个不同输出(3,5,4和6)代表类,那么您应该定义一个具有四个输出的网络,并按如下方式定义所需的输出值:

$n = new NeuralNetwork(3, 4, 4);

$n->addTestData(array (1, 2, 1), array ( 1, -1, -1, -1));
$n->addTestData(array (1, 4, 1), array (-1,  1, -1, -1));
$n->addTestData(array (2, 2, 1), array (-1, -1,  1, -1));
$n->addTestData(array (2, 4, 1), array (-1, -1, -1,  1));

请注意,您的示例可能需要4个以上的隐藏节点。<​​/ p>

如果您尝试进行函数插值,那么您只需保留单个输出神经元,但需要将目标输出值缩放到tanh函数的范围内。