基于之前的元编程矩阵,接下来就可以实现BP神经网络了。先来看一下实例代码吧:
int main()
{
mat<3, 1> mt_input = { 1,2,3 }; // 训练数据集,只有一个数据[1,2,3]
net<3, 3, 1> n(.01); // 定义学习率为0.01,神经元数分别为3,3,1的bp神经网络
n.print(); // 打印神经网络权值矩阵
for (int i = 0; i < 500; ++i)
{
auto mt_out = n.forward(mt_input);
n.backward(mat<1, 1>({ .7 })); // 以矩阵[.7]为期望值,计算误差并反向传播,更新网络
std::cout << "vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv" << std::endl;
mt_out.print(); // 输出结果打印
}
std::cout << "=====================================" << std::endl;
n.print();
_getch();
return 0;
}
看上去足够简洁,接下来是基于之前元编程矩阵的一些改正,主要是转置的更正以及初始化的随机极小值。代码如下:
#include <random>
template<typename val_t>
struct mat_m
{
val_t* p;
mat_m(const int& sz) :p(nullptr)
{
p = (val_t*)malloc(sz * sizeof(val_t));
static std::default_random_engine e;
std::uniform_real_distribution<double> ud(0, .001);
for (int i = 0; i < sz; ++i)
{
p[i] = ud(e);
}
}
~mat_m()
{
if (p)
free(p);
}
val_t& get(const int& len_1d, const int& i_1d_idx, const int& i_2d_idx)
{
return p[i_2d_idx + len_1d * i_1d_idx];
}
};
template<int row_num, int col_num, typename val_t = double>
struct mat
{
typedef val_t vt;
static constexpr int r = row_num;
static constexpr int c = col_num;
std::shared_ptr<mat_m<val_t>> pval;
bool b_t;
mat():b_t(false)
{
pval = std::make_shared<mat_m<val_t>>(row_num * col_num);
}
mat(const mat<row_num, col_num, val_t>& other) :pval(other.pval), b_t(other.b_t)
{
}
mat(const val_t&