深度学习入门--神经网络
一、感知机
感知机接受多个输入信号,输出一个信号。
图中感知机接收 x 1 x_1 x1和 x 2 x_2 x2两个输入信号,输出y,用下式表示图中的感知机。
y = { 0 , ( b+ w 1 x 1 + w 2 x 2 ≤ 0) 1 , ( b+ w 1 x 1 + w 2 x 2 >0 ) y= \begin{cases} 0, & \text {(\it{b+$w_1x_1$+$w_2x_2$}$\leq${0})} \\ 1, & \text{(\it{b+$w_1x_1$+$w_2x_2$>0})} \end{cases} y={0,1,(b+w1x1+w2x2≤0)(b+w1x1+w2x2>0)
b是被称为偏置的参数,用于控制神经元被激活的容易程度;
w 1 w_1 w1和 w 2 w_2 w2是表示各个信号权重的参数,用于控制各个信号的重要性;
明确表示出偏置,如下图
实际上,输入信号的加权总和经过了阶跃函数 h ( x ) = { 0 , (x ≤ 0) 1 , (x>0) h(x)= \begin{cases} 0, & \text {(x$\leq$0)} \\ 1, & \text{(x>0)} \end{cases} h(x)={0,1,(x≤0)(x>0)(即单层感知机的激活函数)得到了输出信号y。
阶跃函数的实现:
import numpy as np
from matplotlib import pyplot as plt
def step_function(x):
return np.array(x>0,dtype=np.int)
x = np.arange(-5,5,0.1)
y = step_function(x)
plt.title('step_function')
plt.plot(x,y)
plt.ylim(-0.1,1.1)
plt.show()
二、激活函数
激活函数( activation function )将输入信号的总和转换为输出信号。
激活函数的作用在于决定如何来激活输入信号的总和。
激活函数是连接感知机和神经网络的桥梁。实际上,如果将激活函数从阶跃函数转换为其他函数,就进入了神经网络的世界。
1. sigmold函数
h ( x ) = 1 1 + e − x h(x)={1\over{1+e^{-x}}} h(x)=1+e−x1
sigmold函数的平滑性对神经网络有着重要意义
sigmold函数的实现:
import numpy as np
from matplotlib import pyplot as plt
def sigmold_function(x):
return 1/(1+np.exp(-x))
x = np.arange(-5,5,0.1)
y = sigmold_function(x)
plt.title('sigmold_function')
plt.plot(x,y)
plt.ylim(-0.1,1.1)
plt.show()
2. ReLU函数
y = { x , ( x>0) 0 , ( x ≤ 0 ) y= \begin{cases} x, & \text {(\it{x>0)}} \\ 0, & \text{(\it{x$\leq$0})} \end{cases} y={x,0,(x>0)(x≤0)
实现:
import numpy as np
from matplotlib import pyplot as plt
def relu_function(x):
return np.maximum(x,0)
x = np.arange(-5,5,0.1)
y = relu_function(x)
plt.title('relu_function')
plt.plot(x,y)
plt.show()
3. softmax函数
神经网络在分类问题上一般使用softmax函数
y k = e a k ∑ i = 1 n e a i y_k = {e^{a_k}\over{\sum_{i=1}^n{e^{a_i}}}} yk=∑i=1neaieak
softmax函数输出0.0-1.0之间的实数,并且 y 1 , y 2 . . . y n y_1,y_2...y_n y1,y2...yn的和为1,所以把softmax函数的输出解释为“概率”
为防止数值溢出的实现方法:
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
三、三层神经网络的实现
从输入层到第一层的信号传递
代码小结:
import numpy as np
def sigmold_function(x):
return 1/(1+np.exp(-x))
def identity_function(x):
return x
def init_network():
network = {}
network['w1'] = np.array([[0.1,0.3,0.5],[0.2,0.4,0.6]])#第一层权重数组
network['w2'] = np.array([[0.1,0.4], [0.2,0.5],[0.3,0.6]])
network['w3'] = np.array([[0.1,0.3], [0.2, 0.4]])
network['b1'] = np.array([0.1,0.2,0.3])#第一层偏置数组
network['b2'] = np.array([0.1,0.2])
network['b3'] = np.array([0.1,0.2])
return network
def forward(x):#前向处理(从前往后处理)
network = init_network()
a1 = np.dot(x,network['w1'])+network['b1'] #从输入层到第一层
z1 = sigmold_function(a1) #经过sigmold激活函数
a2 = np.dot(z1, network['w2']) + network['b2'] #从第一层到第二层
z2 = sigmold_function(a2) #经过sigmold激活函数
a3 = np.dot(z2, network['w3']) + network['b3'] #从第二层到第三层
z3 = identity_function(a3) #恒等函数用于回归问题
return z3
x = np.array([1.0,0.5])
print(forward(x))
结果:
[0.31682708 0.69627909]