BlackCat

Neural nets 4 min read

building micrograd

从零搭建 micrograd:神经元、权重、bias、激活函数(ReLU)与反向传播的直观解释,配可交互函数图像。

micrograd 是 andrej karpathy 所开源的一个Github学习项目,项目的初衷是让读者可以更好的学习back propagation.andrej karpathy 本人也录制过一段 Youtube 视频来进行讲解 (url:https://youtu.be/VMj-3S1tku0?si=6qfc4FQkdIn_WmnL)。那么为了理解 micrograd. 我们需要先从最基础的神经网络开始讲起.

神经元就是一个 $f(x_1,x_2,x_3,...)$ 一个函数 输入了一堆数字
然后每个input 都会跟着一个weight 权重 就是 最主要是一个常数
高就代表这个输入很重要
低就代表没那么重要
当然也要看正负 可以看出是负影响 还是 正影响

基本结构:
$f(x_1,x_2,x_3,...) = Activation_function(w_1 \times x_1 + w_2\times x_2 + ... + bias)$

这里可以看到在刚刚输入×权重后 还要加一个bias
而bias的作用是什么 为什么 + 一个bias呢

bias 从几何意义上来理解
y = mx + c
c 也就是代表着这条线可以在整个空间里面平移

机器学习 最主要是学习数据关系
也就是 输入 和 输出的对应关系
如果不允许平移 那么 如果真实数据里面是 y= 2x + 100
在 输入永远 = 0 的时候
如果没有bias 永远拟合不了线性的真实数据

而我们最终的目的也就是 确保 x轴上 每一个x 只要调整 w 和 bias 可以触及 任意的y
因为我们要拟合 世界上 任意的对应关系 任何的数据形态

但是单单只有一条 直线 是不够的
所以我们要引入 非线性

也就是 Activation function(激活函数)

我们先介绍第一种 Activation function
ReLU:

其实也就是创造一个折点 在几何意义上

那我们现在画一个最简单的神经网络 长这样(2个输入 3个隐藏神经元 1个输出):

最简单的神经网络:2输入 3隐藏 1输出

每条连线就是一个权重w 每个神经元做的是 加权求和 再过一个Activation function

为什么一定要非线性?
如果每个神经元都只是线性加权求和 那不管叠多少层 组合起来还是一条直线:

m(斜率) 1
b(y截距) 0.5

拖动左边m b的滑条 怎么调都只是一条直线 永远拟合不了sin(x)

但是只要加上ReLU这种非线性 把几个ReLU加起来 曲线就开始拐弯了:

c₁ 1
c₂ -0.8
c₃ 0.5
c₄ -0.3

拖动c₁到c₄的滑条 可以看到分段线性的曲线可以一点点逼近sin(x)
神经元的数量越多 拐弯的点越多 就能逼近越复杂的函数
这就是为什么神经网络一定要加Activation function

简单介绍完基本的神经网络结构就可以来说一下 micrograd 了

micrograd 是一个 autograd engine 就是自动梯度的机器

  • 也就是Implement backpropagation 向后传播

backpropagation 向后传播解释

整个Neural Network的目的例如说 我们想要这个神经网络去拟合一种数据分布对吧
首先整个的流程就是
Feed input -> Process -> Output

然后看看结果如何

那如何衡量结果 我们就需要loss function

有了 loss function 之后 知道做的好不好了

我们就需要去改良 (也就是去调整权重和bias)

举出一个简单的例子

Mean Squared Error - MSE

$$
MSE = \frac{1}{n} \sum_{i=1}^{n}(y_i-\hat{y}_i)^2
$$

有了Loss function 之后 我们的步骤就到了如何改进
那么改进 需要 gradient (梯度)

梯度的意思就是在 那一变量的对整个函数的影响 就是 如果增加一个无穷小量 dx 如何影响整个函数

让L 作为 Loss function

dL/dL 是1

L = tanh(wx + c)

dL/dw = dL/d(wx+c) d(wx +c)/dw
只要用微积分的法则 例如多变量微积分是将其他的变量当成常熟,嵌套函数就是chain rule 就可以算出 某个具体变量的梯度

知道梯度是 x 增加一个dx y的上涨
那么为了最小化L 可以学习率乘一个负导数
因为x 如果+dx是增加 L 那么 -dx 就是减少L 这样可以让Loss function 变小
而学习率就是变小多少 防止直接跳过了minimum

Keep reading

View all