作者:桂子山下一棵草 email: slowguy@qq.com
题目:
表一: 澳大利亚野兔眼睛晶状体重量与年龄的对应关系
编号
|
年龄(天)
|
重量(mg)
|
年龄(天)
|
重量(mg)
|
年龄(天)
|
重量(mg)
|
年龄(天)
|
重量(mg)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
15
15
15
18
28
29
37
37
44
50
50
60
61
64
65
65
72
75
|
21.66
22.75
22.3
31.25
44.79
40.55
50.25
46.88
52.03
63.47
61.13
81
73.09
79.09
79.51
65.31
71.9
86.1
|
75
82
85
91
91
97
98
125
142
142
147
147
150
159
165
183
192
195
|
94.6
92.5
105
101.7
102.9
110
104.3
134.9
130.68
140.58
155.3
152.2
144.5
142.15
139.81
153.22
145.72
161.1
|
218
218
219
224
225
227
232
232
237
246
258
276
285
300
301
305
312
317
|
174.18
173.03
173.54
178.86
177.68
173.73
159.98
161.29
187.07
176.13
183.4
186.26
189.66
186.09
186.7
186.8
195.1
216.41
|
338
347
354
357
375
394
513
535
554
591
648
660
705
723
756
768
860
|
203.23
188.38
189.7
195.31
202.63
224.82
203.3
209.7
233.9
234.7
244.3
231
242.4
230.77
242.57
232.12
246.7
|
澳大利亚野兔眼睛晶状体的重量为年龄的函数。利用BP算法,设计一个多层感知器,为表中的数据集提供一个非线性逼近,并测试其泛化能力。
算法源码:
package com.lwm.cn.althom;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Random;
public class BackProp {
private int randomPrecision = 8; // 生成double型随机数的精度,默认为6位小数
private int input_dimension; // 输入向量的维度
private int output_dimension; // 输出向量的维数
private int mid_dimension; // 隐层结点的个数
private double[][] V; // 输入层到隐层的权值矩阵
private double[][] W; // 隐层到输出层的权值矩阵
private double[] inputArray; // 输入层向量
private double[] midArray; // 隐层输出向量
private double[] outputArray; // 输出层向量
private double[] teacherArray; // 期望层向量
private double mid_Threshold; // 隐层阈值
private double out_Threshold; // 输出层阈值
private double[] midError; // 隐层的误差
private double[] outError; // 输出层的误差
private double totalError = 0.0;
private double outPrecision; // 要达到的精度
private double learnRate; // 学习的速率
private int trainTotal = 3000; // 学习1000次
private boolean isQualify = false; // 用于判断是不是达到精度要求
private ArrayList<SampleNode> trainArray = new ArrayList<SampleNode>(100); // 存入训练集
private ArrayList<SampleNode> testArray = new ArrayList<SampleNode>(100); // 存放测试集
private BufferedWriter bw = null; // 用于将学习和测试过程写于文件
Date startTime;
// SampleNode sample;
// Math.random()
public BackProp(double[][] v, double[][] w, int input_dimension,
int output_dimension, int mid_dimension) {
super();
V = v;
W = w;
this.input_dimension = input_dimension;
this.output_dimension = output_dimension;
this.mid_dimension = mid_dimension;
}
/**
* 默认构造函数 ,对于本次实验,输入向量只有一个,输出也只有一个. 隐层结点的个数默认为4
*
*/
public BackProp() {
input_dimension = 1;
output_dimension = 1;
mid_dimension = 8;
inputArray = new double[input_dimension];
teacherArray = new double[output_dimension];
midArray = new double[mid_dimension];
outputArray = new double[output_dimension];
V = new double[input_dimension][mid_dimension];
W = new double[mid_dimension][input_dimension];
midError = new double[mid_dimension];
outError = new double[output_dimension];
}
/**
* 初始化函数 我认为一个完整的BP算法应该具备通用性,可以任意设置输入结点个数和隐层的层数及每一层的结点个数
* 初始化权值矩阵V和W,每个元素的值均为0-1之间的六位小数
*/
public void init()
{
// 记录程序开始时间及结束时间,以开始时间命名一个文件,用来保存学习和测试结果.
startTime = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒");
String timeStr = sdf.format(startTime);
String filePathName = "E:" + File.separator + timeStr + ".txt";
try
{
bw = new BufferedWriter(new FileWriter(filePathName));
bw.write("程序开始时间:" + timeStr + "\n");
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
mid_Threshold = MathExtend.round(Math.random(), randomPrecision); // 初始化隐层的阈值
out_Threshold = MathExtend.round(Math.random(), randomPrecision); // 初始化输出层的阈值
// 初始化V矩阵
for (int i = 0; i < input_dimension; i++)
for (int j = 0; j < mid_dimension; j++)
V[i][j] = MathExtend.round(Math.random(), randomPrecision);
// 初始化W矩阵
for (int i = 0; i < mid_dimension; i++)
for (int j = 0; j < output_dimension; j++)
W[i][j] = MathExtend.round(Math.random(), randomPrecision);
// 置总的误差为0,学习率为0-1之间的小数,网络训练后达到的精度为一正小数
totalError = 0.0;
learnRate = MathExtend.round(Math.random(), randomPrecision);
// learnRate = 0.12;
outPrecision = MathExtend.round(Math.random(), randomPrecision);
try
{
StringBuilder sb = new StringBuilder();
sb.append("本次实验随机生成的学习率: " + learnRate);
sb.append("\n");
sb.append("期望达到的精度为: " + outPrecision);
sb.append("\n");
bw.write(sb.toString());
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
getTrainData(); // 取得训练集
getTestData(); // 取得测试集
normalized(); // 归一化
}
/**
* @author Administrator 输入层向隐层,隐层向输出层的传播
*
*/
public void finish()
{
// Date endDate = new Date() ;
try
{
bw.close();
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void forword()
{
int i, j;
double temp_sum ; // 用于向量的内积
// 输出层到隐层
for (i = 0; i < mid_dimension; i++)
{
temp_sum = 0.0 ; //初始化为0
for (j = 0; j < input_dimension; j++)
temp_sum += V[j][i] * inputArray[j];
temp_sum = temp_sum - mid_Threshold;
midArray[i] = 1.0 / (1 + Math.exp(-temp_sum));
}
// 隐层到输出层
for (i = 0; i < output_dimension; i++)
{
temp_sum = 0.0; // 初始化
for (j = 0; j < mid_dimension; j++)
temp_sum = W[j][i] * midArray[j];
temp_sum = temp_sum - out_Threshold;
outputArray[i] = 1.0 / (1 + Math.exp(-temp_sum));
}
// 计算误差,累加起来,
temp_sum = 0.0;
for (i = 0; i < output_dimension; i++)
{
temp_sum = teacherArray[i] - outputArray[i]; // 注意中,本设计中output_dimension=1的
totalError += temp_sum * temp_sum / 2;
}
// printResult();
}
private void printResult()
{
/*
* StringBuilder sb = new StringBuilder() ;
* sb.append("输入数据:"+inputArray[0]); sb.append("
* 实际输出数据:"+outputArray[0]); sb.append(" 期望输出数据为:"+teacherArray[0]) ;
* sb.append("\\n") ; try { bw.write(sb.toString()); } catch
* (IOException e) { // TODO Auto-generated catch block
* e.printStackTrace(); }
*/
System.out.print("输入数据:" + inputArray[0]);
System.out.print(" 实际输出数据:" + outputArray[0]);
System.out.println(" 期望输出数据为:" + teacherArray[0]);
}
/**
* 反向调整权值矩阵
*/
public void adjustWeight()
{
double temp_sum = 0.0;
int i, j;
// 计算各层的误差信号 输出层
for (i = 0; i < output_dimension; i++)
{
outError[i] = (teacherArray[i] - outputArray[i])
* (1 - outputArray[i]) * outputArray[i];
}
// 隐层误差
for (i = 0; i < mid_dimension; i++)
{
temp_sum=0.0d ;
for (j = 0; j < output_dimension; j++)
temp_sum += outError[j] * W[i][j];
midError[i] = temp_sum * (1 - midArray[i]) * midArray[i];
}
// 调整W权值矩阵
for (i = 0; i < mid_dimension; i++)
{
for (j = 0; j < output_dimension; j++)
W[i][j] += learnRate * outError[j] * midArray[i];
}
// 调整V权值矩阵
for (i = 0; i < input_dimension; i++)
for (j = 0; j < mid_dimension; j++)
V[i][j] += learnRate * midError[j] * inputArray[i];
}
public void getTrainData()
{
String filePathName = "E:" + File.separator + "traindata.txt";
BufferedReader br = null;
try
{
br = new BufferedReader(new FileReader(filePathName));
} catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
String s = null;
SampleNode sNode = null;
try
{
while ((s = br.readLine()) != null)
{
String data[] = s.trim().split("[\\s]+");
if (data == null || data.length != 2)
{
System.out.println("traindata文件数据有问题!");
return;
}
double in = Double.parseDouble(data[0]);
double hope = Double.parseDouble(data[1]);
sNode = new SampleNode(in, hope);
trainArray.add(sNode);
// trainArray.
}
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
trainArray.trimToSize();
}
public void getTestData()
{
String fileName = "E:" + File.separator + "testdata.txt";
BufferedReader br = null;
try
{
br = new BufferedReader(new FileReader(fileName));
} catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
System.out.println("testdata.txt文件不存在");
e.printStackTrace();
}
String s = null;
SampleNode sNode = null;
try
{
while ((s = br.readLine()) != null)
{
String data[] = s.trim().split("[\\s]+");
if (data == null || data.length != 2)
{
System.out.println("testdata文件数据有问题!");
return;
}
double in = Double.parseDouble(data[0]);
double hope = Double.parseDouble(data[1]);
sNode = new SampleNode(in, hope);
testArray.add(sNode);
// trainArray.
}
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
testArray.trimToSize();
}
/**
* 对输入数据进行归一化处理,将输入数据限制在[0,1]区间内
*
*/
private void normalized()
{
if (trainArray == null || trainArray.size() == 0 || testArray == null
|| testArray.size() == 0)
{
System.out.println("测试数据或者训练数据有问题!");
return;
}
SampleNode sNode = null;
// 训练数据归一化
int size = trainArray.size();
int i = 0;
while (i < size)
{
sNode = trainArray.get(i);
double in = sNode.in;
double hope = sNode.hope;
in /= 1000.0; // 归一
hope /= 250.0;
sNode.in = in;
sNode.hope = hope;
trainArray.set(i, sNode);
i++;
}
size = testArray.size();
i = 0;
// 测试数据归一化
while (i < size)
{
sNode = testArray.get(i);
double in = sNode.in;
double hope = sNode.hope;
in /= 1000.0; // 归一
hope /= 250.0;
sNode.in = in;
sNode.hope = hope;
trainArray.set(i, sNode);
i++;
}
}
public void startTrain()
{
if (trainArray == null || trainArray.size() == 0)
return;
System.out.println("训练开始");
System.out.println("当前学习速率:" + learnRate);
System.out.println("期望精度为:" + outPrecision);
int trainConunter = 0;
while (trainConunter++ < trainTotal)
{
System.out.println("第" + trainConunter + "次训练开始:");
for (SampleNode sNode : trainArray)
{
// 说明:在本设计中inputArray,和teacherArray虽然都是数组,但均只有一个元素.
// 本人为了综合虑,才将设为数组的.
inputArray[0] = sNode.in;
teacherArray[0] = sNode.hope;
forword(); // 学习一次
printResult();
} // 至此,所有训练集全部学习完毕,下面应该进行权值调整.
/*System.out.println("此次学习后,总的误差为:" + totalError);
StringBuilder sb = new StringBuilder();
sb.append("第" + trainConunter);
sb.append("次学习后,总的误差为:" + totalError);
sb.append("\n");*/
try
{
// bw.write(sb.toString());
bw.write(Double.toString(totalError)+"\n") ;
} catch (IOException e)
{
e.printStackTrace();
}
adjustWeight(); // 集体主义原则来调整权值
if (totalError <= outPrecision)
{
isQualify = true; // 置标志位为真,表示达到要求
break;
}
totalError = 0.0; // 误差初化
}
Date endTime = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒");
String endtimeStr = sdf.format(endTime);
long gap = endTime.getTime() - this.startTime.getTime();
StringBuilder sb = new StringBuilder();
try
{
sb.append("训练结束时间为:" + endtimeStr);
sb.append("\n");
sb.append("总的学习时间为:" + gap);
sb.append("微秒\n");
sb.append("********************************************\n");
bw.write(sb.toString());
} catch (IOException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
if (!isQualify)
{
System.out.println("达到训练次数,训练结束!");
try
{
bw.write("训练次数:" + trainTotal + "次\n");
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
} else
{
try
{
bw.write("达到精度要求,学习完毕!\n");
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("达到要求的精度,训练结束!");
}
}
public void startTest()
{
if (testArray == null || testArray.isEmpty() == true)
return;
for (SampleNode sNode : testArray)
{
StringBuilder sb = new StringBuilder();
inputArray[0] = sNode.in;
teacherArray[0] = sNode.hope;
forword();
sb.append("输入测试数据: " + inputArray[0]);
sb.append(" 实际输出:" + outputArray[0]);
sb.append(" 期望输出:" + teacherArray[0]);
sb.append("\n");
try
{
bw.write(sb.toString());
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
printResult();
}
}
}
测试输出结果如下图:
程序运行一次的收敛图如下图:
<!--EndFragment-->
- 大小: 187.8 KB
- 大小: 3.8 KB
分享到:
相关推荐
8. **预测**:训练完成后,使用测试集数据进行预测,评估模型的泛化能力。 9. **优化策略**:可能需要调整学习率、动量项、正则化参数等超参数,或者采用更高级的优化算法,如Adam,以提高训练效率和模型性能。 10...
在这个名为“15.MATLAB神经网络43个案例分析 定制神经网络的实现-神经网络的个性化建模与仿真.zip”的资源包中,重点是利用MATLAB进行神经网络的构建、训练和应用。神经网络是一种模仿人脑神经元结构的计算模型,...
在IT领域,神经网络是一种模仿人脑神经元结构的计算模型,广泛应用于机器学习和人工智能。...通过研究和实践这些代码,不仅可以掌握各种神经网络的工作原理,还能提升在Matlab环境下进行机器学习和人工智能开发的能力。
BP神经网络,全称为Backpropagation Neural Network,是人工神经网络的一种典型模型,尤其在非线性系统建模和预测领域应用广泛。本案例通过BP神经网络实现对非线性函数的拟合,以展示其在处理复杂问题时的能力。 在...
在本资源中,"27.MATLAB神经网络43个案例分析 基于灰色神经网络的预测算法研究-订单需求预测.zip" 提供了一套深入的学习资料,旨在教授如何利用MATLAB进行神经网络的建模和预测,特别是关注灰色神经网络在订单需求...
标题 "用matlab编BP神经网络预测程序.doc.zip" 提示我们这个压缩包包含一个MATLAB编写的BP(Backpropagation)神经网络预测程序的文档。BP神经网络是一种广泛用于函数逼近、分类和预测的监督学习算法,尤其在处理非...
在本资源中,我们主要探讨的是如何利用MATLAB这一强大的计算工具进行神经网络的应用,特别是针对变量筛选问题。...通过对BP神经网络的学习和实践,我们可以提升数据分析和建模的能力,更好地应对实际工程问题。
BP神经网络是机器学习和深度学习领域中的一种常用算法,通过反向传播算法来调整神经网络中的权值,从而实现对复杂数据的建模和预测。在本文中,作者提出了基于BP神经网络的空调能耗预测与监控系统,以解决空调能耗...
这个案例主要探讨了如何在Java环境中利用Weka进行数据分析和建模。以下是对标题和描述中涉及知识点的详细解释: 1. **Weka算法**:Weka(Waikato Environment for Knowledge Analysis)是新西兰怀卡托大学开发的一...
在本资源中,我们主要探讨的是使用MATLAB进行分类与判别建模,特别是基于模糊神经网络的方法来评价嘉陵江的水质。MATLAB是一款强大的数值计算和编程环境,广泛应用于工程、科研和数据分析等领域。在这个项目中,我们...
本资源“5.MATLAB神经网络43个案例分析 LIBSVM-FarutoUltimate工具箱及GUI版本介绍与使用.zip”是针对MATLAB神经网络应用的深入学习材料,其中包含了43个具体的案例,涵盖了各种神经网络模型和应用场景,以及LIBSVM...
BP神经网络,全称为Backpropagation Neural Network,是一种广泛应用的人工神经网络模型,主要用于监督学习中的非线性建模。它的核心思想是通过反向传播误差来调整网络中各连接权重,从而实现对复杂函数的逼近。在这...
MATLAB是进行模糊系统和神经网络建模的常用工具,其强大的库函数和直观的编程环境为模型构建提供了便利。 "data1.mat"和"data2.mat"是数据文件,可能包含了嘉陵江不同时间点的水质监测数据,如pH值、溶解氧、氨氮、...
基于深度神经网络的空气质量预测系统.pdf 本文提出了一种基于深度神经网络的空气质量预测系统,使用栈式自编码模型来预测空气质量。该系统选择了PM、PM10等污染物数据作为样本,基于Java平台构建,进行了训练和参数...
本手册将以神经网络为例,详细介绍如何使用MATLAB Builder for Java进行混合编程。首先,将在MATLAB环境中编写神经网络模型的训练和预测代码,然后使用MATLAB Builder for Java将其转换为Java组件。最后,这些组件将...
描述中提到的“预测源码”表明这是用某种编程语言实现的代码,可能是Python、Java、C++等,用于构建和训练双隐含层的BP神经网络模型,并进行预测。源码可能包括数据预处理、网络结构定义、权重初始化、反向传播算法...
此外,我们还使用C#和Java将BP神经网络得到的辐射误差修正方程分别进行封装,并完成Windows上位机和安卓端移动应用开发。这使得我们的方法可以在实际应用中得到更好的效果。 在气候变化研究中,温度测量精确性的...
SVM以其高效性和强大的泛化能力而受到青睐,而神经网络则以其强大的非线性建模能力著名。本案例“56.配套案例13 SVM神经网络中的参数优化-提升分类器性能.zip”旨在探讨如何通过参数优化来提升这两种模型的性能。 ...
此外,压缩包内的“19.MATLAB神经网络43个案例分析 基于BP_Adaboost的强分类器设计——公司财务预警建模.zip”文件可能包含另一个案例,说明如何使用增强学习方法,如Adaboost,结合BP神经网络进行公司财务危机的...