2022-10-10AI00
请注意,本文编写于 53 天前,最后修改于 53 天前,其中某些信息可能已经过时。

隐藏层与深度学习

在现实中,判断一个物体,或者说对一个物体下定义,往往不能只从一个方面或两个方面观察。这时候,单个的Rosenblatt感知器已经无法胜任这样复杂的判断,是时候再增加一个神经元了。新增一个神经元,便增加了一个抽象的维度,每个维度通过不断地调整权重并进行激活,从而产生对输入的不同理解,最后再将这些抽象维度中的输出合并并降维得到最后的输出。而这些新添加的神经元,就被称之为隐藏层。

为了直观的看到效果,我还是使用了matplotlib进行绘图。这一次的w和b的值,我选择使用rand()函数生成随机数。并且为了之后的方便,将sigmoid函数(标准Logistic函数)和前向传播封装为两个函数。

import dataset
import matplotlib.pyplot as plt
import numpy as np

m = 100
xs, ys = dataset.get_beans(m)



plt.title("STF", fontsize=12)
plt.xlabel("B")
plt.ylabel("T")

plt.scatter(xs, ys)

def sigmoid(x):
	return 1/(1+np.exp(-x))



#第一层
#第一个神经元
w11_1 = np.random.rand()
b1_1 = np.random.rand()
#第二个神经元
w12_1 = np.random.rand()
b2_1 = np.random.rand()

#第二层
w11_2 = np.random.rand()
w21_2 = np.random.rand()
b1_2 = np.random.rand()

#前向传播
def forward(xs):
	#第一层第一个
	z1_1 = w11_1*xs + b1_1
	a1_1 = sigmoid(z1_1)
	#第一层第二个
	z2_1 = w12_1*xs + b2_1
	a2_1 = sigmoid(z2_1)
	#第二层(输出层)
	z1_2 = w11_2*a1_1 + w21_2*a2_1 + b1_2
	a1_2 = sigmoid(z1_2)
	return a1_2,z1_2,a2_1,z2_1,a1_1,z1_1

这样准备工作就完成了,接下来就是繁琐的隐藏层求导进行反向传播的过程。

for _ in range(5000):
	for i in range(100):
		x = xs[i]
		y = ys[i]
		#先来一次前向传播
		a1_2,z1_2,a2_1,z2_1,a1_1,z1_1 = forward(x)
		#反向传播
		#代价函数e
		e = (y-a1_2)**2

		deda1_2 = -2*(y - a1_2)
		da1_2dz1_2 = a1_2*(1 - a1_2)

		dz1_2dw11_2 = a1_1
		dz1_2dw21_2 = a2_1

		dedw11_2 = deda1_2*da1_2dz1_2*dz1_2dw11_2
		dedw21_2 = deda1_2*da1_2dz1_2*dz1_2dw21_2

		dz1_2db1_2 = 1
		dedb1_2 = deda1_2*da1_2dz1_2*dz1_2db1_2

		#隐藏层的第一个神经元
		dz1_2da1_1 = w11_2
		da1_1dz1_1 = a1_1*(1-a1_1)
		dz1_1dw11_1 = x

		dedw11_1 = deda1_2*da1_2dz1_2*dz1_2da1_1*da1_1dz1_1*dz1_1dw11_1
		dz1_1db1_1 = 1
		dedb1_1 = deda1_2*da1_2dz1_2*dz1_2da1_1*da1_1dz1_1*dz1_1db1_1

		#隐藏层的第二个神经元
		dz1_2da2_1 = w21_2
		da2_1dz2_1 = a2_1*(1-a2_1)
		dz2_1dw12_1 = x

		dedw12_1 = deda1_2*da1_2dz1_2*dz1_2da2_1*da2_1dz2_1*dz2_1dw12_1
		dz2_1db2_1 = 1
		dedb2_1 = deda1_2*da1_2dz1_2*dz1_2da2_1*da2_1dz2_1*dz2_1db2_1

		#梯度下降
		alpha = 0.03
		w11_2 = w11_2 - alpha*dedw11_2
		w21_2 = w21_2 - alpha*dedw21_2
		b1_2 = b1_2 - alpha*dedb1_2

		w12_1 = w12_1 - alpha*dedw12_1
		b2_1 = b2_1 - alpha*dedb2_1

		w11_1 = w11_1 - alpha*dedw11_1
		b1_1 = b1_1 - alpha*dedb1_1

经过漫长的求导与修改错误,最后再使用plt.clf()函数和plt.pause()函数相结合绘制动态图像,就得到了最终的结果。

hidden.gif

当隐藏层变得更多与更深,神经网络也会变得更加强大与智能。当我们设计出一个复杂程度恰当的神经网络,经过不断的训练过后,网络中的各个参数被调节成不同的值,而他们组成的整体,就可以近似出一个相当复杂的函数。

我们一般把隐藏层超过三层的网络称之为深度神经网络。隐藏层的神经元对样本的理解和提取的参数都太过微妙,我们能做的也只有设计一个网络,送入数据进行训练,如果效果好,那它就”起作用了“,效果不好就”没起作用“,只能再次调参,再来一次。这也是为什么深度学习被很多人戏称”炼丹“的原因。

本文作者:Ch1nfo

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!