-------------------------
1.简单预测题
2.python代码
3.代码讲解
4.数学计算过程
-------------------------
想要更好的消化课程内容,不动手是不行的,所以写了这篇实验课程,课程内容也是参考了网络素材(很直观,也解释的很清楚),参考链接http://python.jobbole.com/82758/,我在这个基础之上加入了一些自己的理解,将程序执行的每个数学过程进行了梳理,方便记忆。整个代码使用python写的,需要一定的python基础。
一、简单预测题
1)题目
为了将原理表述清楚,本节拿一个简单的例子,并且用python进行编码实现。我们的训练数据只有4个,单个数据有3个维度,输入三个变量x1,x2,x3,然后输出1个结果数据y),如下图所示
考虑以上情形:给定三列输入,试着去预测对应的一列输出。 我们给的是比较少的训练数据,所以可以很容易就可以看出来里面的模型:第一列的输入和输出完全一致(在实际当中,有海量的数据 ,这个规则是很难发现出来)。
2)目标
我们的目标是建立一个分类方法y=f(x,w),通过上面的训练数据,结合反向传播算法,不断的优化,得到一个靠谱的w,这个w预测出来的值,要和实际值的误差尽量小,越小说明模型越精准。
3)方法
我们构建一个2层的神经网络,使用sigmoid函数进行计算,通过反向传播算法,不断优化和调整权重w的系数。
二、python代码
--------------------
import numpy as np
# 定义sigmoid function函数,deriv就可以得到它的导数
def nonlin(x,deriv=False):
if(deriv==True):
return x*(1-x)
return 1/(1+np.exp(-x))
# 数据数据集,每个数据集有三个变量,共4个数据实例
X = np.array([ [0,0,1],
[0,1,1],
[1,0,1],
[1,1,1] ])
# 定义输出数据集,为了方便编写,使用了转置T
y = np.array([[0,0,1,1]]).T
# 设定随机函数,随机种子为1
#初始化权重,是一个3行一列的向量
#进行训练
for iter in range(1000):
# forward propagation
l0 = X
#输出训练结果
l1 = nonlin(np.dot(l0,syn0))
#训练结果与真实结果比对,计算出损失值
l1_error = y - l1
# slope of the sigmoid at the values in l1
l1_delta = l1_error * nonlin(l1,True)
# 更新权重值
syn0 += np.dot(l0.T,l1_delta)
print("Output After Training:")
print(l1)
print(syn0)
-----------------------
下面是一次训练的结果(我们真实的结果是0,0,1,1,随机提取了一个训练结果)还是比较接近的
Output After Training:
三、代码讲解
1) 导入numpy 的线性代数工具库
import numpy as np
2) 定义sigmoid function函数,
如果deriv为true就可以得到它的导数,这个函数也可以为其他函数,这里我们选了sigmoid,他的特性是其倒数可以很容易起出来,若 Sigmoid 的输出值用变量 out 表示,则其导数值可简单通过式子 out *(1-out) 得到,这是非常高效的。
def nonlin(x,deriv=False):
if(deriv==True):
return x*(1-x)
return 1/(1+np.exp(-x))
3)初始化输入数据集和输出数据集
数据数据集,每个数据集有三个标量,共4个数据实例;# 定义输出数据集,为了方便编写,使用了转置T
X = np.array([ [0,0,1],
[0,1,1],
[1,0,1],
[1,1,1] ])
y = np.array([[0,0,1,1]]).T
4)设定随机函数,随机种子为1
我们的数字仍然会随机分布但是每次随机生成的方式都是一样的。这样就会让我们更容易的观察网络的改变。随机数种子对后面的结果一直有影响。同时,加了随机数种子以后,后面的随机数组都是按一定的顺序生成的。这个参数设置可以随意
5)初始化权重,权重初始值为随机数,是一个3行一列的向量
6)基于迭代的方式优化神经网络,进行训练
for iter in range(1000):
# 前向计算,我们的输入数据,记住X包含4个训练样例(4行)
l0 = X
7)输出训练结果
这一步用来进行预测。本质上来讲,我们首先让网络通过输入“尝试着”去预测输出。然后我们就研究怎么样每次循环都去逐步适应使得系统表现更好。这一行包含两个步骤。第一步用l0乘以syn0。第二步从sigmoid函数中获得输出
l1 = nonlin(np.dot(l0,syn0))
8)训练结果与真实结果比对,计算出损失值
现在l1对于每个输入有了一个“猜测”的输出。现在我们可以通过用真实值y减去猜测值l1来比较“猜测”的效果。l1_error是一个包含正数与负数的向量,揭示出当前的网络到底有多少误差。
l1_error = y - l1
# slope of the sigmoid at the values in l1
9)最关键部分,
l1_delta = l1_error * nonlin(l1,True)
先求出导数,之所以求出这个,前面的博文中已经讲明了,想象一下梯度的表达式
10)更新权重
syn0 += np.dot(l0.T,l1_delta)
print("Output After Training:")
syn0 =syn0+ np.dot(l0.T,l1_delta)
四、数学计算过程
实际优化过程中,会持续不断的进行,我们就选择其中一次优化过程进行分析
第一步,使用Sgmoid作为激活函数
第二步,定义输入矩阵x,输出矩阵y,权重矩阵syn0(这里的权重是随机选出来的)
第三步,将X赋给输入层l0
第四步,输入值是l0,通过sigmoid函数,计算出预测结果l1
第五步、计算预测输出和实际值偏差
第六步、计算预测输出的偏导(预测偏差*输入的偏导),这个结果
第七步,根据预测输出的偏导,调整syn0的值(反向传播)
计算出新的权重后,开始下一轮的优化,从权重调整的结果看,第一列的权重调整的是最多的,达到0.28,比其他两个0.03,0.12明显要搞出,这个也比较符合实际(理想模型就是第一列主要影响输出,其他2列影响结果)
领取专属 10元无门槛券
私享最新 技术干货