📄 neuralnetwork.cpp
字号:
// NeuralNetwork.cpp : 定义控制台应用程序的入口点。
//
/************************************************************************
* 版权所有 (C)2008, HITSZ
*
* 文件名称:// NeuralNetwork.cpp
* 文件标识://
* 内容摘要:// 利用反向传播算法进行音轨分类
* 其它说明:
* 当前版本:// 1.0版
* 作 者:// 李江涛,哈尔滨工业大学深圳研究生院智能计算研究中心
* 完成日期:// 2008年12月14日
*
* 修改记录1:
* 修改日期:
* 版 本 号:
* 修 改 人:
* 修改内容:
************************************************************************/
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <cmath>
#include <cstring>
#include <string>
#include <ctime>
#include "GlobalVal.h"
using namespace std;
/************************************************************************
* 函数名称:// StrToInt
* 功能描述:// string到int的转换
* 访问的表://
* 修改的表://
* 输入参数:// string
* 输出参数:// int
* 返 回 值://
* 其它说明://
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------------------------------
* 2008/12/14 v1.0 李江涛 建立该函数
************************************************************************/
int StrToInt(string& str)
{
int i, len = (int)str.size(), num = 0;
i = 0;
while (i < len)
{
num = num * 10 + (int)(str[i] - '0');
++i;
}
return num;
}
/************************************************************************/
/* 函数原型 */
/************************************************************************/
bool startTraining(void);
bool startTesting(void);
void initialWeight(void);
/************************************************************************/
/* 主函数 */
/************************************************************************/
int _tmain(int argc, _TCHAR* argv[])
{
int ctrl; //循环控制
int choose = 0; //循环控制
ofstream outputFile;
//初始化权值
initialWeight();
cout << "特征数:" << NUMIN << "\t" << "以mid为单位判断准确率 !" << endl;
while (3 != choose)
{
// 选择
ctrl = 0;
cout << "*********************" << endl;
cout << " 1. Train\n 2. Test\n 3. Quit\n";
cout << "*********************" << endl;
cout << "Please input your choice: ";
cin >> choose;
if (1 == choose)
{
cout << "\nTraining ... " << endl;
while (800 > ctrl)
{
if (!startTraining())
{
cout << "train error !" << endl;
break;
//exit(1);
}
++ctrl;
}
cout << "Training end!\n" << endl;
}
else if (2 == choose)
{
cout << "\nTesting ..." << endl;
outputFile.open("Result.txt");
if (outputFile.fail())
{
cout<<"Can not open result file!\n";
exit(1);
}
if (!startTesting())
{
cout << "test error !" << endl;
//exit(1);
}
else
{
// 输出结果
outputFile << "====================================================" << endl;
outputFile << "Right number : " << rightNum << endl;
outputFile << "Right rate : " << (float)rightNum / (float)testNum << endl;
outputFile.close();
cout << "Testing end!\n" << endl;
cout << "Total number: " << testNum << endl;
cout << "Right number : " << rightNum << endl;
cout << "Right rate : " << (float)rightNum / (float)testNum << endl;
cout << "\n";
}
}
else if (3 == choose)
{
cout << "\nBye~~~\n" << endl;
break;
}
else
{
cout << "Input error!" << endl;
continue;
}
}
return 0;
}
/************************************************************************
* 函数名称:// initialWeight
* 功能描述:// 初始化神经网络权值
* 访问的表://
* 修改的表://
* 输入参数://
* 输出参数://
* 返 回 值:// 无返回值
* 其它说明://
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------------------------------
* 2008/12/14 v1.0 李江涛 建立该函数
************************************************************************/
void initialWeight(void)
{
int i, j;
// 时间种子
srand((unsigned)time(NULL));
for (i = 0; i < NUMIN; i++)
{
for (j = 0; j < NUMHIDDEN; j++)
{
weightInHidden[i][j] = (double)((rand() % 1000) - 500) / 10000;
}
}
for (i = 0; i < NUMHIDDEN; i++)
{
for (j = 0; j < NUMOUT; j++)
{
weightHiddenOut[i][j] = (double)((rand() % 1000) - 500) / 10000;
}
}
}
/************************************************************************
* 函数名称:// initialWeight
* 功能描述:// 训练神经网络权值
* 访问的表://
* 修改的表://
* 输入参数://
* 输出参数://
* 返 回 值:// 无返回值
* 其它说明://
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------------------------------
* 2008/12/14 v1.0 李江涛 建立该函数
*
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------------------------------
* 2008/12/18 v1.1 李江涛 增加头处理,避免每次改样本文件
************************************************************************/
bool startTraining(void)
{
float pgmContent[NUMIN], t[NUMOUT];
int i, j;
double hiddenLayer[NUMHIDDEN];
double outputLayer[NUMOUT];
double errOfHidden[NUMHIDDEN];
double errOfOutput[NUMOUT];
string filename;
int trackNum;
ifstream trainList("train.txt");
if (trainList.fail())
{
cout << "open train.txt error !";
return false;
}
while (trainList.peek() != EOF )
{
trainList >> filename;
trainList >> trackNum;
for (int k=1; k<=trackNum; ++k)
{
for (i=0; i<NUMIN; ++i)
{
trainList >> pgmContent[i];
}
trainList >> t[0];
t[1] = 1 - t[0];
for (i = 0; i < NUMHIDDEN; i++)
{
hiddenLayer[i] = 0;
}
outputLayer[0] = 0;
outputLayer[1] = 0;
// 初始化隐藏层
for (i=0; i<NUMHIDDEN; ++i)
{
for (j=0; j<NUMIN; ++j)
{
hiddenLayer[i] += pgmContent[j] * weightInHidden[j][i];
}
hiddenLayer[i] = 1 / (1 + exp((-1) * hiddenLayer[i]));
}
// 初始化输出层
for (i=0; i<NUMOUT; ++i)
{
for (j=0; j<NUMHIDDEN; ++j)
{
outputLayer[i] += hiddenLayer[j] * weightHiddenOut[j][i];
}
outputLayer[i] = 1 / (1 + exp((-1) * outputLayer[i]));
}
// 修改输出层误差
for (i=0; i<NUMOUT; ++i)
{
errOfOutput[i] = outputLayer[i] * (1 - outputLayer[i]) * (t[i] - outputLayer[i]);
}
// 修改隐藏层误差
for (i=0; i<NUMHIDDEN; ++i)
{
errOfHidden[i] = hiddenLayer[i] * (1 - hiddenLayer[i]) * (weightHiddenOut[i][0] * errOfOutput[0]
+ weightHiddenOut[i][1] * errOfOutput[1]);
}
// 更新隐藏层到输出层权值
for (i=0; i<NUMHIDDEN; ++i)
{
for (j=0; j<NUMOUT; ++j)
{
weightHiddenOut[i][j] = weightHiddenOut[i][j] + learningRate * errOfOutput[j] * hiddenLayer[i];
}
}
// 更新输入层到隐藏层权值
for (i=0; i<NUMIN; ++i)
{
for (j=0; j<NUMHIDDEN; ++j)
{
weightInHidden[i][j] = weightInHidden[i][j] + learningRate * errOfHidden[j] * pgmContent[i];
}
}
}
filename.clear();
}
trainList.close();
return true;
}
/************************************************************************
* 函数名称:// initialWeight
* 功能描述:// 测试神经网络
* 访问的表://
* 修改的表://
* 输入参数://
* 输出参数://
* 返 回 值:// 无返回值
* 其它说明://
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------------------------------
* 2008/12/14 v1.0 李江涛 建立该函数
************************************************************************/
bool startTesting(void)
{
ofstream testOut("testResult.txt");
string filename;
int trackNum;
int maxNum;
float maxOutPut;
int zeroNum;
float pgmContent[NUMIN];
float t[NUMOUT];
int melodyTrack;
ifstream testList("test.txt");
if (testList.fail())
{
cout << "open test.txt error !";
return false;
}
int i, j, k;
int temp;
double hiddenLayer[NUMHIDDEN];
double outputLayer[50][NUMOUT];
/*for (i = 0; i < NUMHIDDEN; i++)
{
hiddenLayer[i] = 0;
}
outputLayer[k][0] = 0;
outputLayer[k][1] = 0;*/
testNum = 0;
rightNum = 0;
while (testList.peek() != EOF)
{
melodyTrack = 0;
maxOutPut = -100.0;
maxNum = 0;
temp = 0;
testList >> filename;
if (filename.empty())
{
continue;
}
testList >> trackNum;
++testNum;
for (k=1; k<=trackNum; ++k)
{
for (i=0; i<NUMIN; ++i)
{
testList >> pgmContent[i];
}
zeroNum = 0;
testList >> t[0];
if (t[0] > 0.5)
{
melodyTrack = k;
}
for (i=0; i<NUMIN; ++i)
{
if (pgmContent[i] == 0)
{
++zeroNum;
}
}
if (zeroNum >= NUMIN-2)
{
outputLayer[k][0] = 0.1;
continue;
}
for (i = 0; i < NUMHIDDEN; i++)
{
hiddenLayer[i] = 0;
}
outputLayer[k][0] = 0;
outputLayer[k][1] = 0;
// 计算隐藏层
for (i = 0; i < NUMHIDDEN; i++)
{
for (j = 0; j < NUMIN; j++)
{
hiddenLayer[i] += pgmContent[j] * weightInHidden[j][i];
}
hiddenLayer[i] = 1 / (1 + exp((-1) * hiddenLayer[i]));
}
// 计算输出层
for (i = 0; i < NUMOUT; i++)
{
for (j = 0; j < NUMHIDDEN; j++)
{
outputLayer[k][i] += hiddenLayer[j] * weightHiddenOut[j][i];
}
outputLayer[k][i] = 1 / (1 + exp((-1) * outputLayer[k][i]));
}
//outputLayer[k][0] = outputLayer[k][0] - outputLayer[k][1];
}
for (k=0; k<trackNum; ++k)
{
if ((outputLayer[k][0]-maxOutPut) > 10e-4)
{
maxOutPut = (float)outputLayer[k][0];
maxNum = k;
}
}
testOut << filename << " " << maxNum << " " << melodyTrack << endl;
if (maxNum == melodyTrack)
{
++rightNum;
}
filename.clear();
}
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -