【深度学习】使用C++手动搭建一个神经网络

1.前言

       深度学习框架给我们带来了很多方便,但是过于依赖框架反而会让我们不知所以然。本篇博客中,我使用C和C++语言实现了一个神经网络。由于时间关系,仅实现BP神经网络(BP是一种反向传播更新梯度算法,但一开始用于MLP,习惯称MLP为BP神经网络),对于卷积神经网络,由于时间问题以后再编写。Github网址:GitHub - xuzhifanGithub/Neural-Network: C/C++编写神经网络

2.原理

2.1前向传播

神经元结构

对于输入x1,x2,x3,权重w1,w2,w3,偏置b有output = \sum_{i}^{3}x_iw_i+b=x1*w1+x2*w2+x3*w3+b

对于n个输入x1,x2,...,xn,权重w1,w2,...,wn,偏置b有output = \sum_{i}^{n}x_iw_i+b

2.2反向传播

先以下图简单的例子来推。损失Loss采用SGD来计算,及下图中式子。o_j^i代表第i层第j个输入。

这里只推了第0层w11,其他的朋友感觉不太明白的可以动手推推。对于偏置b理解的w应该很容易看出,只需把最后一个偏导替换成对b的,这部分结果为1.

接下来上难度,

3.代码实现

3.1定义实现tensor2D相关函数

struct Tensor2D {
    int h;//高(行)
    int w;//宽(列)
    float** data;
};

std::mt19937& get_generator();//伪随机数生成器
Tensor2D Tensor2D_init(int h, int w);//初始化tensor,值默认正态分布均值0,方差1
Tensor2D Tensor2D_init(int h, int w, float value);//初始化tensor,值均为自定义value
void Tensor2D_display(Tensor2D tensor,bool printValue = true);//打印tensor大小和打印值(默认)
Tensor2D Tensor2D_copy(Tensor2D tensor);//复制
void Tensor2D_copy(Tensor2D des,Tensor2D src);//复制
void Tensor2D_setZero(Tensor2D tensor);//tensor值置0
void Tensor2D_freeTensor(Tensor2D tensor);//释放tensor内存
//伪随机数生成器
std::mt19937& get_generator() {
    thread_local std::mt19937 gen(std::random_device{}());
    return gen;
}


//tensor值置0
void Tensor2D_setZero(Tensor2D tensor) {
    int m = tensor.h;
    int n = tensor.w;
 
    for (int i = 0; i < m; ++i) {
        for (int j = 0; j < n; ++j) {
            tensor.data[i][j] = 0.0;
        }
    }
}

//初始化
Tensor2D Tensor2D_init(int h, int w) {
    Tensor2D tensor;
    tensor.h = h;
    tensor.w = w;
    tensor.data = (float**)malloc(sizeof(float*) * h);
    std::mt19937& gen = get_generator();

    // 生成标准正态分布的随机数,mean为均值,stddev为标准差  
    std::normal_distribution<> d(0.0, 1.0); // 标准正态分布,均值为0,标准差为1  

    for (int i = 0; i < h; ++i) {
        tensor.data[i] = (float*)malloc(sizeof(float) * w);
    }

    for (int i = 0; i < h; ++i) {
        for (int j = 0; j < w; ++j) {
            tensor.data[i][j] = d(gen);
        }
    }
    return tensor;
}

//初始化
Tensor2D Tensor2D_init(int h, int w, float value) {
    Tensor2D tensor;
    tensor.h = h;
    tensor.w = w;
    tensor.data = (float**)malloc(sizeof(float*) * h);
    for (int i = 0; i < h; ++i) {
        tensor.data[i] = (float*)malloc(sizeof(float) * w);
    }

    for (int i = 0; i < h; ++i) {
        for (int j = 0; j < w; ++j) {
            tensor.data[i][j] = value;
        }
    }
    return tensor;
}

//显示tensor信息
void Tensor2D_display(Tensor2D tensor, bool printValue) {
    int m = tensor.h;
    int n = tensor.w;
    printf("\nTensor size:[%d,%d]\n", m, n);

    if (printValue) {
        printf("[");
        for (int i = 0; i < m; ++i) {
            printf("[");
                for (int j = 0; j < n; ++j) {
                    printf("%f", tensor.data[i][j]);
                    if (j != n - 1)printf(",");
                }
                if(i!=m-1)printf("]\n");
        }
        printf("]\n");
    }
    


}

//复制tensor
Tensor2D Tensor2D_copy(Tensor2D tensor) {
    Tensor2D temp = Tensor2D_init(tensor.h, tensor.w);
    for (int i = 0; i < tensor.h; ++i) {
        for (int j = 0; j < tensor.w; ++j) {
            temp.data[i][j] = tensor.data[i][j];
        }
    }
    return temp;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值