感知机
一个感知机相当于数字电路里面的一个门电路,多层感知机实现完整电路,以下是与门、与非门和或门的基础实现代码以及原理。如果使用横坐标为$x_1$,纵坐标为$x_2$的数轴来表示,你会发现实际上是$w_1x_1+w_2x_2+b=0$这条直线直线将两块区域划分开来,一部分为0,另一部分为1。
其中$b$称为偏置,$w_1$和$w2$称为权重。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| import numpy as np def AND(x1,x2): x=np.array([x1,x2]) w=np.array([0.5,0.5]) b=-0.7 tmp=np.sum(w*x)+b if tmp <= 0: return 0 else: return 1 def NAND(x1,x2): x=np.array([x1,x2]) w=np.array([0.5,0.5]) b=0.7 tmp=np.sum(w*x)+b if tmp <= 0: return 0 else: return 1 def OR(x1,x2): x=np.array([x1,x2]) w=np.array([0.5,0.5]) b=-0.2 tmp=np.sum(w*x)+b if tmp <= 0: return 0 else: return 1
def XOR(x1,x2): s1=NAND(x1,x2) s2=OR(X1,x2) y=AND(s1,s2) return y
for x in range(0,2): for y in range(0,2): print(XOR(x,y))
|
神经网络
基本概念
神经网络构成:最左边输入层,中间所有部分统称为中间层(也称为隐藏层),右侧为输出层。e.g.上面提到的$x_1$和$x_2$为两个输入神经元(第0层),连接着中间的两个NAND和OR神经元(第1层),再连第二个中间层AND神经元(第2层),最后输出(第3层)。
激活函数将输入信号的总和转换为输出信号,类似中间层的处理函数,下面介绍几种常见的激活函数。
激活函数
阶跃函数
代码实现:
1 2 3
| def stepfunction(x): y=x>0 return y.astype(np.int64)
|
Sigmoid函数
代码实现:
1 2
| def sigmoid(x): return 1/(1+np.exp(-x))
|
观察函数图像可以发现,阶跃函数和sigmoid函数分别是曲线与折线,都属于非线性函数,而形如$y=ax$的线性函数,在嵌套当中无法发挥更好的作用($y=h(h(h(x))$可以写成$y=a^3*x^3$),激活函数都是非线性函数。
代码实现:
1 2
| def relu(x): return np.maximum(x,0)
|
在处理分类问题和回归问题时,可以调整激活函数:回归问题用恒等函数,分类问题用$softmax$函数
这个式子表示假设输出层有有$n$个神经元,求第$k$个神经元的输出。为了防止溢出所以通常在指数位减去一个较大的数C来平衡,一般会使用输入信号中的最大值。由于输出在0到1之间,所以一般该函数都用于表示概率,即分类为某个物体的概率。
代码实现:
1 2 3 4 5 6
| def softmax(a): c = np.max(a) exp_a = np.exp(a - c) sum_exp_a = np.sum(exp_a) y= exp_a/sum_exp_a return y
|
神经网络的实现
通过矩阵点乘的方式能够将输入根据权重计算到下一层,实现神经网络的向前推进
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| import numpy as np def init_network(): network={} network['W1']=np.array([[0.1,0.3,0.5],[0.2,0.4,0.6]]) network['b1'] = np.array([0.1, 0.2, 0.3]) network['W2'] = np.array([[0.1, 0.4], [0.2, 0.5], [0.3, 0.6]]) network['b2'] = np.array([0.1, 0.2]) network['W3'] = np.array([[0.1, 0.3], [0.2, 0.4]]) network['b3'] = np.array([0.1, 0.2]) return network def forward(network, x): w1, w2, w3=network['W1'],network['W2'],network['W3'] b1, b2, b3=network['b1'],network['b2'],network['b3'] a1=np.dot(x,w1) + b1 z1=sigmoid(a1) a2=np.dot(z1,w2) + b2 z2=sigmoid(a2) a3=np.dot(z2,w3) + b3 y = a3 return y network=init_network() x=np.array([1.0,0.5]) y=forward(network,x) print(y)
|
总结
前面都是一些比较通俗易懂的内容,可以过的比较快,重点还是要掌握如何使用python语言去处理数据,对于模型原理更偏向于数学方面,需要有良好的线性代数以及相关的数理统计知识。