?? 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 + -