用PHP5重构人工神经网络

时间:2014-08-12 15:40:53

标签: php artificial-intelligence

因此,在我的网络应用中,我设法将<canvas>连接到ANN for PHP5(http://ann.thwien.de/index.php/Main_Page)。我这样训练:

<?php
require_once 'ANN/Loader.php';

$data = $_POST['data'];

$data = array_map('floatval', $data);

use ANN\Network;
use ANN\Values;

try
{
    $objNetwork = Network::loadFromFile('xor.dat');
}
catch(Exception $e)
{
    print 'Creating a new one...';

    $objNetwork = new Network;

    $objValues = new Values;

    $objValues->train();
    call_user_func_array(array($objValues, 'input'), $data);
    $objValues->output(1);

    $objValues->saveToFile('values_xor.dat');

    unset($objValues);
}

try
{
    $objValues = Values::loadFromFile('values_xor.dat');
}
catch(Exception $e)
{
    die('Loading of values failed');
}

$objNetwork->setValues($objValues); // to be called as of version 2.0.6

$boolTrained = $objNetwork->train();

print ($boolTrained)
    ? 'Network trained'
    : 'Network not trained completely. Please re-run the script';

$objNetwork->saveToFile('xor.dat');

$objNetwork->printNetwork();

如果我需要检查神经网络的数据,我可以这样做:

<?php
require_once 'ANN/Loader.php';

$data = $_POST['data'];

$data = array_map('floatval', $data);

use ANN\Network;
use ANN\Values;

try
{
    $objNetwork = Network::loadFromFile('xor.dat');
}
catch(Exception $e)
{
    die('Network not found');
}

try
{
    $objValues = Values::loadFromFile('values_xor.dat');
}
catch(Exception $e)
{
    die('Loading of values failed');
}

call_user_func_array(array($objValues, 'input'), $data);

$objNetwork->setValues($objValues);

print_r($objNetwork->getOutputs());

然而,我最终想要的是,如果神经网络识别出一个手势,它会使用该数据进行训练。因此,理想情况下,随着时间的推移它变得更加准确。几天来我一直在试图解决这个问题,但我一无所获。

1 个答案:

答案 0 :(得分:1)

观察

大多数经典的ANN架构都遵循

的程序
  • 操作两种模式:培训和制图
训练后的权重(以及因此网络的记忆)是固定的。

有些模型试图将新知识添加到现有数据集中。看看自适应共振理论,ART神经网络。然而,他们并不一定要吸收新知识。他们可能会添加一个新输出或一组神经元来对新项目进行分类。

用于模式识别的goto ANN,您的问题似乎是前馈网络/多层感知器,由反向传播(BP)训练。

我查看了您的链接,似乎正在使用&#34;多层感知器&#34;,因此您可能会遇到这种架构。

问题

这里的问题是,如果您的网络已经过(N)模式和生成(O)输出的训练,则会显示一个新模式(p)。 它将(P)归类为属于产生输出(o)的相同模式(n)或模式组(ns)。

我不知道您的训练数据是否添加了1个训练模式= 1个输出或多个训练模式= 1个输出。

解决方案

强力方法是通过(p)添加到训练数据中来完全重新训练您的网络。

还有其他选择。

BP遵循渐变正确,因此在每个训练周期结束时,您将收到错误。当此错误低于所选级别error_t时,BP通常会停止。 (见末尾的注释)。这不是一个很好的方式,并导致猜测和过度/不足的培训。假设它实际上达到了目标水平而没有陷入局部最小值。

最初你的错误会很高,因为它接近你的error_t,你可以保存权重的副本。这些代表您的网络处于部分训练状态(error_p)。

当您想要引入模式(p)时,您可以使用这些经过部分训练的权重重新开始训练,而不是初始或新的随机权重。该错误最初应从(error_p)开始,然后开始下降。当新的部分训练的权重再次达到error_p时,保存它们。让它完成训练并重新开始工作。

可替换地。 (1)当你想包括(p)时。仅使用(p)或要添加的训练模式组(p)重新训练网络。这将改变对所有其他模式输出对的识别。

请注意,您训练有素的网络原创性采用了新的模式p,并且其上的错误足够低,以至于它说'#34;我知道你&#34;。这意味着当您向训练算法提供经过训练的权重和p时,它可能已经低于您的目标误差,并且您将只获得1个训练周期。

所以我建议只做一个训练周期,如(1)所述。然后测试所有训练数据+ p。如果错误低于error_t,请考虑进行训练,如果没有让它继续运行,直到你回到error_t。

结束时注意

以任意错误停止BP是培训的基本方法。这样做可能会使网络没有经过足够的培训,因此无法识别您想要的内容或者#34;过度安装&#34;所以它只识别你的训练模式并拒绝你的现实世界模式。

另一种方法是拥有一套训练模式和验证集。 您使用训练数据训练网络,但不要将错误视为停止标志。 相反,在每个培训周期后,您都会向网络显示验证模式,如果它识别出来,则会停止培训。这是您的验证error_v。

情况有点糟糕。

假设您有N种训练模式。 在每个训练周期开始时,您将显示网络模式[1]。网络产生错误(期望输出 - 实际输出),你回想一想传播这个错误然后网络,这意味着下次它看到模式[1]时错误应该更低。 它在这里做的是稍微修改一下权重。

现在你对模式[2],......等做同样的事情,直到模式[N]。

每次网络调整其模式[n]的权重时,它都会影响对先前模式[1到n-1]的识别。所以当你得到模式[N]时。以前的学习可能会造成很多伤害。理论上最严重的损害应该发生在模式[1]的学习中,但它实际上取决于模式和模式变量的数学与输出变量之间的共同相似性。

我告诉你的原因是,如果你要向训练有素的网络代表一种新的模式,你就是在做一些这样的事情。

您可以通过在每个训练周期中以随机顺序(或步进顺序)呈现训练模式来修复/缓解它,因此模式[1]并不总是首先出现,模式[N]并不总是最后看到。