<span style="font-size:18px;">#include "stdafx.h"
#include <iostream>
#include "math.h"
using namespace std;
double d = 0.4;
// sigmoid函数
double function_g(double x)
{
// e的x次幂
double ex = pow(2.718281828,x);
return ex/(1+ex);
}
// 自动编码器的输入
double input[4][5] = {{0,0,0,1,1},
{0,0,1,0,1},
{0,1,0,0,1},
{1,0,0,0,1}};
// 第一层的权重
double edge_1[2][5];
// 第二层的权重
double edge_2[4][3];
// 输入层
double first_layer[5];
// 隐藏层
double hidden_layer[3] = {0,0,1};
//输出层
double output_layer[4];
//计算输入与输出的距离(欧氏距离)
double diff()
{
double ret = 0.0;
for(int i=0; i<4; ++i)
{
ret += (output_layer[i]-first_layer[i])*(output_layer[i]-first_layer[i]);
}
return ret;
}
// 计算隐含层节点值,隐含层有3个节点,其中一个是1(相当于截距)。
void count_second_1()
{
for(int i=0; i<2; ++i)
{
hidden_layer[i] = 0;
for(int j=0; j<5; ++j)
{
hidden_layer[i] += first_layer[j]*edge_1[i][j];
}
hidden_layer[i] = function_g(hidden_layer[i]);
}
return;
}
//计算输出层的输出值
void count_last_1()
{
for(int i=0; i<4; ++i)
{
output_layer[i] = 0;
for(int j=0; j<3; ++j)
{
output_layer[i] += hidden_layer[j]*edge_2[i][j];
}
output_layer[i] = function_g(output_layer[i]);
}
return;
}
// 总的重构误差
double total_diff()
{
double ret = 0.0;
for(int j=0; j<4; ++j)
{
for(int i=0; i<5; ++i)
{
first_layer[i] = input[j][i];
}
count_second_1();
count_last_1();
ret += diff();
}
return ret;
}
int main(void)
{
// 初始化第一层的权重
for(int i=0; i<2; ++i)
{
for(int j=0; j<5; ++j)
{
edge_1[i][j] = ((i+j)%4+0.1)/10;
}
}
// 初始化第二层的权重
for(int i=0; i<4; ++i)
{
for(int j=0; j<3; ++j)
{
edge_2[i][j] = ((i+j)%4+0.1)/10;
}
}
for(int i=0; i<40000; ++i)
{
double origin_diff = total_diff();
double direction_1[2][5],direction_2[4][3];
for(int i=0; i<2; i++)
{
for(int j=0; j<5; ++j)
{
double tmp = edge_1[i][j];
// 调整第一层的权值
edge_1[i][j] += d * origin_diff;
// 计算隐含层的输出
count_second_1();
// 输出层的输出
count_last_1();
// 计算输入层和输出层的误差
double diff2 = total_diff();
// 计算修改的权重和之前的差,用来进一步调节权重
direction_1[i][j] = origin_diff-diff2;
// 还原权重值,为了下面调节权重做准备。
edge_1[i][j] = tmp;
}
}
for(int i=0; i<4; ++i)
{
for(int j=0; j<3; ++j)
{
double tmp = edge_2[i][j];
edge_2[i][j] += d*origin_diff;
count_second_1();
count_last_1();
double diff2 = total_diff();
direction_2[i][j] = origin_diff -diff2;
edge_2[i][j] = tmp;
}
}
for(int i=0; i<2; ++i)
{
for(int j=0; j<5; ++j)
{
edge_1[i][j] += d*origin_diff*direction_1[i][j];
}
}
for(int i=0; i<4; ++i)
{
for(int j=0; j<3; ++j)
{
edge_2[i][j] += d*origin_diff*direction_2[i][j];
}
}
double d= 0.0;
d = total_diff();
cout << "diff_sum: " << d << endl;
}
}</span>