php - 如何将神经网络从 C 转换为 PHP
问题描述
我正在尝试将此算法从 C 语言翻译为 PHP(供研究) 这是感知器的一个示例。我复制了用 c 编写的示例,并尝试将其转换为 PHP。目前我写了这段代码,我错了什么?作为输出,我只知道 101 次迭代,结果总是 1。
这是C程序:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define LEARNING_RATE 0.1
#define MAX_ITERATION 100
float randomFloat()
{
return (float)rand() / (float)RAND_MAX;
}
int calculateOutput(float weights[], float x, float y)
{
float sum = x * weights[0] + y * weights[1] + weights[2];
return (sum >= 0) ? 1 : -1;
}
int main(int argc, char *argv[])
{
srand(time(NULL));
float x[208], y[208], weights[3], localError, globalError;
int outputs[208], patternCount, i, p, iteration, output;
FILE *fp;
if ((fp = fopen("test1.txt", "r")) == NULL) {
printf("Cannot open file.\n");
exit(1);
}
i = 0;
while (fscanf(fp, "%f %f %d", &x[i], &y[i], &outputs[i]) != EOF) {
if (outputs[i] == 0) {
outputs[i] = -1;
}
i++;
}
patternCount = i;
weights[0] = randomFloat();
weights[1] = randomFloat();
weights[2] = randomFloat();
iteration = 0;
do {
iteration++;
globalError = 0;
for (p = 0; p < patternCount; p++) {
output = calculateOutput(weights, x[p], y[p]);
localError = outputs[p] - output;
weights[0] += LEARNING_RATE * localError * x[p];
weights[1] += LEARNING_RATE * localError * y[p];
weights[2] += LEARNING_RATE * localError;
globalError += (localError*localError);
}
/* Root Mean Squared Error */
printf("Iteration %d : RMSE = %.4f\n", iteration,
sqrt(globalError/patternCount));
} while (globalError != 0 && iteration<=MAX_ITERATION);
printf("\nDecision boundary (line) equation: %.2f*x + %.2f*y + %.2f = 0\n",
weights[0], weights[1], weights[2]);
return 0;
}
这是我写的代码
<?php
define("LEARNING_RATE", 0.1);
define("MAX_ITERATION", 100);
function randomFloat(){ return (float) mt_rand() / mt_getrandmax(); }
function calculateOutput($weights, $x, $y){
$sum = (float) $x * $weights[0] + $y * $weights[1] + $weights[2];
return ($sum >= 0) ? 1 : -1;
}
srand(time());
$i = 0;
$ars = explode("\n",file_get_contents('https://raw.githubusercontent.com/RichardKnop/ansi-c-perceptron/master/test1.txt'));
foreach($ars as $ar){
$temp = explode("\t", $ar);
$x[$i] = (float) $temp[0];
$y[$i] = (float) $temp[1];
$output[$i] = (int) $temp[2];
if($output[$i] == 0)
$output[$i] = -1;
$i++;
}
$patternCount = $i;
$weights[0] = randomFloat();
$weights[1] = randomFloat();
$weights[2] = randomFloat();
$iteration = 0;
do{
$iteration++;
$globalError = 0;
for ($p = 0; $p < $patternCount; $p++) {
$output = calculateOutput($weights, $x[$p], $y[$p]);
$localError = $outputs[$p] - $output;
$weights[0] += LEARNING_RATE * $localError * $x[$p];
$weights[1] += LEARNING_RATE * $localError * $y[$p];
$weights[2] += LEARNING_RATE * $localError;
$globalError += ($localError*$localError);
}
$r .= "Iteration $iteration : RMSE = " .
sqrt($globalError/$patternCount)."<br>";
}while($globalError != 0 && $iteration<=MAX_ITERATION);
echo $r;
echo "<br><hr><br>";
echo "Decision boundary (line) equation: ".$weights[0]."*x + ".$weights[1]."*y + ".$weights[2]." = 0<br>";
它实际上是相同的,但为什么它不起作用?
解决方案
$ars = explode("\n",file_get_contents('…'));
由于文件以 a 结尾\n
,这会产生一个空字符串作为最后一个数组值,这会破坏foreach($ars as $ar)
循环。要将文件读入数组,只需使用:
$ars = file('…');
在foreach($ars as $ar)
循环中,您使用了错误的名称$output[$i]
而不是$outputs[$i]
.
$r .= "Iteration $iteration : RMSE = " .
sqrt($globalError/$patternCount)."<br>";
}while($globalError != 0 && $iteration<=MAX_ITERATION);
echo $r;
你没有初始化$r
。代替上述方法,您可以使用:
echo "Iteration $iteration : RMSE = " .
sqrt($globalError/$patternCount)."<br>";
} while ($globalError != 0 && $iteration<=MAX_ITERATION);
推荐阅读
- vue.js - 如何在 nuxt 中实现多语言切换?
- javascript - 复杂的对象数组变成简单的对象
- nlp - 清理文本后在命名实体识别任务中保持对齐
- c++ - 按模式制作所有匹配链接
- android - 3路交叉表在房间Android
- css - 如何使用 CSS 在图像的底部和右侧制作形状?
- c++ - __uint128_t 的 std::hash
- powershell - Powershell - 基于广告组的 Azure 许可证
- serialization - 我在哪里可以看到 BinaryFormatter 可以序列化的数据格式?
- python - 是否有一种启发式方法可以从有向图中的特定节点中找到最长的简单循环?