最近做了一个BP神经网络,分享一下
头文件和库文件下载地址: http://download.csdn.net/detail/sdust_dx/9537656
使用随机x 识别 y=sin(x)关系的例子,效果还基本不错。
int main()
{
int InLayerNodesNum = 1; //输入层节点数
int MidLayerNodesNum = 8; //隐层节点数
int OutLayerNodesNum = 1;
cout << "输入层节点数(8): \r\n";
cin >> InLayerNodesNum;
int tLoop = 20000; // 训练次数
cout << "训练次数(10000): \r\n";
cin >> tLoop;
/* 造一组数据进行测试 */
BPNet bpNet(InLayerNodesNum, MidLayerNodesNum, OutLayerNodesNum);
const int N=50;
const float Pi=3.1415926;
srand(time(0));
float** a = new float*[N];
float** a2 = new float*[N];
float** a3 = new float*[N];
float** b = new float*[N];
float** b2 = new float*[N];
float** b3 = new float*[N]; //实际结果
float** b3_bp = new float*[N]; //识别结果
for(int i=0; i<N; i++)
{
a[i] = new float[InLayerNodesNum];
a2[i] = new float[InLayerNodesNum];
a3[i] = new float[InLayerNodesNum];
b[i] = new float[OutLayerNodesNum];
b2[i] = new float[OutLayerNodesNum];
b3[i] = new float[OutLayerNodesNum];
b3_bp[i] = new float[OutLayerNodesNum];
}
for(int i=0;i<N;++i)
{
a[i][0]=((2.0*(float)rand()/RAND_MAX)-1)*(Pi/2-1)+1;
a2[i][0]=((2.0*(float)rand()/RAND_MAX)-1)*(Pi/2-1)+1;
a3[i][0]=((2.0*(float)rand()/RAND_MAX)-1)*(Pi/2-1)+1;
b[i][0]=2*sin(a[i][0])-0.7;
b2[i][0]=2*sin(a2[i][0])-0.7;
b3[i][0]=2*sin(a3[i][0])-0.7;
}
bpNet.train(a,b,N);
bpNet.train(a2,b2,N);
bpNet.sim(a3,b3_bp,N);
cout << "a3 b3 b3-bp"
for(int i=0;i<N;++i)
cout<< a3[i][0] << " & " << b3[i][0]<<" -> "<<b3_bp[i][0]<<endl;
}
使用真实数据进行BP计算的时候,吻合度就没有这么好,因为x[]和y之间没有明确的函数关系甚至有的时候还是一对多的。
(而且也没有对x[]进行特别的预处理,没有将其映射到更好的特征空间里,做了映射的话效果应该会更好,后续计划做k-l或类似于自动聚类的预处理)。
地震数据体反推测井曲线,实际上地震数据体代表了反射结果,测井曲线代表地层特征。与地震波动相关的测井曲线才会在理论上与地震数据体有关,而且这种关系是非线性的。 在试验中,输入层采用了6个输入节点(6维特征)
下图是实际数据的结果