PHP代码部分
PHP矩阵运算:https://blog.csdn.net/FURYZGT/article/details/135008362
以10组历史数据进行模型训练,预测未来时段38组电流数据。输入为辐照度与辐照度的测量时间点,输出为光伏组件的电流值。隐含层为一层,隐含层节点数为4。
实际中需要有大量数据进行模型训练,需要数据导入,以下为手动输入少量数据进行测试。
注:应当将数据进行归一化处理,不然激活函数计算会溢出。
<?php
// 引入矩阵运算文件
include 'matrixOperation/matrixOperation.php';
/*****************************************************************/
/****************************初始化输入数据************************/
// 设置输入层节点数
$inputLayerNodes = 2;
// 设置隐含层节点数
$hiddenLayerNodes = 4;
// 设置输出层节点数
const outputLayerNodes = 1;
// 设置训练次数
$trainingFrequency = 1000000;
// 定义学习率
$learn = 1;
// 定义模型训练输入矩阵(辐照度,温度,时间点)
// $input = array(
// array(0.4444,0.9821,0.92205),
// array(0.4464,0.9947,0.92230),
// array(0.4489,1.0092,0.92300),
// array(0.4517,1.041,0.92330),
// array(0.454991,1.0683,0.92400),
// array(0.459205,1.0958,0.92430),
// array(0.464524,1.1207,0.92501),
// array(0.467022,1.1483,0.92531),
// array(0.471104,1.1763,0.92600),
// array(0.472096,1.2068,0.92630));
// 定义模型训练输入矩阵(辐照度,时间点)
$input = array(
array(0.4444,0.92205),
array(0.4464,0.92230),
array(0.4489,0.92300),
array(0.4517,0.92330),
array(0.454991,0.92400),
array(0.459205,0.92430),
array(0.464524,0.92501),
array(0.467022,0.92531),
array(0.471104,0.92600),
array(0.472096,0.92630));
// 定义模型训练期望输出矩阵(电流值)
$output = array(
array(0.3551),
array(0.3559),
array(0.3583),
array(0.3609),
array(0.3631),
array(0.3649),
array(0.3692),
array(0.3695),
array(0.3735),
array(0.3741));
/*****************************************************************/
/***********************初始化权重W相关数据*************************/
// 定义初始权重矩阵W
$W = array(array());
for($i=0;$i<$inputLayerNodes;$i++)
{
for($j=0;$j<$hiddenLayerNodes;$j++)
{
$W[$i][$j] = rand(1,10)/10;
}
}
// 定义权重W的学习率矩阵
$learnW = array(array());
// 定义权重W的平均值乘数
$averageW = array(array());
// 定义权重W对应的负数矩阵
$negativeW = array(array());
// 定义权重W对应的倍数矩阵
$multipleW = array(array());
for($i=0;$i<count($W);$i++)
{
for($j=0;$j<count($W[0]);$j++)
{
$learnW[$i][$j] = $learn;
$averageW[$i][$j] = 1/count($output);
$negativeW[$i][$j] = -1;
$multipleW[$i][$j] = 2;
}
}
/*****************************************************************/
/***********************初始化权重V相关数据*************************/
// 定义初始权重V
$V = array(array());
for($i=0;$i<$hiddenLayerNodes;$i++)
{
for($j=0;$j<outputLayerNodes;$j++)
{
$V[$i][$j] = rand(1,10)/10;
}
}
// 定义权重V的学习率矩阵
$learnV = array(array());
// 定义权重V调整量对应的负数矩阵
$negativeV = array(array());
// 定义权重V对应的倍数矩阵
$multipleV = array(array());
for($i=0;$i<count($output);$i++)
{
$negativeV[$i][0] = -1;
}
for($i=0;$i<count($V);$i++)
{
$learnV[$i][0] = $learn;
$multipleV[$i][0] = 2;
}
/*****************************************************************/
/***********************初始化偏置N相关数据*************************/
// 定义初始偏置N
$N = array(array());
// 定义偏置N的学习率
$learnN = array(array());
// 定义偏置N调整量对应的负数矩阵
$negativeN = array(array());
// 定义偏置N对应的倍数
$multipleN = 2;
for($i=0;$i<outputLayerNodes;$i++)
{
$N[$i][0] = rand(1,10)/10;
$learnN[$i][0] = $learn;
$negativeN[$i][0] = -1;
}
/*****************************************************************/
/***************************其他数据初始化*************************/
// 定义初始偏置B
$B = array(array());
// 定义偏置B的学习率
$learnB = array(array());
// 定义偏置B的负数矩阵
$negativeB = array(array());
// 定义偏置B对应的倍数矩阵
$multipleB = array(array());
for($i=0;$i<count($V);$i++)
{
$B[$i][0] = rand(1,10)/10;
$learnB[$i][0] = $learn;
$negativeB[$i][0] = -1;
$multipleB[$i][0] = 2;
}
/*****************************************************************/
/***********************初始化偏置B相关数据*************************/
// 定义输出层单位列向量
$I = array(array());
for($i=0;$i<count($output);$i++)
{
$I[$i][0] = 1;
}
// 定义隐含层的线性输出矩阵
$linear_output_implication = array(array());
$sigmoid_implication_output = array(array());
/****************************************************************************/
/**********************************神经网络的运算*****************************/
for($s=0;$s<$trainingFrequency;$s++)
{
/****************************************************************************/
/********************神经网络的前向运算(隐含层前向运算)***********************/
// BP神经网络隐含层偏置矩阵B
$implicationB = array(array());
for($i=0;$i<count($output);$i++)
{
for($j=0;$j<count($V);$j++)
{
$implicationB[$i][$j] = $B[$j][0];
}
}
$linear_output_implication = Matrix_addition(Matrix_cross_product($input,$W),$implicationB);
// 定义隐含层单位矩阵
$hiddenLayerI = array(array());
// 隐含层的PB神经网络sigmoid输出矩阵
for($i=0;$i<count($linear_output_implication);$i++)
{
for($j=0;$j<count($linear_output_implication[0]);$j++)
{
$sigmoid_implication_output[$i][$j] = 1/(1+exp(-$linear_output_implication[$i][$j]));
$hiddenLayerI[$i][$j] = 1;
}
}
// 定义权重V的平均值乘数矩阵
$averageV = array(array());
for($i=0;$i<count($sigmoid_implication_output[0]);$i++)
{
$averageV[$i][0] = 1/count($output);
}
/****************************************************************************/
/********************神经网络的前向运算(输出层前向运算)***********************/
// BP神经网络隐含层偏置矩阵N
$outputN = array(array());
for($i=0;$i<count($output);$i++)
{
$outputN[$i][0] = $N[0][0];
}
// 输出层的BP神经网络线性输出矩阵
$linear_output = Matrix_addition(Matrix_cross_product($sigmoid_implication_output,$V),$outputN);
// 输出层的PB神经网络sigmoid输出矩阵
for($k=0;$k<count($linear_output);$k++)
{
for($l=0;$l<count($linear_output[0]);$l++)
{
$sigmoid_output[$k][$l] = 1/(1+exp(-$linear_output[$k][$l]));
}
}
/****************************************************************************/
/*******************************神经网络的反向运算*****************************/
// 权重V的变化量:DV = 2(预测值-真实值)*预测值*(1-预测值)*隐含层sigmoid输出
$DVS = Matrix_dot_multiplication(
Matrix_dot_multiplication(
Matrix_dot_multiplication(
Matrix_subtraction($sigmoid_output,$output),$sigmoid_output),Matrix_subtraction($I,$sigmoid_output)),$sigmoid_implication_output);
$DV = array(array());
for($i=0;$i<count($V);$i++)
{
$DV[$i][0] = 0;
}
for($i=0;$i<count($DVS[0]);$i++)
{
for($j=0;$j<count($DVS);$j++)
{
$DV[$i][0] = $DV[$i][0] + $DVS[$j][$i];
}
}
$DV = Matrix_dot_multiplication(Matrix_dot_multiplication(Matrix_dot_multiplication($DV,$averageV),$multipleV),$learnV);
$V = Matrix_subtraction($V,$DV);
/****************************************************************************/
/*******************************神经网络的反向运算*****************************/
// 偏置N的变化量:DN = 2(预测值-真实值)*预测值*(1-预测值)
$avgN = 0;
$DN = Matrix_dot_multiplication(Matrix_dot_multiplication(Matrix_subtraction($sigmoid_output,$output),$sigmoid_output),Matrix_subtraction($I,$sigmoid_output));
for($i=0;$i<count($output);$i++)
{
$avgN = $avgN + $DN[$i][0];
}
$avgN = $avgN/count($output);
$N[0][0] = $N[0][0] - $multipleN*$avgN*$learn;
/****************************************************************************/
/*******************************神经网络的反向运算*****************************/
// 权重W的变化量:DW(ij) =
// 2(预测值 - 真实值) * 预测值 * (1-预测值)
// * 隐含层权重V(j)
// * 隐含层输出sigmoid_implication_output(j)
// * (1-隐含层输出sigmoid_implication_output(j))
// * 输入量input(i)
$A = Matrix_dot_multiplication(Matrix_dot_multiplication(Matrix_subtraction($sigmoid_output,$output),$sigmoid_output),Matrix_subtraction($I,$sigmoid_output));
$BB = Matrix_dot_multiplication(Matrix_dot_multiplication($V,Matrix_transpose($sigmoid_implication_output)),Matrix_subtraction(Matrix_transpose($hiddenLayerI),Matrix_transpose($sigmoid_implication_output)));
$C = Matrix_dot_multiplication($A,Matrix_transpose($BB));
$DW = array(array());
for($i=0;$i<count($W);$i++)
{
for($j=0;$j<count($W[0]);$j++)
{
$DW[$i][$j] = 0;
}
}
for($i=0;$i<count($input);$i++)
{
for($j=0;$j<count($input[0]);$j++)
{
for($k=0;$k<count($C[0]);$k++)
{
$DW[$j][$k] = $DW[$j][$k] + $input[$i][$j]*$C[$i][$k];
}
}
}
$DW = Matrix_dot_multiplication(Matrix_dot_multiplication(Matrix_dot_multiplication($DW,$averageW),$multipleW),$learnW);
$W = Matrix_subtraction($W,$DW);
/****************************************************************************/
/*******************************神经网络的反向运算*****************************/
// 偏置B的变化量:DB =
// 2(预测值 - 真实值) * 预测值 * (1-预测值)
// * 隐含层权重V(j)
// * 隐含层输出sigmoid_implication_output(j)
// * (1-隐含层输出sigmoid_implication_output(j))
$D = Matrix_dot_multiplication(Matrix_dot_multiplication(Matrix_subtraction($sigmoid_output,$output),$sigmoid_output),Matrix_subtraction($I,$sigmoid_output));
$E = Matrix_dot_multiplication(Matrix_dot_multiplication($V,Matrix_transpose($sigmoid_implication_output)),Matrix_subtraction(Matrix_transpose($hiddenLayerI),Matrix_transpose($sigmoid_implication_output)));
$F = Matrix_dot_multiplication($D,Matrix_transpose($E));
$DBS = array(array());
for($i=0;$i<count($V);$i++)
{
$DBS[$i][0] = 0;
}
$avgB = array(array());
for($i=0;$i<count($V);$i++)
{
$avgB[$i][0] = 1/count($output);
}
for($i=0;$i<count($F[0]);$i++)
{
for($j=0;$j<count($F);$j++)
{
$DBS[$i][0] = $DBS[$i][0] + $F[$j][$i];
}
}
$DB = Matrix_dot_multiplication(Matrix_dot_multiplication(Matrix_dot_multiplication($DBS,$avgB),$multipleB),$learnB);
$B = Matrix_subtraction($B,$DB);
}
/****************************************************************************/
/********************************神经网络预测数据*****************************/
// 数据输入(辐照度,温度,时间点)
// $productive = array(
// array(0.474142,1.2191,0.92700),
// array(0.478633,1.2309,0.92730),
// array(0.481854,1.2437,0.92800),
// array(0.485597,1.2776,0.92830),
// array(0.488798,1.2907,0.92900),
// array(0.491006,1.3293,0.92930),
// array(0.493468,1.3355,0.93000),
// array(0.497063,1.3661,0.93030),
// array(0.499797,1.3731,0.93100),
// array(0.501473,1.3675,0.93130),
// array(0.504012,1.4086,0.93200),
// array(0.506765,1.431,0.93230),
// array(0.509593,1.4539,0.93300),
// array(0.513532,1.4666,0.93330),
// array(0.514743,1.4963,0.93400),
// array(0.515494,1.4991,0.93430),
// array(0.516827,1.4895,0.93500),
// array(0.519071,1.5333,0.93530),
// array(0.519362,1.5516,0.93600),
// array(0.522301,1.5583,0.93630),
// array(0.527086,1.5562,0.93700),
// array(0.237792,1.5835,0.93730),
// array(0.513545,1.6001,0.93800),
// array(0.609365,1.6253,0.93830),
// array(0.52686,1.6752,0.93930),
// array(0.527433,1.6808,0.94000),
// array(0.528413,1.6652,0.94030),
// array(0.530072,1.6719,0.94100),
// array(0.531925,1.6853,0.94130),
// array(0.533353,1.6711,0.94200),
// array(0.537223,1.6674,0.94230),
// array(0.539114,1.6813,0.94300),
// array(0.538837,1.6978,0.94330),
// array(0.541224,1.7254,0.94400),
// array(0.543783,1.7191,0.94430),
// array(0.547884,1.7356,0.94500),
// array(0.550122,1.7279,0.94530),
// array(0.553295,1.7594,0.94600),
// array(0.556807,1.7582,0.94630),
// array(0.557816,1.7626,0.94700));
$productive = array(
array(0.474142,0.92700),
array(0.478633,0.92730),
array(0.481854,0.92800),
array(0.485597,0.92830),
array(0.488798,0.92900),
array(0.491006,0.92930),
array(0.493468,0.93000),
array(0.497063,0.93030),
array(0.499797,0.93100),
array(0.501473,0.93130),
array(0.504012,0.93200),
array(0.506765,0.93230),
array(0.509593,0.93300),
array(0.513532,0.93330),
array(0.514743,0.93400),
array(0.515494,0.93430),
array(0.516827,0.93500),
array(0.519071,0.93530),
array(0.519362,0.93600),
array(0.522301,0.93630),
array(0.527086,0.93700),
array(0.513545,0.93800),
array(0.609365,0.93830),
array(0.52686,0.93930),
array(0.527433,0.94000),
array(0.528413,0.94030),
array(0.530072,0.94100),
array(0.531925,0.94130),
array(0.533353,0.94200),
array(0.537223,0.94230),
array(0.539114,0.94300),
array(0.538837,0.94330),
array(0.541224,0.94400),
array(0.543783,0.94430),
array(0.547884,0.94500),
array(0.550122,0.94530),
array(0.553295,0.94600),
array(0.556807,0.94630),
array(0.557816,0.94700));
/****************************************************************************/
/********************神经网络的前向运算(隐含层前向运算)***********************/
// 隐含层的BP神经网络线性输出矩阵
$productive_linear_output_implication = array(array());
// BP神经网络隐含层偏置矩阵B
$predictionImplicationB = array(array());
for($i=0;$i<count($productive);$i++)
{
for($j=0;$j<count($V);$j++)
{
$predictionImplicationB[$i][$j] = $B[$j][0];
}
}
$productive_linear_output_implication = Matrix_addition(Matrix_cross_product($productive,$W),$predictionImplicationB);
// PB神经网络隐含层sigmoid输出矩阵
for($i=0;$i<count($productive_linear_output_implication);$i++)
{
for($j=0;$j<count($productive_linear_output_implication[0]);$j++)
{
$productive_sigmoid_implication_output[$i][$j] = 1/(1+exp(-$productive_linear_output_implication[$i][$j]));
}
}
/****************************************************************************/
/********************神经网络的前向运算(输出层前向运算)***********************/
// BP神经网络隐含层偏置矩阵N
$predictionOutputN = array(array());
for($i=0;$i<count($productive);$i++)
{
$predictionOutputN[$i][0] = $N[0][0];
}
// BP神经网络输出层的线性输出矩阵
$productive_linear_output = Matrix_addition(Matrix_cross_product($productive_sigmoid_implication_output,$V),$predictionOutputN);
// PB神经网络输出层的sigmoid输出矩阵
for($i=0;$i<count($productive_linear_output);$i++)
{
for($j=0;$j<count($productive_linear_output[0]);$j++)
{
$productive_sigmoid_output[$i][$j] = 1/(1+exp(-$productive_linear_output[$i][$j]));
}
}
/****************************************************************************/
/*******************************预测结果输出**********************************/
for($i=0;$i<count($productive_sigmoid_output);$i++)
{
echo $productive[$i][1].'时间点的电流值:';
var_dump(round($productive_sigmoid_output[$i][0]*10,3));
echo '<br>';
}
?>
预测结果:
以下分别是隐含层神经元节点为3、4、5、6时的预测结果。可见,当隐含层神经元节点为4时,预测效果最佳,其相较于真实值,平均误差率为1.24%、最大误差率为3.34%、最小误差率为0%。