您的位置:首页 > 理论基础 > 计算机网络

[AI]人工神经网络对葡萄酒打分

2016-05-26 17:58 387 查看
人工神经网络(artificial neural network,缩写ANN),简称神经网络(neural network,缩写NN)或类神经网络,是一种模仿生物神经网络(动物的中枢神经系统,特别是大脑)的结构和功能的数学模型计算模型。神经网络由大量的人工神经元联结进行计算。大多数情况下人工神经网络能在外界信息的基础上改变内部结构,是一种自适应系统。现代神经网络是一种非线性统计性数据建模工具,常用来对输入和输出间复杂的关系进行建模,或用来探索数据的模式。(摘自https://zh.wikipedia.org/wiki/%E4%BA%BA%E5%B7%A5%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C)

给定葡萄酒的各项属性及评分,训练一个人工神经网络,对任意给定新的葡萄酒进行打分。

实验数据如下:

样品编号蛋白质mg/100g(x1)DPPH自由基1/IC50(g/L)(x2)总酚(mmol/kg)(x3)葡萄总黄酮(mmol/kg)(x4)PH值(x5)果皮质量(g)(x6)总分(y)
葡萄样品1555.4550.431423.5769.5093.540.12077.1
葡萄样品2624.0940.465926.02613.7203.880.19378.2
葡萄样品3580.2730.410221.47910.8533.800.16074.6
葡萄样品4527.4380.266010.7834.3943.360.17375.8
葡萄样品5590.6510.397218.54710.3333.580.26074
葡萄样品6532.0260.275510.4696.8673.310.21374.5
葡萄样品7489.3200.17589.1813.4973.130.13672.6
葡萄样品8556.0910.416015.3438.4542.900.24071.5
葡萄样品9703.3000.668931.76720.4333.680.15072.2
葡萄样品10547.6950.32639.1914.6033.660.21071.6
葡萄样品11545.0340.27966.1972.5453.460.12572
葡萄样品12491.2650.197511.9243.9263.370.25372.6
葡萄样品13603.6860.442014.5727.3603.910.17072.1
葡萄样品14597.2740.360615.6617.7803.460.25669.9
葡萄样品15531.4310.219312.0015.5983.160.20871.5
葡萄样品16585.7830.237110.9929.1853.250.13868.8
葡萄样品17546.5160.359415.3948.6133.380.33668.8
葡萄样品18511.5650.22607.9795.2733.330.15071.2
葡萄样品19542.2010.380616.7329.3703.690.08966.3
葡萄样品20556.8950.282511.9148.0693.660.24766
葡萄样品21566.1880.380315.6397.5423.660.10768.2
葡萄样品22490.7590.284216.0667.7593.720.12665.3
葡萄样品23547.8130.574832.52224.4363.420.26361.6
葡萄样品24504.4290.28368.1928.2653.650.22768.1
葡萄样品25539.5020.351811.8135.4293.410.20165.4
葡萄样品26589.9060.31797.1293.4133.630.21065.7
葡萄样品27523.8370.26549.1454.7113.310.18968.3
由于样本不足,存在过拟合等问题

源码:

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <cmath>
#include <ctime>
#define HIDENODE 5
#define RATE 0.9
#define TOLATHRE 0.001
#define PRECISION 10000
#define TOTALNUM 27
#define SAMPLENUM 17
#define ATTRNUM 7
using namespace std;
double SampleData[SAMPLENUM][ATTRNUM];
double TotalData[TOTALNUM][ATTRNUM], EvalData[TOTALNUM], MaxEval, MinEval;
double hi[HIDENODE], ho[HIDENODE], yi[SAMPLENUM], yo[SAMPLENUM];
double wih[HIDENODE][ATTRNUM - 1], who[HIDENODE];
double bh[HIDENODE], bo;
double Distin = 0x7FFFFFFF;
inline double f(double x)
{
return 1.0 / (1 + exp(-1 * x));
}

void Init()
{
freopen("ANN.txt", "r", stdin);
double max_attr[ATTRNUM], min_attr[ATTRNUM];
memset(max_attr, 0, sizeof(max_attr));
for (int i = 0; i< ATTRNUM; i++)
min_attr[i] = 0x7FFFFFFF;
//Input data
for (int i = 0; i < SAMPLENUM; i++)
{
for (int j = 0; j < ATTRNUM; j++)
{
cin >> SampleData[i][j];
max_attr[j] = (max_attr[j]>SampleData[i][j]) ? max_attr[j] : SampleData[i][j];
min_attr[j] = (min_attr[j]<SampleData[i][j]) ? min_attr[j] : SampleData[i][j];
}
}
//Normalize data
for (int i = 0; i < ATTRNUM; i++)
{
double diff = max_attr[i] - min_attr[i];
for (int j = 0; j < SAMPLENUM; j++)
SampleData[j][i] = (SampleData[j][i] - min_attr[i]) / diff;
}
//Rand weight
for (int i = 0; i < HIDENODE; i++)
{
who[i] = rand() % (2 * PRECISION + 1) / (double)PRECISION - 1;
for (int j = 0; j < ATTRNUM - 1; j++)
wih[i][j] = rand() % (2 * PRECISION + 1) / (double)PRECISION - 1;
}
for (int i = 0; i < SAMPLENUM; i++)
bh[i] = rand() % (2 * PRECISION + 1) / (double)PRECISION - 1;
bo = rand() % (2 * PRECISION + 1) / (double)PRECISION - 1;
}
void Train()
{
double theta1[HIDENODE], theta2 = 0;
Distin = 0;
//cout << Distin << ' ';
for (int i = 0; i < SAMPLENUM; i++)
{
memset(hi, 0, sizeof(hi));
memset(theta1, 0, sizeof(theta1));
yi[i] = 0;
for (int j = 0; j < HIDENODE; j++)
for (int k = 0; k < 6; k++)
hi[j] += SampleData[i][k] * wih[j][k];
for (int j = 0; j < HIDENODE; j++)
ho[j] = f(hi[j] + bh[j]);
for (int j = 0; j < HIDENODE; j++)
yi[i] += who[j] * ho[j];
yo[i] = f(yi[i] + bo);
theta2 = (SampleData[i][ATTRNUM - 1] - yo[i])*yo[i] * (1 - yo[i]);
for (int j = 0; j < HIDENODE; j++)
who[j] += RATE*theta2*ho[j];

for (int j = 0; j < HIDENODE; j++)
{
theta1[j] += theta2 * who[j] * ho[j] * (1 - ho[j]);
for (int k = 0; k < 6; k++)
wih[j][k] += RATE*theta1[j] * SampleData[i][k];
}
bo += RATE*theta2;
for (int j = 0; j < HIDENODE; j++)
bh[j] += RATE*theta1[j];

// compute Distin
Distin += pow(yo[i] - SampleData[i][6], 2);
}
//cout << Distin << endl;
}
void OutputParaments()
{
cout << "weights between input layer and hidden layer:" << endl;
for (int i = 0; i < HIDENODE; i++)
{
for (int j = 0; j < ATTRNUM - 1; j++)
cout << wih[i][j] << ' ';
cout << endl;
}

cout << endl << "weights between hidden layer and output layer:" << endl;
for (int i = 0; i < HIDENODE; i++)
cout << who[i] << ' ';
cout << endl;

cout << endl << "Thresholds in hidden layer:" << endl;
for (int i = 0; i < HIDENODE; i++)
cout << bh[i] << ' ';
cout << endl << endl;

cout << "Threshold in output layer:" << endl << bo << endl << endl;
}
void CalculateDifferences()
{
double max_diff = 0, min_diff = 0x7FFFFFFF, aver_diff = 0;
for (int i = 0; i < SAMPLENUM; i++)
{
aver_diff += fabs(SampleData[i][ATTRNUM - 1] - yo[i]);
max_diff = (max_diff > fabs(SampleData[i][ATTRNUM - 1] - yo[i])) ? max_diff : fabs(SampleData[i][ATTRNUM - 1] - yo[i]);
min_diff = (min_diff < fabs(SampleData[i][ATTRNUM - 1] - yo[i])) ? min_diff : fabs(SampleData[i][ATTRNUM - 1] - yo[i]);
}
aver_diff /= SAMPLENUM;
cout << "Max difference is: " << max_diff << endl;
cout << "Min difference is: " << min_diff << endl;
cout << "Average difference is: " << aver_diff << endl;
}
void GetAllGrap()
{
ifstream fin("ANN.txt");
double max_attr[ATTRNUM], min_attr[ATTRNUM];
memset(max_attr, 0, sizeof(max_attr));
MaxEval = 0;
MinEval = 0x7FFFFFFF;
for (int i = 0; i< ATTRNUM; i++)
min_attr[i] = 0x7FFFFFFF;
for (int i = 0; i < TOTALNUM; i++)
{
for (int j = 0; j < ATTRNUM; j++)
{
fin >> TotalData[i][j];
max_attr[j] = (max_attr[j]>TotalData[i][j]) ? max_attr[j] : TotalData[i][j];
min_attr[j] = (min_attr[j]<TotalData[i][j]) ? min_attr[j] : TotalData[i][j];
}
EvalData[i] = TotalData[i][ATTRNUM - 1];
MaxEval = (MaxEval>TotalData[i][ATTRNUM - 1]) ? MaxEval : TotalData[i][ATTRNUM - 1];
MinEval = (MinEval<TotalData[i][ATTRNUM - 1]) ? MinEval : TotalData[i][ATTRNUM - 1];
}
for (int i = 0; i < ATTRNUM; i++)
{
double diff = max_attr[i] - min_attr[i];
for (int j = 0; j < TOTALNUM; j++)
TotalData[j][i] = (TotalData[j][i] - min_attr[i]) / diff;
}
fin.close();
}
void CalculateEval(int grapnum)
{
double tmp_hidden[HIDENODE];
memset(tmp_hidden, 0, sizeof(tmp_hidden));
for (int i = 0; i < HIDENODE; i++)
{
for (int j = 0; j < ATTRNUM - 1; j++)
{
tmp_hidden[i] += TotalData[grapnum][j] * wih[i][j];
}
tmp_hidden[i] -= bh[i];
}
double tmp_output = 0;
for (int i = 0; i < HIDENODE; i++)
{
for (int j = 0; j < ATTRNUM - 1; j++)
tmp_output += tmp_hidden[i] * who[i];
}
tmp_output -= bo;
//tmp_output*=(MaxEval - MinEval) + MinEval;
cout << "the test result is: " << tmp_output << endl;
cout << "the distinguish is: " << fabs(tmp_output-EvalData[grapnum])<<endl;
}
int main()
{
srand((unsigned)time(0));
memset(hi, 0, sizeof(hi));
memset(ho, 0, sizeof(ho));
memset(yi, 0, sizeof(yi));
memset(yo, 0, sizeof(yo));
Init();
while (Distin > TOLATHRE)
Train();
OutputParaments();
CalculateDifferences();
int TestGrap = 0;
GetAllGrap();
freopen("con", "r", stdin);
cout<<"input the test grap num:"<<endl;
while (cin >> TestGrap)
{
if(TestGrap>=0&&TestGrap<=26)
{
CalculateEval(TestGrap);
cout<<"input the test grap num:"<<endl;
}
else
cout<<"Not legal!"<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息