C++ 实现神经网络模型(一):只考虑神经网络中神经元模型和层的结构,未考虑反向传播算法

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值