[译] 面向初学者: 神经网络概述(一)
最近网上看到一篇质量很不错的翻译文《小白都能看懂的神经网络教程:从原理到优化如此简单》,如获至宝。细读后发现里面有些翻译不到位。然后翻到原文读了一遍,又感觉原文有些虎头蛇尾,前半部分讲解深入浅出,后半部分讲解不够细致,匆匆收尾,作者似乎着急忙慌要睡觉似的。于是决定对原文再翻译一遍,以飨读者。
译文如下:
一篇简单介绍神经网络如何工作,以及如何用Python从头实现的文章
如果说“神经网络”其实不复杂,这可能会让你感到惊讶。事实上“神经网络”往往比你想象的要简单。
这篇文章是面向初学者的,并假定你机器学习基础为0。 我们将从头了解如何用 Python 实现神经网络。
1. 基本构建模块:神经元(Neurons)
首先,我们必须讨论下神经元,这是神经网络的基本单位。一个神经元接受多个输入,并对它们进行一些数学运算,然后产生一个输出。下图展示的是一个接收2个输入的神经元:
这里发生了三件事:
首先,每个 输入 (input) 都乘以一个 权重 w (weight):
$$ \begin{array}{l} x_{1} \rightarrow x_{1} * w_{1} \\ x_{2} \rightarrow x_{2} * w_{2} \end{array} $$
然后,所有的加权输入求和后又加上一个 偏移 b (bias):
$$ \left(x_{1} * w_{1}\right)+\left(x_{2} * w_{2}\right)+b $$
最后,加他们的 和 传递给一个 激活函数 (activation function):
$$ y=f\left(x_{1} * w_{1}+x_{2} * w_{2}+b\right) $$
这里的激活函数作用是将无限制的输入转换为可预测的输出。一种常见的激活函数是 sigmoid函数:
$$ \begin{aligned} \frac{1}{1+e^{-x}} \end{aligned} $$
激活函数的输出数值只会落在 \((0,1)\) 这个区间。你可以把它想象成将 \((−∞,+∞)\) 压缩成 \((0,1)\):
- 把无限小的负数转化为无限接近于0
- 把无限大的正数转化为无限接近于1
一个简单的例子
假设我们有一个使用\(sigmoid\)激活函数的神经元,它可以接收两个输入,下面是他的权重和偏移:\(w = [0,1]\) ,\(b = 4\)
\(w = [0 ,1]\) 是 \(w_{1} = 0,w_{2} = 1\)
的矢量表示法。
现在我们输入 \(x = [2, 3]\)。我们将用 点积 来简明的阐述:
$$ \begin{aligned} (w \cdot x)+b &=\left(\left(w_{1} * x_{1}\right)+\left(w_{2} * x_{2}\right)\right)+b \\ &=0 * 2+1 * 3+4 \\ &=7 \end{aligned} $$
$$ y=f(w \cdot x+b)=f(7)=\bm{0.999} $$
这个神经元给定输入 [2,3],给定输出 0.999。就是这样!这种向前传递输入以获得输出的过程成为前馈(feedforward) 。
编写一个神经元
是时候实现一个神经元了!我们将利用 Numpy (一个流行而强大的科学计数库) 来帮我们实现数学公式:
import numpy as np
def sigmoid(x):
# Our activation function: f(x) = 1 / (1 + e^(-x))
return 1 / (1 + np.exp(-x))
class Neuron:
def __init__(self, weights, bias):
self.weights = weights
self.bias = bias
def feedforward(self, inputs):
# Weight inputs, add bias, then use the activation function
total = np.dot(self.weights, inputs) + self.bias
return sigmoid(total)
weights = np.array([0, 1]) # w1 = 0, w2 = 1
bias = 4 # b = 4
n = Neuron(weights, bias)
x = np.array([2, 3]) # x1 = 2, x2 = 3
print(n.feedforward(x)) # 0.9990889488055994
认识这个数字吧?我们得到了相同的结果 0.999
2. 将神经元组合成神经网络
神经网络是什么?其实无非就是一束连接在一起的神经元。这是一个简单的神经网络的样子:
该网络有2个输入,一个包含2个神经元的隐藏层(\(h_1\) 和 \(h_2\)),以及一个带有1个神经元的输出层(\(o_1\))(请注意,\(o_1\) 的输入来自 \(h_1\) 和 \(h_2\)的输出 -这就是神经网络)。
举个栗子:前馈
以上面图中的神经网络为例,并假定所有神经元都有相同的权重 \(w=[0,1]\), 相同的偏移 \(b=0\),以及相同的 \(sigmoid\) 激活函数。用\(h_1,h_2,o_1\)表示他们代表的神经元输出。
如果我们输入 \(x = [2,3]\),会发生什么?
$$ \begin{aligned} h_{1}=h_{2} &=f(w \cdot x+b) \\ &=f((0 * 2)+(1 * 3)+0) \\ &=f(3) \\ &=0.9526 \end{aligned} $$
$$ \begin{aligned} o_{1} &=f\left(w \cdot\left[h_{1}, h_{2}\right]+b\right) \\ &=f\left(\left(0 * h_{1}\right)+\left(1 * h_{2}\right)+0\right) \\ &=f(0.9526) \\ &=\bm{0.7216} \end{aligned} $$
当输入为 \(x = [2,3]\),这个神经网络输出为 \(0.7216\), 是不是很简单?
一个神经网络可以有任意数量的层,每层可以有任意数据的神经元。基本思想一致:向前给神经元传递输入,并在后面得到结果。
方便起见,本文的其余部分将继续使用上图所示的神经网络
编写一个神经网络:前馈
让我们实现一个前馈神经网络。这是该网络的图片,仅供参考:
import numpy as np
# ... code from previous section here
class OurNeuralNetwork:
'''
A neural network with:
- 2 inputs
- a hidden layer with 2 neurons (h1, h2)
- an output layer with 1 neuron (o1)
Each neuron has the same weights and bias:
- w = [0, 1]
- b = 0
'''
def __init__(self):
weights = np.array([0, 1])
bias = 0
# The Neuron class here is from the previous section
self.h1 = Neuron(weights, bias)
self.h2 = Neuron(weights, bias)
self.o1 = Neuron(weights, bias)
def feedforward(self, x):
out_h1 = self.h1.feedforward(x)
out_h2 = self.h2.feedforward(x)
# The inputs for o1 are the outputs from h1 and h2
out_o1 = self.o1.feedforward(np.array([out_h1, out_h2]))
return out_o1
network = OurNeuralNetwork()
x = np.array([2, 3])
print(network.feedforward(x)) # 0.7216325609518421
我们又得出了\(0.7216\),完美!
TOPI 简介
超神经HyperAI赞 1阅读 90.6k
编译 PyTorch 模型
超神经HyperAI赞 1阅读 88.9k
编译 MXNet 模型
超神经HyperAI赞 1阅读 36.3k
横向对比 11 种算法,多伦多大学推出机器学习模型,加速长效注射剂新药研发
超神经HyperAI赞 1阅读 25.2k
利用 UMA 使硬件加速器可直接用于 TVM
超神经HyperAI阅读 94.1k
科罗拉多州立大学发布CSU-MLP模型,用随机森林预测中期恶劣天气
超神经HyperAI阅读 43.2k
借助计算机建模及 eBird 数据集,马萨诸塞大学成功预测鸟类迁徙
超神经HyperAI阅读 89.6k
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。