今天我在B站上无意间看到了关于卷积神经网络相关的视频,出于好奇,我连续看了好几个这样的视频,同时也激起了我对这方面的兴趣,毕竟也学了这么久的python,这点代码量也难不倒我,所以就有了接下来的故事。
关于卷积这个概念我不做太多介绍,形象的总结几个字就是将两个积分的图像卷起来,如图
接下来直接上代码:
from numpy import array, exp, random, dot
X = array([[0, 0, 1], [1, 1, 1], [1, 0, 1], [0, 1, 1]])
y = array([[0, 1, 1, 0]]).T
random.seed(1)
# 随机生成三行一列的随机数,也就是默认的权重,范围在0~1
weight = random.random((3, 1)) * 2 - 1
for i in range(10000):
# 采用矩阵点乘法将生成的随机数列与这个3 X 4矩阵逐一相乘
z = dot(X, weight)
# 使用Sigmoid公式,将生成的矩阵的值控制在0-1之间
output = 1 / (1 + exp(-z))
# 计算出当前的值和之间的值之间的差距
error = y - output
# 参照Sigmoid公式中计算斜率
slope = output * (1 - output)
# 计算增量
delta = error * slope
# 更新权重
weight += dot(X.T, delta)
# print(weight)
# 给一组新的数据,看看我们训练出来的模型能不能求出正确的值
print((1 / (1 + exp(-dot([[1, 0, 0]], weight)))))
大家可以直接复制到自己的编译器上运行,其中的dot()
函数是将一块矩阵点的列表跟另外的列表进行相乘,得到一个新的矩阵列表。exp()函数则是用来计算e的负x次幂,下面就是代码中用到的Sigmoid函数,他的作用主要是降低误差,广泛应用于深度学习中:
然后是关于题目的说明:
小花等4人喜欢一起去看电影,但是每次人总是到不齐,以下是其中四次情况
那么假设第五次:
问:第五次小明去没去?
可能有人要说了:这不是有手就行?还需要思考?大家看小明跟小花的规律,是不是一目了然。但是我要说,人的大脑有着近100亿的神经元,跟只会认0跟1的计算机相比那不知强了多少倍,要想让计算机通过程序算出来,可不能靠直觉,一定要有方法。刚刚放上去的代码就是这种方法,我们称它为单节点的神经网络,相当于人类的一个神经元。
接下来是关于代码的讲解:
1. 加载数据
from numpy import array, exp, random, dot
x = array([[0, 0, 1], [1, 1, 1], [1, 0, 1], [0, 1, 1]])
y = array([[0, 1, 1, 0]]).T
首先导入程序需要的基础函数库,这些都是python自带的,无需手动安装;
X的值想必大家都看出来了,他分别对应了小花、小美、小李3人的四次数据,然后将需要计算学习的小明的数据单独赋值给另一个列表y,末尾引用的.T
意思是将列表从一行转换成一列;
2. 初始化权重
random.seed(1)
# 随机生成三行一列的随机数,也就是默认的权重,范围在0~1
weight = random.random((3, 1)) * 2 - 1
我们将小花、小美、小李分别用ABC代替,那么计算权重的公式就是:A * W1 + B * W2 + C * W3,相当于就是求他们三人分别对小明产生的影响。但是我们并不知道要用多大的数字来当权重,所以用1作为随机数的种子,每次循环都会用它来随机生成三个0~1的小数;
3. 正向推测
# 采用矩阵点乘法将生成的随机数列与这个3 X 4矩阵逐一相乘
z = dot(X, weight)
# 使用Sigmoid公式,将生成的矩阵的值控制在0-1之间
output = 1 / (1 + exp(-z))
dot函数前面已经说过了,就是将一个MN的矩阵列表,也就是二维列表,和我们随机的权重列表(我们已经将它转化成一行且一共有三个值,刚好与X的3 * 4的结构对应)进行一行一行的相乘,就能得到一个新的一维列表;再用Sigmoid函数将列表的数值“矫正”,使其值永远都在0~1之间,方便我们计算,大家想想,如果最后求出来的值是一个小到几十大到几百的数,那我们又该如何来判断他的权重呢?
4. 计算误差
# 计算出当前的值和的值之间的差距
error = y - output
# 参照Sigmoid公式中计算斜率
slope = output * (1 - output)
# 计算增量
delta = error * slope
y的值对应的就是小明的数据,我们要让这个模型去学习,就一定要先给它一些数据;用这个数据列表减去上面求出来的值output
,看看我们有多“错”,错了多少。再用这个差值乘以Sigmoid()
函数中的另一个重要的概念:斜率 ;
大家都知道我们计算这么多就是为了向变量y这个列表里的数据靠拢,但是伴随着我们的循环次数的增多,我们的权重与正确答案的距离也会越来越小,所以我们不能每一次尝试的时候都迈一样大的步子,也就是说,我们迈步子的值要越来越小。然后就是计算出增量了,这里不做赘述。
5. 更新增量
weight += dot(X.T, delta)
我们将X这个矩阵列表的每一列转换成一行,刚好对应每个人的四次数据,再用dot函数将求出来的增量与X这个矩阵列表逐一相乘,这就相当于是将每个人每次的值乘以增量来求出每个人对小明每次来不来应该负多大的“责任”,最后用这个值来更新权重。
到此,我对这段代码的讲解就结束了。
当然了,这和卷积神经网络可差得远,假如这个单节点神经网络在地表层,那么卷积神经网络一定就在外太空,所以要做出那种能自主学习的模型,还得更加深入的学习才行。我也是才开始接触这个东西,还有很多不会的地方。如果我说的有不对的地方,还望见谅!