package bpnet;
import java.util.*;
import java.io.*;
class BPNet{
/*
* 神经网络常量和变量定义
*/
int InCode;//输入层节点个数;
int HideCode;//隐层节点个数;
int OutCode;//输出层节点个数;
int SampleNum=0;//样本数据的个数
double W_I_H[][];
double W_H_O[][];//隐层到输出层的权值
double Bias_H[];//隐层的阈值
double Bias_O[];//输出层的阈值
double I_Hide[];//隐层的纯输入
double I_Out[];//输出层的纯输入
double O_In[];//输入层的输出
double O_Hide[];//隐层的输出
double O_Out[];//输出层的输出
double Err_Hide[];//隐层的误差
double Err_Out[];//输出层的误差
int T[];//网络的实际输出
double O_Middle[];//记录样本数据中每一行的值
double Study_Efficient;//记录神经网络学习效率
//String SampleData[];//存储每一行样本数据
int classNum=0;//记录被正确分类的样本数据个数
String TestData[];
public int Echo_Num;//记录BP算法运行次数
public double Precision;//记录BP算法运行的精度
String[] t;
public int echo;
public double[] prerate;
public int InputPara;//输入参数个数
public static String argspre;
public static String trainfile;
public static String ceshifile;
public static String output;
FileWriter fr;//把流失的客户数据写入文件中
BufferedWriter bw;
/*
* 初始化神经网络的权值和阈值
*/
public void initial(){
Random rnd=new Random();
W_I_H=new double[InCode][HideCode];
W_H_O=new double[HideCode][OutCode];
Bias_H=new double[HideCode];
Bias_O=new double[OutCode];
for(int i=0;i<InCode;i++){//输入层到隐层的权值
for(int j=0;j<HideCode;j++){
W_I_H[i][j]=(rnd.nextInt(21)-10)/10.0;
}
}
for(int i=0;i<HideCode;i++){//隐层到输出层的权值
for(int j=0;j<OutCode;j++){
W_H_O[i][j]=(rnd.nextInt(21)-10)/10.0;
}
}
for(int i=0;i<HideCode;i++){//隐层的阈值
Bias_H[i]=(rnd.nextInt(21)-10)/10.0;
}
for(int j=0;j<OutCode;j++){//输出层的阈值
Bias_O[j]=(rnd.nextInt(21)-10)/10.0;
}
}
/*
* 读取样本数据的行数
*/
public int sampleNum(FileInputStream fis){
String s;
try{
InputStreamReader isr=new InputStreamReader(fis);
BufferedReader br=new BufferedReader(isr);
while((s=br.readLine())!=null){
SampleNum++;
}
br.close();
}catch(IOException ie){System.out.println(ie.toString());}
return SampleNum;
}
/*
* 获取样本数据的参数个数
*/
public void getParaNumber(String s) throws Exception{
InputPara=0;
try{
StringTokenizer stok=new StringTokenizer(s);
for(int i=0;stok.hasMoreTokens();i++){
String stoken=stok.nextToken();
InputPara++;
}
}catch(Exception e){
System.out.println(e.toString());
}
}
/*
*读取样本数据集中每一行的值
*/
public void readSample(String s) throws Exception{
try{
O_In=new double[InCode+1];
StringTokenizer stok=new StringTokenizer(s);
for(int i=0;stok.hasMoreTokens();i++){
String str=stok.nextToken();
O_In[i]=Double.parseDouble(str);
}
}catch(Exception e){System.out.println(e.toString());}
}
/*
* 计算隐层的纯输入和输出
*/
public void cal_I(int m){
double sum_W_I=0.0;
I_Hide=new double[HideCode];
O_Hide=new double[HideCode];
for(int j=0;j<HideCode;j++){//隐层的纯输入
for(int i=0;i<InCode;i++){
sum_W_I+=W_I_H[i][j]*O_In[i];
}
I_Hide[j]=sum_W_I+Bias_H[j];
}
for(int j=0;j<HideCode;j++){//隐层的输出
O_Hide[j]=(double)(1/(1+Math.exp(-I_Hide[j])));
}
}
/*
* 计算输出层的纯输入和输出
*/
public void cal_O(int m){
double sum_W_O=0.0;
I_Out=new double[OutCode];
O_Out=new double[OutCode];
for(int j=0;j<OutCode;j++){//输出层的纯输入
for(int i=0;i<HideCode;i++){
sum_W_O+=W_H_O[i][j]*O_Hide[i];
}
I_Out[j]=sum_W_O+Bias_O[j];
}
for(int j=0;j<OutCode;j++){//输出层的输出
O_Out[j]=(double)(1/(1+Math.exp(-I_Out[j])));
}
}
/*
* 计算输出层的误差
*/
public void cal_Err_O(int m){
Err_Out=new double[OutCode];
for(int j=0;j<OutCode;j++){
Err_Out[j]=O_Out[j]*(1-O_Out[j])*(O_In[InCode]-O_Out[j]);
if(Math.abs(O_Out[j]-O_In[InCode])<Precision){
classNum++;
}
}
}
/*
* 计算隐层的误差
*/
public void cal_Err_H(int m){
Err_Hide=new double[HideCode];
double sum_W_H=0.0;
for(int i=0;i<HideCode;i++){
for(int j=0;j<OutCode;j++){
sum_W_H+=Err_Out[j]*W_H_O[i][j];
}
Err_Hide[i]=sum_W_H*O_Hide[i]*(1-O_Hide[i]);
}
}
/*
*神经网络权值的更新
*/
public void W_Refresh(int m){
double[][] delta_W_I_H=new double[InCode][HideCode];
double[][] delta_W_H_O=new double[HideCode][OutCode];
for(int i=0;i<InCode;i++){
for(int j=0;j<HideCode;j++){
delta_W_I_H[i][j]=Study_Efficient*Err_Hide[j]*O_In[i];
W_I_H[i][j]=W_I_H[i][j]+delta_W_I_H[i][j];
}
}
for(int i=0;i<HideCode;i++){
for(int j=0;j<OutCode;j++){
delta_W_H_O[i][j]=Study_Efficient*Err_Out[j]*O_Hide[i];
W_H_O[i][j]=W_H_O[i][j]+delta_W_H_O[i][j];
}
}
}
/*
* 神经网络阈值的更新
*/
public void Bias_Refresh(int m){
double[] delta_Bias_H=new double[HideCode];
double[] delta_Bias_O=new double[OutCode];
for(int i=0;i<HideCode;i++){
delta_Bias_H[i]=Study_Efficient*Err_Hide[i];
Bias_H[i]=delta_Bias_H[i]+Bias_H[i];
}
for(int i=0;i<OutCode;i++){
delta_Bias_O[i]=Study_Efficient*Err_Out[i];
Bias_O[i]=delta_Bias_O[i]+Bias_O[i];
}
}
/*
* 神经网络模拟输出
*/
public void simulate() throws Exception{//通过测试数据来判断模型的准确度
for(int i=0;i<SampleNum;i++){
readSample(TestData[i]);
cal_I(i+1);
cal_O(i+1);
cal_Err_O(i+1);
}
}
/*
* 算法开始
*/
public void begin() throws Exception{
String SampleData[] = null;
echo=0;
try{
FileInputStream fis=new FileInputStream(trainfile);
sampleNum(fis);
}catch(IOException ie){System.out.println(ie.toString());}
try{
SampleData=new String[SampleNum];
FileInputStream fis1=new FileInputStream(trainfile);
InputStreamReader isr1=new InputStreamReader(fis1);
BufferedReader br1=new BufferedReader(isr1);
int k=0;
String s;
while((s=br1.readLine())!=null){
SampleData[k]=s;
getParaNumber(s);//获得样本数据的参数个数;
k++;
}
br1.close();
}catch(IOException ie){System.out.println(ie.toString());}
InCode=InputPara-1;
System.out.println("输入层节点数:"+InCode);
HideCode=2*InCode+1;
System.out.println("隐层节点数: "+HideCode);
System.out.println("输出层节点数:"+OutCode);
System.out.println("学习效率为:"+Study_Efficient);
System.out.println("算法运行次数