路人战队|用C语言从头开始实现一个神经网络

字幕组双语原文:用C从头实现神经网络
英语原文:Building Neural Network Framework in C using Backpropagation
翻译:雷锋字幕组(Mr.水方子)
在本文中 , 我们将用C语言从头开始实现一个基本的神经网络框架 。 之所以在C语言中这样做 , 是因为大多数库和其他高级语言(如Python)都抽象出了实现细节 。 在C语言中实现反向传播实际上会让我们更详细地了解改变权重和偏差是如何改变网络的整体行为的 。
注意:本文假设您了解反向传播算法背后的数学原理 。 如果你不熟悉 , 请参考这个 。
我们的目标是建立一个通用的框架 , 其中的层数和神经元将由用户根据他的要求指定 。 因此 , 我们将从用户获得以下输入来定义我们的神经网络框架:
1. 层数
2.每层神经元数目
3.学习速率
4.训练例子
5.输出标签
定义层和神经元结构:一旦我们有了层的数量和每层神经元的数量 , 我们就可以创建我们的神经网络的架构 。 但首先我们必须定义神经元和层的结构 。
神经元结构将包含以下参数:
路人战队|用C语言从头开始实现一个神经网络层结构将有许多神经元在该层和一个指针的neuron_t结构 。
路人战队|用C语言从头开始实现一个神经网络创建架构:现在 , 让我们使用create_architecture函数创建我们的神经网络的体系结构 。
在下面的代码片段中 , 外部For循环创建层 , 内部For循环将指定数量的神经元添加到该层 。 我们也随机初始化神经元的权值在0到1之间 。
路人战队|用C语言从头开始实现一个神经网络训练的例子:我们将使用get_input函数存储训练示例:
路人战队|用C语言从头开始实现一个神经网络得到输出标签:我们将使用get_desired_exports函数存储输出标签
路人战队|用C语言从头开始实现一个神经网络前向传递:第i层第j个神经元的激活与(i?1)第(i?1)层神经元的激活关系为:
注意:σ是激活函数 。 这里输出层使用sigmoid激活函数 , 隐藏层使用Relu激活函数 。
sigmoid函数:
Relu函数:
让我们实现forward_prop函数
路人战队|用C语言从头开始实现一个神经网络反向传递:反向传播的目标是反向传播错误并更新权值以最小化错误 。 这里 , 我们将使用均方误差函数来计算误差 。
权重(dw)和偏差(dbias)的变化是使用成本函数C对网络中的权重和偏差的偏导数(?C/ ?weights和?C/? bias)来计算的 。
sigmoid函数的导数:
relu函数的导数:
反向传播背后的四个基本方程:
路人战队|用C语言从头开始实现一个神经网络让我们在back_prop函数中实现这些公式:
路人战队|用C语言从头开始实现一个神经网络更新权重:在每个epoch中 , 我们将使用update_weights函数更新网络权值和偏差


推荐阅读