由于课程设计选的题目是基于神经网络的综合评价,利用暑假时间用C#实现的bp神经网络。其中用到的_Matrix类是C#实现的矩阵类http://blog.csdn.net/lanqiuchaoren/article/details/37738665。此bp神经网络包含1个隐藏层,其中输入层,隐藏层,输出层个数都可以根据需要更改。
具体bp神经网络代码如下
BP类:
using Matrix_Mul;
using Excel = Microsoft.Office.Interop.Excel;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Office.Interop.Excel;
namespace BPNETSerial
{
public class BP
{
///
/// 判断是否训练过网络
///
Boolean IsTrained;
///
/// 用于矩阵的相关计算
///
_Matrix_Calc matrix_Calc;
///
/// 输入层节点数
///
int innum;
///
/// 测试数据组数
///
int train_num;
///
/// 训练数据组数
///
int test_num;
public int Test_num
{
get
{
return test_num;
}
set
{
test_num = value;
}
}
///
/// 测试数据维度;
///
int sampdim;
///
/// 隐藏层节点数
///
int midnum;
///
/// 输出层节点数
///
int outnum;
///
/// 迭代次数
///
int iteration;
///
/// 输入层与隐藏层间的权值
///
_Matrix w1;
///
/// 输入层与隐藏层间的阀值
///
_Matrix b1;
///
/// 输出层与隐藏层间的权值
///
_Matrix w2;
///
/// 输出层与隐藏层间的阀值
///
_Matrix b2;
///
/// 保存w1的值
///
_Matrix w1_1;
///
/// 保存w2的值
///
_Matrix w2_1;
///
/// 用于综合评价的矩阵(基于bp神经网络测试结果)
///
_Matrix comprehesiveEvaluationMatrix;
///
/// 综合评价结果输出矩阵(基于bp神经网络测试结果)
///
_Matrix comprehensiveEvaluationResultMatrix;
///
/// 保存b1的值
///
_Matrix b1_1;
///
/// 保存b2的值
///
_Matrix b2_1;
///
/// 学习率
///
double xite;
///
/// 误差
///
double error;
public double[] comprehensiveEvaluation;
double accu_average;
///
/// 误差率
///
double[] accuracy;
///
/// 训练输入数据
///
_Matrix input_train;
public _Matrix Input_train
{
get
{
return input_train;
}
set
{
this.input_train = value;
}
}
///
/// 训练输出数据
///
_Matrix output_train;
public _Matrix Output_train
{
get
{
return output_train;
}
set
{
this.output_train = value;
}
}
///
/// 归一化后的训练输入数据
///
_Matrix input_train_Norm;
///
/// 归一化后的训练输出数据
///
_Matrix output_train_Norm;
///
/// 测试输入数据
///
_Matrix input_test;
public _Matrix Input_test
{
get
{
return input_test;
}
set
{
this.input_test = value;
}
}
///
/// 预期输出数据(归一化前)
///
public _Matrix fore_test;
///
/// 预期输出数据(归一化后)
///
public _Matrix fore;
///
/// 测试输出数据
///
_Matrix output_test;
public _Matrix Output_test
{
get
{
return output_test;
}
set
{
this.output_test = value;
}
}
///
/// 误差矩阵
///
_Matrix error_test;
///
/// 归一化后的测试输入数据
///
_Matrix input_test_Norm;
///
/// 归一化后的测试输出数据
///
_Matrix output_test_Norm;
///
/// 构造函数
///
///
///
///
///
///
///
///
///
public BP(int innum, int midnum, int outnum, int train_num, int sampDim, int iteration, double xite)
{
this.innum = innum;
this.midnum = midnum;
this.outnum = outnum;
this.iteration = iteration;
matrix_Calc = new _Matrix_Calc();
this.train_num = train_num;
this.sampdim = sampDim;
this.xite = xite;
this.input_train = new _Matrix(train_num, sampDim);
input_train.init_matrix();
this.output_train = new _Matrix(train_num, outnum);
output_train.init_matrix();
//初始化w1,w2,b1,b2;
w1 = InitWB(midnum, innum);
w2 = InitWB(midnum, outnum);
b1 = InitWB(midnum, 1);
b2 = InitWB(outnum, 1);
w1_1 = new _Matrix(w1);
b1_1 = new _Matrix(b1);
w2_1 = new _Matrix(w2);
b2_1 = new _Matrix(b2);
}
///
/// 应用与BP训练时的计算,矩阵的每一个值乘上学习率
///
///
///
///
public _Matrix AddStudyRate(_Matrix data, double xite)
{
for (int i = 0; i < data.m; i++)
{
for (int j = 0; j < data.n; j++)
{
data.write(i, j, data.read(i, j) * xite);
}
}
return data;
}
///
/// 归一化
///
///
///
public _Matrix Normalize(_Matrix data) //@_@ to do test
{
_Matrix dat = new _Matrix(data);
for (int i = 0; i < dat.m; i++)
{
double min = 100000.0; double max = -100000.0;
for (int j = 0; j < dat.n; j++)
{
double s = dat.read(i, j);
if (s > max)
{
max = s;
}
else if (s < min)
{
min = s;
}
}
for (int j = 0; j < dat.n; j++)
{
double s = dat.read(i, j);
s = (s - min) / (max - min);
dat.write(i, j, s);
}
}
return dat;
}
///
/// 初始化w1,w2,b1,b2
///
///
///
///
public _Matrix InitWB(int m, int n)
{
_Matrix mat = new _Matrix(m, n);
mat.init_matrix();
Random rand = new Random();
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
double s;
s = (rand.NextDouble() - 0.5) * 2;
mat.write(i, j, s);
}
}
return mat;
}
///
/// 获取矩阵的某一行
///
///
///
///
public _Matrix GetRow(_Matrix data, int kk)
{
_Matrix p = new _Matrix(1, data.n);
p.init_matrix();
for (int i = 0; i < data.n; i++)
{
p.write(0, i, data.read(kk, i));
}
return p;
}
public _Matrix GetColumn(_Matrix data, int kk)
{
_Matrix p = new _Matrix(data.m, 1);
p.init_matrix();
for (int i = 0; i < data.m; i++)
{
p.write(i, 0, data.read(i, kk));
}
return p;
}
public double sumsqr(_Matrix data)
{
double s = 0.0;
for (int i = 0; i < data.m; i++)
{
for (int j = 0; j < data.n; j++)
{
s += data.read(i, j) * data.read(i, j);
}
}
return s;
}
///
/// 训练网络
///
/// 输入矩阵(可以是未归一化的)
/// 期望的输出矩阵(可以是未归一化的)
public void trainBP(_Matrix input_train, _Matrix output_train)
{
this.input_train = input_train;
this.output_train = output_train;
this.input_train_Norm = Normalize(input_train);
this.output_train_Norm = Normalize(output_train);
for (int ii = 0; ii < iteration; ii++)
{
for (int i = 0; i < train_num; i++)
{
var x = GetColumn(input_train_Norm, i);
_Matrix I = new _Matrix(1, midnum);
I.init_matrix();
_Matrix lout = new _Matrix(1, midnum);
lout.init_matrix();
for (int j = 0; j < midnum; j++)
{
_Matrix t = new _Matrix(1, 1);
t.init_matrix();
_Matrix aaa = GetColumn(input_train_Norm, i);
_Matrix tt = matrix_Calc.transposs(aaa);
_Matrix ttt = matrix_Calc.transposs(GetRow(w1, j));
t = matrix_Calc.multiplys(tt, ttt);
I.write(0, j, t.read(0, 0) + b1.read(j, 0));
double s = 1 / (1 + Math.Exp(-I.read(0, j)));
lout.write(0, j, s);
}
_Matrix yn;
_Matrix y = matrix_Calc.transposs(w2);
_Matrix yy = matrix_Calc.transposs(lout);
_Matrix yyy = matrix_Calc.multiplys(y, yy);
yn = matrix_Calc.adds(yyy, b2);
_Matrix e;
e = GetColumn(output_train_Norm, i);
e = matrix_Calc.subtracts(e, yn);
_Matrix dw2;
dw2 = matrix_Calc.multiplys(e, lout);
_Matrix db2 = matrix_Calc.transposs(e);
_Matrix dw1 = new _Matrix(innum, midnum);
dw1.init_matrix();
_Matrix db1 = new _Matrix(1, midnum);
db1.init_matrix();
double[] FI = new double[midnum];
for (int j = 0; j < midnum; j++)
{
double S = 1 / (1 + Math.Exp(-I.read(0, j)));
FI[j] = S;
}
for (int k = 0; k < innum; k++)
{
for (int j = 0; j < midnum; j++)
{
double s = 0.0;
for (int tt = 0; tt < outnum; tt++)
{
s += e.arr[tt] * w2.read(j, tt);
}
dw1.write(k, j, FI[j] * x.read(k, 0) * s);
db1.write(j, 1, FI[j] * s);
}
}
_Matrix sw1 = matrix_Calc.transposs(dw1);
_Matrix sb1 = matrix_Calc.transposs(db1);
_Matrix sw2 = matrix_Calc.transposs(dw2);
_Matrix sb2 = matrix_Calc.transposs(db2);
w1 = matrix_Calc.adds(w1_1, AddStudyRate(sw1, xite));
_Matrix aaaa = AddStudyRate(sb1, xite);
b1 = matrix_Calc.adds(b1_1, aaaa);
w2 = matrix_Calc.adds(w2_1, AddStudyRate(sw2, xite));
b2 = matrix_Calc.adds(b2_1, AddStudyRate(sb2, xite));
w1_1 = new _Matrix(w1);
b1_1 = new _Matrix(b1);
w2_1 = new _Matrix(w2);
b2_1 = new _Matrix(b2);
}
}
}
///
/// 将测试数据代入进行测试
///
/// 测试组的输入数据
/// 测试组的预期输出数据
/// 测试组的组数
public void testBP(_Matrix input_test, _Matrix output_test, int test_num)
{
this.input_test = input_test;
this.output_test = output_test;
this.input_test_Norm = Normalize(input_test);
this.output_test_Norm = Normalize(output_test);
fore_test = new _Matrix(output_test.m, output_test.n);
fore_test.init_matrix();
error_test = new _Matrix(output_test.m, output_test.n);
error_test.init_matrix();
this.test_num = test_num;
for (int i = 0; i < test_num; i++)
{
double[] I = new double[midnum];
_Matrix lout = new _Matrix(1, midnum);
lout.init_matrix();
for (int j = 0; j < midnum; j++)
{
_Matrix s = GetColumn(input_test_Norm, i);
s = matrix_Calc.transposs(s);
_Matrix ss = GetRow(w1, j);
ss = matrix_Calc.transposs(ss);
_Matrix sss = matrix_Calc.multiplys(s, ss);
I[j] = sss.arr[0] + b1.read(j, 0);
lout.write(0, j, 1 / (1 + Math.Exp(-I[j])));
}
_Matrix t = matrix_Calc.transposs(w2);
_Matrix tt = matrix_Calc.transposs(lout);
_Matrix ttt = matrix_Calc.adds(matrix_Calc.multiplys(t, tt), b2);
for (int j = 0; j < fore_test.m; j++)
{
fore_test.write(j, i, ttt.read(j, 0));
}
}
error_test = matrix_Calc.subtracts(fore_test, output_test_Norm);
error = sumsqr(error_test);
Console.WriteLine(error);
}
///
/// 获得综合评价矩阵
///
/// 综合评价矩阵的维度
public void GetComprehensiveEvaluationMatrix(int num)
{
if (output_test_Norm.arr==null)
{
return;
}
output_test_Norm = matrix_Calc.transposs(output_test_Norm);
fore_test = matrix_Calc.transposs(fore_test);
comprehesiveEvaluationMatrix = new _Matrix(output_test_Norm.m,2*num);
comprehesiveEvaluationMatrix.init_matrix();
for (int i = 0; i < comprehesiveEvaluationMatrix.m; i++)
{
comprehesiveEvaluationMatrix.write(i,0,output_test_Norm.read(i,0));
double s = 0.0;
s = output_test_Norm.read(i,1)+output_test_Norm.read(i,2)+output_test_Norm.read(i,3)+output_test_Norm.read(i,4)+output_test_Norm.read(i,5);
s = s / 5;
comprehesiveEvaluationMatrix.write(i, 1, s);
comprehesiveEvaluationMatrix.write(i, 2, output_test_Norm.read(i, 6));
comprehesiveEvaluationMatrix.write(i, 3, output_test_Norm.read(i, 7));
comprehesiveEvaluationMatrix.write(i, 4, fore_test.read(i, 0));
s = fore_test.read(i, 1) + fore_test.read(i, 2) + fore_test.read(i, 3) + fore_test.read(i, 4) + fore_test.read(i, 5);
s = s / 5;
comprehesiveEvaluationMatrix.write(i, 5, s);
comprehesiveEvaluationMatrix.write(i, 6, fore_test.read(i, 6));
comprehesiveEvaluationMatrix.write(i, 7, fore_test.read(i, 7));
}
}
///
/// 进行综合评价,获得综合评价后的结果矩阵
///
/// 各维度权值
/// 评价矩阵
public void ComEvaluation(double [] ComEval)
{
comprehensiveEvaluationResultMatrix = new _Matrix(comprehesiveEvaluationMatrix.m,3);
comprehensiveEvaluationResultMatrix.init_matrix();
_Matrix data = new _Matrix(comprehesiveEvaluationMatrix);
for (int i = 0; i < data.m; i++)
{
double s = 0.0;
for (int j = 0; j < data.n/2; j++)
{
s += ComEval[j] * data.read(i,j);
}
comprehensiveEvaluationResultMatrix.write(i,0,i+1);
comprehensiveEvaluationResultMatrix.write(i,1,s);
s = 0.0;
for (int j = data.n/2; j < data.n; j++)
{
s += ComEval[j-data.n/2] * data.read(i, j);
}
comprehensiveEvaluationResultMatrix.write(i, 2, s);
}
}
///
/// ComEvaResult矩阵写入EXCEL
///
public void ComEvaResult_Excel()
{
if (comprehensiveEvaluationResultMatrix.arr==null)
{
return;
}
var excelApp = new Microsoft.Office.Interop.Excel.Application();
Workbooks workbooks = excelApp.Workbooks;
Workbook workBook = workbooks.Add(Type.Missing);
Worksheet workSheet = (Worksheet)workBook.Worksheets[1];//取得sheet1
for (int i = 1; i <=comprehensiveEvaluationResultMatrix.m; i++)
{
for (int j = 1; j <=comprehensiveEvaluationResultMatrix.n; j++)
{
workSheet.Cells[i, j] = comprehensiveEvaluationResultMatrix.read(i-1,j-1);
}
}
workBook.SaveAs(@"d:\comEvaResult.xlsx", Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Excel.XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
workbooks.Close();
}
///
/// 把求得的W,B,w,b
///
public void WB_Excel()
{
var excelApp = new Microsoft.Office.Interop.Excel.Application();
Workbooks workbooks = excelApp.Workbooks;
Workbook workBook = workbooks.Add(Type.Missing);
Worksheet workSheet = (Worksheet)workBook.Worksheets[1];//取得sheet1
workSheet.Name = "w1";
for (int i = 1; i <= this.w1.m; i++)
{
for (int j = 1; j <= this.w1.n; j++)
{
workSheet.Cells[i, j] = this.w1.read(i - 1, j - 1);
}
}
workBook.Worksheets.Add(Type.Missing,Type.Missing,Type.Missing,Type.Missing);
workSheet = (Worksheet)workBook.Worksheets[1];
workSheet.Name = "b1";
for (int i = 1; i <= this.b1.m; i++)
{
for (int j = 1; j <=b1.n; j++)
{
workSheet.Cells[i, j] = this.b1.read(i-1,j-1);
}
}
workBook.Worksheets.Add(Type.Missing, Type.Missing, Type.Missing, Type.Missing);
workSheet = (Worksheet)workBook.Worksheets[1];
workSheet.Name = "w2";
for (int i = 1; i <= this.w2.m; i++)
{
for (int j = 1; j <= w2.n; j++)
{
workSheet.Cells[i, j] = this.w2.read(i - 1, j - 1);
}
}
workBook.Worksheets.Add(Type.Missing, Type.Missing, Type.Missing, Type.Missing);
workSheet = (Worksheet)workBook.Worksheets[1];
workSheet.Name = "b2";
for (int i = 1; i <= this.b2.m; i++)
{
for (int j = 1; j <= b2.n; j++)
{
workSheet.Cells[i, j] = this.b2.read(i - 1, j - 1);
}
}
workBook.SaveAs(@"d:\saveWB.xlsx", Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Excel.XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
workbooks.Close();
}
///
/// 输出结果写入Excel
///
public void output_Excel()
{
var excelApp = new Microsoft.Office.Interop.Excel.Application();
Workbooks workbooks = excelApp.Workbooks;
Workbook workBook = workbooks.Add(Type.Missing);
Worksheet workSheet = (Worksheet)workBook.Worksheets[1];//取得sheet1
for (int j = 1; j < 9; j++)
workSheet.Cells[1, j] = accuracy[j - 1];
workSheet.Cells[2, 1] = accu_average;
workBook.SaveAs(@"d:\result.xlsx", Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Excel.XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
workbooks.Close();
}
///
/// 反归一化获得输出结果
///
public void ConvNorm()
{
fore = matrix_Calc.transposs(this.fore_test);
_Matrix output = matrix_Calc.transposs(this.Output_train);
for (int i = 0; i < output.n; i++)
{
double max = -100000.0; double min = 100000.0;
for (int j = 0; j < output.m; j++)
{
if (max < output.read(j, i))
{
max = output.read(j, i);
}
else if (min > output.read(j, i))
{
min = output.read(j, i);
}
}
for (int j = 0; j < fore.m; j++)
{
double s = (max - min) * fore.read(j, i) + min;
fore.write(j, i, s);
}
}
}
public void CalcAccuracy()
{
accuracy = new double[outnum];
_Matrix output = matrix_Calc.transposs(output_train);
accu_average = 0.0;
for (int i = 0; i < outnum; i++)
{
double accu = 0.0;
for (int j = 0; j < test_num; j++)
{
accu += Math.Abs(fore.read(j, i) - output.read(j, i)) / output.read(j, i);
accu_average += Math.Abs(fore.read(j, i) - output.read(j, i)) / output.read(j, i);
}
accuracy[i] = accu / 180;
accu_average = accu_average / (outnum) / (test_num);
}
}
}
}
using NPOI.HSSF.UserModel;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Matrix_Mul;
using Excel=Microsoft.Office.Interop.Excel;
using System.Reflection;
namespace BPNETSerial
{
class Program
{
static void Main(string[] args)
{
//初始化bp神经网络
BP bp = new BP(9,15,8,1620,9,300,0.2);
//创建一个mat来便于对_Matrix类进行计算
_Matrix_Calc mat = new _Matrix_Calc();
using (FileStream stream = new FileStream(@"train.xls", FileMode.Open, FileAccess.Read))
{
HSSFWorkbook Workbook = new HSSFWorkbook(stream);
var Sheet = Workbook.GetSheetAt(0);
int j = 0;
for (int i = 1; i < 1621; i++)
{
var row = Sheet.GetRow(i);
for (int k = 0; k < row.Cells.Count; k++)
{
bp.Input_train.arr[j++] = row.GetCell(k).NumericCellValue;
}
}
}
using (FileStream stream = new FileStream(@"train.xls", FileMode.Open, FileAccess.Read))
{
HSSFWorkbook Workbook = new HSSFWorkbook(stream);
var Sheet = Workbook.GetSheetAt(1);
int j = 0;
for (int i = 1; i < 1621; i++)
{
var row = Sheet.GetRow(i);
for (int k = 0; k < row.Cells.Count; k++)
{
bp.Output_train.arr[j++] = row.GetCell(k).NumericCellValue;
}
}
}
using (FileStream stream = new FileStream(@"train.xls", FileMode.Open, FileAccess.Read))
{
bp.Test_num = 180;
bp.Input_test = new _Matrix(180,9);
bp.Input_test.init_matrix();
HSSFWorkbook Workbook = new HSSFWorkbook(stream);
var Sheet = Workbook.GetSheetAt(2);
int j = 0;
for (int i = 1; i < 181; i++)
{
var row = Sheet.GetRow(i);
for (int k = 0; k < row.Cells.Count; k++)
{
bp.Input_test.arr[j++] = row.GetCell(k).NumericCellValue;
}
}
}
using (FileStream stream = new FileStream(@"train.xls", FileMode.Open, FileAccess.Read))
{
bp.Output_test = new _Matrix(180, 8);
bp.Output_test.init_matrix();
HSSFWorkbook Workbook = new HSSFWorkbook(stream);
var Sheet = Workbook.GetSheetAt(3);
int j = 0;
for (int i = 1; i < 181; i++)
{
var row = Sheet.GetRow(i);
for (int k = 0; k < row.Cells.Count; k++)
{
bp.Output_test.arr[j++] = row.GetCell(k).NumericCellValue;
}
}
}
bp.Input_train = mat.transposs(bp.Input_train);
_Matrix Output_train = new _Matrix(bp.Output_train);
bp.Output_train = mat.transposs(bp.Output_train);
bp.Input_test = mat.transposs(bp.Input_test);
bp.Output_test = mat.transposs(bp.Output_test);
bp.trainBP(bp.Input_train,bp.Output_train);
bp.testBP(bp.Input_test,bp.Output_test,180);
//以下的代码均是为了测试网络准确度和实现综合评价所写
//bp.ConvNorm();
//bp.CalcAccuracy();
//bp.GetComprehensiveEvaluationMatrix(4);
//bp.comprehensiveEvaluation = new double[4] {0.3309,0.2201,0.2696,0.1793 };
//bp.ComEvaluation(bp.comprehensiveEvaluation);
//bp.ComEvaResult_Excel();
//bp.WB_Excel();
//bp.output_Excel();
}
}
}
其中数据来自来自Minifab(
Minifab是针对Intel公司的半导体生产线提炼出的用于研究的调度仿真模型,在机器数和加工步数都较少的情况下,能够反映半导体生产线的一些本质问题,满足研究的需要。)
训练输入数据是1620组9维数据,输出是1620组8维数据;测试输入数据为180组9维数据,输出是180组8维数据;训练后总误差为3.4%项目源代码:http://download.csdn.net/detail/lanqiuchaoren/7628945