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


Modify XOR Neural network to other type of Neural networks

我下载了一个用PHP编写的神经网络程序。它是用于异或门的。我想把它修改成一个适用于其他数据集的程序。有没有可能仅仅通过改变训练数据集。

我改变了这一部分。我使用数据集(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>

如果没有看到神经网络实现的代码,很难给出一个明确的答案。但看起来实现可能使用tanh激活函数,这将约束神经元输出到范围(- 1,1)。此外,实现似乎不使用隐式偏差输入,这就是为什么异或函数的示例使用第三个输入,该输入在所有情况下都显式设置为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个以上的隐藏节点。

如果你试图做函数插值,那么你将只保留单个输出神经元,但需要缩放你的目标输出值,使其在tanh函数的范围内。