宁波个人做网站,谷歌网站推广排名工具,手机2345网址导航老版下载,微信手机网站支付怎么做cuda实现PB神经网络 基于上一篇的矩阵点乘#xff0c;实现了矩阵的加减乘除、函数调用等。并且复用之前元编程里面写的梯度下降、Adam、NAdam优化方法。实现PB神经网络如下#xff1a; #ifndef __BP_NETWORK_HPP__
#define __BP_NETWORK_HPP__
#include matrix.hpp实现了矩阵的加减乘除、函数调用等。并且复用之前元编程里面写的梯度下降、Adam、NAdam优化方法。实现PB神经网络如下 #ifndef __BP_NETWORK_HPP__
#define __BP_NETWORK_HPP__
#include matrix.hpp
#include mat.hpp
#include update_methods.hpptemplatetypename activate_type, typename val_type_, templatetypename class update_type_tpl, typename init_type, int input_num_, int output_num_, int ... remain_layer
struct bp_network
{constexpr static int input_num input_num_;constexpr static int output_num output_num_;using val_type val_type_;using input_type matinput_num, 1, val_type;using input_t_type mat1, input_num, val_type;using output_type matoutput_num, 1, val_type;using weight_type matoutput_num, input_num, val_type;using forward_func typename func_pairactivate_type::forward_func;using backward_func typename func_pairactivate_type::backward_func;using next_node_type typename bp_networkactivate_type, val_type, update_type_tpl, init_type, output_num, remain_layer...;using term_output_type typename next_node_type::term_output_type;weight_type weight;update_type_tplweight_type weight_update_method;output_type bias;update_type_tploutput_type bias_update_method;input_type pre_input;output_type pre_func_input;next_node_type next_node;bp_network():weight_update_method(), bias_update_method(){weight.template resetinit_type();bias.template resetinit_type();next_node bp_networkactivate_type, val_type, update_type_tpl, init_type, output_num, remain_layer...();}auto forward(input_type input){output_type curr_output;pre_input input;auto temp weight.dot(input);pre_func_input temp bias;curr_output pre_func_input.template activateforward_func();return next_node.forward(curr_output);}auto backward(term_output_type delta, val_type lr){output_type curr_delta next_node.backward(delta, lr);curr_delta pre_func_input.template activatebackward_func() * curr_delta;auto ret weight.t_dot(curr_delta);// 更新参数weight_type delta_weight curr_delta.dot(pre_input.t());weight weight_update_method.update(weight, delta_weight);bias bias_update_method.update(bias, curr_delta);return ret;} // 更新惯性量void update_inert(){weight_update_method.update_inert();bias_update_method.update_inert();next_node.update_inert();}void print(){weight.print();printf(-----------------\n);bias.print();printf(\n);next_node.print();}
};templatetypename activate_type, typename val_type_, templatetypename class update_type_tpl, typename init_type, int input_num_, int output_num_
struct bp_networkactivate_type, val_type_, update_type_tpl, init_type, input_num_, output_num_
{constexpr static int input_num input_num_;constexpr static int output_num output_num_;using val_type val_type_;using input_type matinput_num, 1, val_type;using input_t_type mat1, input_num, val_type;using output_type matoutput_num, 1, val_type;using weight_type matoutput_num, input_num, val_type;using forward_func typename func_pairactivate_type::forward_func;using backward_func typename func_pairactivate_type::backward_func;using term_output_type typename output_type;using weight_update_type typename update_type_tplweight_type;using bias_update_type typename update_type_tploutput_type;weight_type weight;weight_update_type weight_update;output_type bias;bias_update_type bias_update;output_type pre_func_input;input_type pre_input;bp_network():weight_update(), bias_update(){weight.template resetinit_type();bias.template resetinit_type();}auto forward(input_type input){pre_input input;auto temp weight.dot(input);pre_func_input temp bias;return pre_func_input.template activateforward_func();}auto backward(output_type delta, val_type lr){output_type curr_delta pre_func_input.template activatebackward_func() * delta;auto ret weight.t_dot(curr_delta);// 更新参数weight_type delta_weight curr_delta.dot(pre_input.t());weight weight_update.update(weight, delta_weight);bias bias_update.update(bias, curr_delta);return ret;}void update_inert(){weight_update.update_inert();bias_update.update_inert();}void print(){weight.print();printf(-----------------\n);bias.print();printf(*****************\n);}
};#endif
下面实验一下我们的bp神经网络。
#include chrono
#include thread
#include matrix.hpp
#include bp_network.hpp
int main()
{constexpr int row_num 32;constexpr int adj_num 32;constexpr int col_num 32;/*matrix_device_proxyrow_num, adj_num, double A;eyes(A(), 2.0);matrix_device_proxyadj_num, col_num, double B;eyes(B(), 1.0);matrix_device_proxyrow_num, col_num, double C;mat_dotsigmoid(A(), B(), C());print(type_cast(C()));auto A matrow_num, adj_num, double::eyes(2.0);auto B matadj_num, col_num, double::eyes(1.0);auto C A.dot(B);C C 1.0;C sqrtl(C);C C - 2.0;C C * 3.0;C C / 4.0;C.print();std::cout ---------- D ---------- std::endl;auto D matrow_num, col_num, double::xavier_gaussian();D.print();std::cout ---------- E ---------- std::endl;auto E matrow_num, col_num, double::xavier_mean();E.print();std::cout ---------- F ---------- std::endl;auto F matrow_num, col_num, double::he_gaussian();F.print();std::cout ---------- G ---------- std::endl;auto G matrow_num, col_num, double::he_mean();G.print();*/bp_networksigmoid, double, nadam, xavier_gaussian_type, row_num, adj_num, col_num node;auto input matrow_num, 1, double::ones(0.2);auto expect matcol_num, 1, double::ones(0.4);int times 8000;int update_inert_times 100;int step times / update_inert_times;// 计时开始auto start std::chrono::high_resolution_clock::now();for (int i 0; i times; i){auto output node.forward(input);auto delta (output - expect);node.backward(delta, 0.001);if (i times - 1){output.t().print();}if (i % step 0 i ! 0){node.update_inert();}}// 计时结束// 获取结束时间点auto end std::chrono::high_resolution_clock::now();// 计算持续时间std::chrono::durationdouble duration end - start;// 输出执行时间std::cout Execution time: duration.count() seconds std::endl;//node.print();cudaDeviceReset();return 0;
}以上代码有个学习率lr没有地方设置哈将来优化见谅。执行结果如下 可以看出经过8000次的训练这个使用sigmoid激活函数、NAdam优化、Xavier-Gaussian初始化的323232的PB能够将误差缩减到0.0001这个量级而训练时间仅为8.54秒。还是相当给力的。 虽然这对于我的工作没有任何关系但是我还是想搞一下。毕竟“越是没用的知识就越有用越是有用的东西就越没用”。