1.定义激活函数和神经元模型
(1)激活函数:此处仅仅定义两种激活函数Sigmoid和ReLU
/**@author @还下着雨ZG
* @brief 对向量求解sigmoid(sigmoid激活函数)
* @param[in] z 输入向量
* @return 输出向量
*/
double sigmoid(const double &z){
return 1.0/(1+exp(-z));
}
/**
* @brief 对向量求解ReLU(ReLU激活函数)
* @param[in] z 输入向量
* @return 输出向量
*/
double ReLU(const double &z){
return z>0 ? z : 0;
}
(2)神经元模型:用一个类模拟神经元,本文因为没有考虑反向传播,因此偏导、优化等方法还没有定义
/**
* @brief 模拟一个神经元
* @param[in] x 输入向量
* @param[in] activation 激活函数
*/
class Neuron{
public:
Neuron(const VectorXd &_x,const string &_activation):x(_x),activation(_activation){
n=x.size();
w=generate_w_init(n);
b=generate_b_init();
z=w.dot(_x)+b;
if(activation=="sigmoid"){
a=sigmoid(z);
}
if(activation=="ReLU"){
a=ReLU(z);
}
std::cout<<"当前神经元的权重为:"<<w.transpose()<<std::endl;
}
VectorXd generate_w_init(int len){
return (VectorXd::Random(n).array()+1.0)/2.0;//初始化权重:0-1的随机均匀分布
}
double generate_b_init(){
std::random_device rd; // 用于获取随机种子
std::mt19937 gen(rd()); // 使用随机种子初始化随机数发生器
std::uniform_real_distribution<> dis(0, 1); // 定义一个范围为 [0,1] 的均匀分布
return b=dis(gen);
}
double get_output(){
return a;
}
VectorXd get_w(){
return w;
}
double get_b(){
return b;
}
private:
VectorXd x;
string activation;
VectorXd w;
double b;
int n; //当前神经元权重的维度
double z;
double a;//神经元输出值
VectorXd grad_w;
double grad_b;
VectorXd err;
double lr=5.0e-7;
};
2.定义一个神经网络层
该神经网络模型无法对参数进行调整:因为没有定义损失函数、没有定义反向传播算法,本文仅用于对神经网络架构中细节的理解
/**
* @brief 神经网络的层Layer
* @param[in] units 神经元数量
* @param[in] activation 激活函数
* @param[in] x 输入向量
*/
class Dense_self{
public:
Dense_self(int _units,string _activation):units(_units),activation(_activation){
output.resize(units);
neuron=shared_ptr<Neuron>(nullptr);
}
~Dense_self(){}
VectorXd get_output(){
return output;
}
auto operator()(VectorXd &x)->decltype(*this){
for(int i=0;i<units;++i){
neuron.reset(new Neuron(x,activation));
neuron_list.push_back(*neuron);
output[i]=neuron_list[i].get_output();
}
neuron=nullptr;
return *this;
}
private:
int units;
string activation;
vector<Neuron> neuron_list;
shared_ptr<Neuron> neuron;
VectorXd input;
VectorXd output;
};
3.使用上述定义的神经网络模型
int main(){
VectorXd a(5);
a<<1,2,3,4,-5;
Dense_self layer01(25,"sigmoid");//初始化神经网络的一层
// auto a_01=layer01(a).get_output();
auto a_01=layer01(a).get_output();
cout<<"First layer output:\n"<<a_01<<endl;
Dense_self layer02(9,"ReLU");
auto a_02=layer02(a_01).get_output();
cout<<"Second layer output:\n"<<a_02<<endl;
return 0;
}
4.所有代码(可直接运行)
注意:需要Eigen库的支持
#include <iostream>
#include <Eigen/Dense>
#include <string>
#include <Eigen/Geometry>
#include <random>
#include <memory>
using namespace Eigen;
using namespace std;
/**@author @还下着雨ZG
* @brief 对向量求解sigmoid(sigmoid激活函数)
* @param[in] z 输入向量
* @return 输出向量
*/
double sigmoid(const double &z){
return 1.0/(1+exp(-z));
}
/**
* @brief 对向量求解ReLU(ReLU激活函数)
* @param[in] z 输入向量
* @return 输出向量
*/
double ReLU(const double &z){
return z>0 ? z : 0;
}
/**
* @brief 模拟一个神经元
* @param[in] x 输入向量
* @param[in] activation 激活函数
*/
class Neuron{
public:
Neuron(const VectorXd &_x,const string &_activation):x(_x),activation(_activation){
n=x.size();
w=generate_w_init(n);
b=generate_b_init();
z=w.dot(_x)+b;
if(activation=="sigmoid"){
a=sigmoid(z);
}
if(activation=="ReLU"){
a=ReLU(z);
}
std::cout<<"当前神经元的权重为:"<<w.transpose()<<std::endl;
}
VectorXd generate_w_init(int len){
return (VectorXd::Random(n).array()+1.0)/2.0;//初始化权重:0-1的随机均匀分布
}
double generate_b_init(){
std::random_device rd; // 用于获取随机种子
std::mt19937 gen(rd()); // 使用随机种子初始化随机数发生器
std::uniform_real_distribution<> dis(0, 1); // 定义一个范围为 [0,1] 的均匀分布
return b=dis(gen);
}
double get_output(){
return a;
}
VectorXd get_w(){
return w;
}
double get_b(){
return b;
}
private:
VectorXd x;
string activation;
VectorXd w;
double b;
int n; //当前神经元权重的维度
double z;
double a;//神经元输出值
VectorXd grad_w;
double grad_b;
VectorXd err;
double lr=5.0e-7;
};
/**
* @brief 神经网络的层Layer
* @param[in] units 神经元数量
* @param[in] activation 激活函数
* @param[in] x 输入向量
*/
class Dense_self{
public:
Dense_self(int _units,string _activation):units(_units),activation(_activation){
output.resize(units);
neuron=shared_ptr<Neuron>(nullptr);
}
~Dense_self(){}
VectorXd get_output(){
return output;
}
auto operator()(VectorXd &x)->decltype(*this){
for(int i=0;i<units;++i){
neuron.reset(new Neuron(x,activation));
neuron_list.push_back(*neuron);
output[i]=neuron_list[i].get_output();
}
neuron=nullptr;
return *this;
}
private:
int units;
string activation;
vector<Neuron> neuron_list;
shared_ptr<Neuron> neuron;
VectorXd input;
VectorXd output;
};
int main(){
VectorXd a(5);
a<<1,2,3,4,-5;
Dense_self layer01(25,"sigmoid");//初始化神经网络的一层
// auto a_01=layer01(a).get_output();
auto a_01=layer01(a).get_output();
cout<<"First layer output:\n"<<a_01<<endl;
Dense_self layer02(9,"ReLU");
auto a_02=layer02(a_01).get_output();
cout<<"Second layer output:\n"<<a_02<<endl;
return 0;
}