目录
一、算法思想
在两层神经网络之间,必须有激活函数连接,从而加入非线性因素,提高神经网络的能力。所以,我们先从激活函数学起,一类是挤压型的激活函数,常用于简单网络的学习;另一类是半线性的激活函数,常用于深度网络的学习。
万能近似定理,是深度学习最根本的理论依据。
万能近似定理声明了在给定网络具有足够多的隐藏单元的条件下,配备一个线性输出层和一个带有任何挤压性质的激活函数的隐藏层的前馈神经网络,能够以任何想要的误差量近似任何从一个有限维度的空间映射到到另一个有限维度空间的可测的函数。
二、算法原理
激活函数决定是否传递信号。在这种情况下,只需要带有一个参数(阈值)的简单阶梯函数。
一般而言,我们构造的模型都是线性的,但是在实际应用过程中,遇到的很多问题其实是非线性的,这个时候,就需要在模型中应用激活函数,从而提高模型的性能。
激活函数优点:可以将连续值映射到0到1之间,将问题转化为概率问题,值大于0.5时是正例。
激活函数缺点:可能导致梯度消失和梯度爆炸问题;因为其中含有幂运算,所以计算机处理时会很耗时。
三、算法分析
首先明确两点:
(1)前向传播求损失,反向传播回传误差。
(2)每个神经元都可以根据误差修正权重。
神经网络前向算法:
前向算法的作用是计算输入层结点对隐藏层结点的影响,
也就是说,神经网络前向算法网络正向的走一遍:输入层->隐藏层->输出层
神经网络反向推导:
(1)计算总误差
(2)隐藏层的权重更新
(3)更新权重
四、源程序代码
import numpy as np
def sigmoid(x):
return 1 / (1 + np.exp(-x))
def deriv_sigmoid(x):
fx = sigmoid(x)
return fx * (1 - fx)
def mse_loss(y_true, y_pred):
return ((y_true - y_pred) ** 2).mean()
class OurNeuralNetwork:
def __init__(self):
self.w1 = np.random.normal()
self.w2 = np.random.normal()
self.w3 = np.random.normal()
self.w4 = np.random.normal()
self.w5 = np.random.normal()
self.w6 = np.random.normal()
self.b1 = np.random.normal()
self.b2 = np.random.normal()
self.b3 = np.random.normal()
def feedforward(self, x):
h1 = sigmoid(self.w1 * x[0] + self.w2 * x[1] + self.b1)
h2 = sigmoid(self.w3 * x[0] + self.w4 * x[1] + self.b2)
o1 = sigmoid(self.w5 * h1 + self.w6 * h2 + self.b3)
return o1
def train(self, data, all_y_trues):
learn_rate = 0.1
epochs = 1000 # 遍历整个数据集的次数
for epoch in range(epochs):
for x, y_true in zip(data, all_y_trues):
# --- 做一个前馈(稍后我们将需要这些值)
sum_h1 = self.w1 * x[0] + self.w2 * x[1] + self.b1
h1 = sigmoid(sum_h1)
sum_h2 = self.w3 * x[0] + self.w4 * x[1] + self.b2
h2 = sigmoid(sum_h2)
sum_o1 = self.w5 * h1 + self.w6 * h2 + self.b3
o1 = sigmoid(sum_o1)
y_pred = o1
d_L_d_ypred = -2 * (y_true - y_pred)
d_ypred_d_w5 = h1 * deriv_sigmoid(sum_o1)
d_ypred_d_w6 = h2 * deriv_sigmoid(sum_o1)
d_ypred_d_b3 = deriv_sigmoid(sum_o1)
d_ypred_d_h1 = self.w5 * deriv_sigmoid(sum_o1)
d_ypred_d_h2 = self.w6 * deriv_sigmoid(sum_o1)
d_h1_d_w1 = x[0] * deriv_sigmoid(sum_h1)
d_h1_d_w2 = x[1] * deriv_sigmoid(sum_h1)
d_h1_d_b1 = deriv_sigmoid(sum_h1)
# Neuron h2
d_h2_d_w3 = x[0] * deriv_sigmoid(sum_h2)
d_h2_d_w4 = x[1] * deriv_sigmoid(sum_h2)
d_h2_d_b2 = deriv_sigmoid(sum_h2)
self.w1 -= learn_rate * d_L_d_ypred * d_ypred_d_h1 * d_h1_d_w1
self.w2 -= learn_rate * d_L_d_ypred * d_ypred_d_h1 * d_h1_d_w2
self.b1 -= learn_rate * d_L_d_ypred * d_ypred_d_h1 * d_h1_d_b1
self.w3 -= learn_rate * d_L_d_ypred * d_ypred_d_h2 * d_h2_d_w3
self.w4 -= learn_rate * d_L_d_ypred * d_ypred_d_h2 * d_h2_d_w4
self.b2 -= learn_rate * d_L_d_ypred * d_ypred_d_h2 * d_h2_d_b2
self.w5 -= learn_rate * d_L_d_ypred * d_ypred_d_w5
self.w6 -= learn_rate * d_L_d_ypred * d_ypred_d_w6
self.b3 -= learn_rate * d_L_d_ypred * d_ypred_d_b3
if epoch % 100 == 0:
y_preds = np.apply_along_axis(self.feedforward, 1, data)
loss = mse_loss(all_y_trues, y_preds)
print("训练 %d 次模型错误率: %.3f" % (epoch, loss))
data = np.array([
[-2, -1], # Alice
[25, 6], # Bob
[17, 4], # Charlie
[-15, -6], # Diana
])
all_y_trues = np.array([
1, # Alice
0, # Bob
0, # Charlie
1, # Diana
])
network = OurNeuralNetwork()
network.train(data, all_y_trues)
import matplotlib.pyplot as plt
import numpy as np
x=np.linspace(-10,10)
y_sigmoid=1/(1+np.exp(-x))
plt.plot(x,y_sigmoid,'r-')
plt.title('sigmoid')
plt.show()
五、运行结果及分析