Autoencoder的C++代码(带注释)。


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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MachineLP

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值