- 企业级AI技术内幕:深度学习框架开发+机器学习案例实战+Alluxio解密
- 王家林 段智华编著
- 1563字
- 2021-03-26 23:54:00
8.1 使用矩阵编写人工智能框架
ANN_V1.py的源代码如下:
![](https://epubservercos.yuewen.com/A2E645/19549640608913906/epubprivate/OEBPS/Images/Figure-P126_130851.jpg?sign=1739036237-z4qaArfAejMH4WI9RJOOaLtWwrASvpam-0-a103feb5414b7d3e4d863b55c797dff0)
在Spyder集成开发环境中运行代码ANN_V1.py,运行结果如下:
![](https://epubservercos.yuewen.com/A2E645/19549640608913906/epubprivate/OEBPS/Images/Figure-P127_130853.jpg?sign=1739036237-RaoZJKvornhuFJd8JUfbUAKIEkvMG0zc-0-dba0df621eec4d3f1956f57464187961)
第一个预测值是0.009 664 49,实际值是0;第二个预测值是0.007 865 06,实际值是0;第三个预测值是0.993 588 98,实际值是1;第四个预测值是0.992 119 57,实际值是1。预测的结果很不错。
ANN_V1.py的输入数据如下:
![](https://epubservercos.yuewen.com/A2E645/19549640608913906/epubprivate/OEBPS/Images/Figure-P127_130854.jpg?sign=1739036237-2wVbinfkQvnPeklcmyRsNGGRTpf5D115-0-b922a0244ca5b022402eadc643fb4043)
输入特征x包括4行3列数据,分别为[0,0,1]、[0,1,1]、[1,0,1]、[1,1,1],第1行是[0,0,1],对应的y值是0;第2行是[0,1,1],对应的y值是0;第3行是[1,0,1],对应的y值是1;第4行是[1,1,1],对应的y值是1。根据x中每一行的数据,预测y中对应的值,判断预测值是否准确。
如图8-1所示,输入数据x是自变量(Independent Variable),输出数据y是因变量(Dependent Variable)。从数学的角度,例如y=ax+b,x是自变量,y就是因变量,y随着x的改变而改变。自变量x有3列,x1、x2、x3;y只有1列。
![](https://epubservercos.yuewen.com/A2E645/19549640608913906/epubprivate/OEBPS/Images/Figure-P127_21915.jpg?sign=1739036237-I1jpSJxHJgJZCFaiax1LDgqWzHL6r1nG-0-a6448c20a756a127822b9d4a2e3dd5cd)
图8-1 输入及输出数据
NumPy通过np.array方法创建矩阵。如何判断一个变量是否为矩阵?在Spyder的Variable explorer栏中,如果变量是(4,3),表明是一个矩阵;如果是(4,),表明是一个数组,如图8-2所示。
![](https://epubservercos.yuewen.com/A2E645/19549640608913906/epubprivate/OEBPS/Images/Figure-P128_21976.jpg?sign=1739036237-qZpud47qRSopBypXuPDBdH5VsaevPTz2-0-dad6459d036f98d0245360a0c780fb72)
图8-2 查询变量
通过np.array创建一个矩阵,在Spyder中将鼠标指针放在np.array上,按Ctrl+鼠标左键即可查看np.array的源代码,将打开numerictypes.py的代码文件。
numerictypes.py的源代码如下:
![](https://epubservercos.yuewen.com/A2E645/19549640608913906/epubprivate/OEBPS/Images/Figure-P128_130855.jpg?sign=1739036237-hieVpVxjoTcqq7b5pzyMgTjKaVD8xC8f-0-34c8ded6efdb2f200ed84d48aa8f4e71)
ANN_V1.py的输入数据X是一个矩阵,在Spyder的Ipython console栏中通过print (dir(X))命令查询矩阵X的方法如下:
![](https://epubservercos.yuewen.com/A2E645/19549640608913906/epubprivate/OEBPS/Images/Figure-P128_130856.jpg?sign=1739036237-E8gzVi7cFEJxWjOGeH7choKLgntwKDps-0-2b1c9be39f8853aad0736c416e555f7f)
矩阵对象包括很多方法,其中一个方法是矩阵转置(transpose),在IPython console栏中输入help(X.T),可查询矩阵转置的使用方法。矩阵转置是将行变成列,将列变成行。矩阵转置的示例如下:
![](https://epubservercos.yuewen.com/A2E645/19549640608913906/epubprivate/OEBPS/Images/Figure-P129_130858.jpg?sign=1739036237-6cYb3hQ0jKkmSZapWMAn5xnuB3S1aY4t-0-4aa3c54841b9bfa63eaa620a79a013f5)
第1个示例中的x是2行2列的数据,第1行是1.、2.,第2行是3.、4.,第1列是1.、3.,第2列是2.、4.。对x进行转置以后,行变成列,列变成行,第1行的1.、2.就变成了第1列的1.、2.,第2行3.、4.就变成了第2列3.、4.。
第2个示例中的x是一个数组,只有1行数据1.、2.、3.、4.,对x进行转置以后,x仍是1.、2.、3.、4.。
例如ANN_V1.py中y=np.array([[0,0,1,1]]).T的值,转置以后变成了矩阵[[0],[0],[1],[1]],如图8-3所示。
![](https://epubservercos.yuewen.com/A2E645/19549640608913906/epubprivate/OEBPS/Images/Figure-P129_22296.jpg?sign=1739036237-0rVVKY1ov6fhis2YiXv10cEC9fgW6SxW-0-81258c6b31c256278185df1cef2a2255)
图8-3 y转置矩阵
为理解转置的作用,我们将ANN_V1.py中的y=np.array([[0,0,1,1]]).T的转置去掉,变成y=np.array([[0,0,1,1]]),y是np.array创建的数组,这里y变成了一行数据。从数值的角度,y是一个二维数组,包含一行四列的数据,运行结果如图8-4所示。
将y=np.array([[0,0,1,1]])代码改回y=np.array([[0,0,1,1]]).T,再次运行ANN_V1.py,矩阵转置将一行变成了一列,对比结果如图8-5所示,左侧是转置运算以后的结果,右侧是未做转置运算的结果。
![](https://epubservercos.yuewen.com/A2E645/19549640608913906/epubprivate/OEBPS/Images/Figure-P130_22311.jpg?sign=1739036237-vPM9CBjwDmbJtoKQzhC03ROZvW7asaZZ-0-bc1d4a30cf6306d24eb15083175767b2)
图8-4 不做转置运算
![](https://epubservercos.yuewen.com/A2E645/19549640608913906/epubprivate/OEBPS/Images/Figure-P130_22321.jpg?sign=1739036237-ohytcrXaBD2xlNLHKeMkYukQ0c3pd0eT-0-32d4a5f5872d98f4e4753b9d291fdec8)
图8-5 转置运算、不做转置运算的对比
在Spyder右下角的IPython console栏,在提示符后输入y,查询y的值,如图8-6所示。
![](https://epubservercos.yuewen.com/A2E645/19549640608913906/epubprivate/OEBPS/Images/Figure-P130_130861.jpg?sign=1739036237-zJUtps2SzeTt1xbr5v4KtLWQ8EABmVl6-0-33c33b1ea4ae68358686113342682f0b)
图8-6 y值查询
y的表现形式是一个4行1列的数组。
为了加深对矩阵转置运算的理解,我们对x=np.array([1.,2.,3.,4.])代码进行测试,x的输出结果是array([1., 2., 3., 4.]),如图8-7所示。
然后进行x.T转置运算,此时x.T的计算结果仍然是array([1.,2.,3.,4.]),在Spyder的Variable explorer栏中查看变量x的值,x在代码中声明的是一维数组类型(4,),对x进行转置操作以后没有变化,一维数组没有将行变成列,如图8-8所示。
可以使用NumPy声明简单的一维数组,但使用NumPy定义的二维数组都是矩阵。在机器学习中都采用矩阵的方式,转置操作本身是对矩阵的操作,矩阵转置将矩阵的行变成列。
![](https://epubservercos.yuewen.com/A2E645/19549640608913906/epubprivate/OEBPS/Images/Figure-P131_22340.jpg?sign=1739036237-8XnXxRtPNhbzvH7RK5cAeu8AhTqoCTkx-0-aef80e39b1b9dcb397cf55177f925d3f)
图8-7 np.array方法
![](https://epubservercos.yuewen.com/A2E645/19549640608913906/epubprivate/OEBPS/Images/Figure-P131_22348.jpg?sign=1739036237-riL1zkn3qdqiDRSpYBLzr9P7qy5yyVkm-0-3e621b62e30e0f8f0fc96f79463125c3)
图8-8 x.T转置运算
构建一个矩阵y=np.array([[1,2,3,4]])。y.T的转置运算和x.T不一样,x=np.array([1.,2.,3.,4.])中只有一对中括号,表明是一个一维数组,一维数组转置运算没有将行变成列;而y=np.array([[1,2,3,4]])中有2对中括号,表示是一个二维数组,不是一个矩阵。矩阵转置运算将行变成了列,如图8-9所示。
![](https://epubservercos.yuewen.com/A2E645/19549640608913906/epubprivate/OEBPS/Images/Figure-P131_22360.jpg?sign=1739036237-BHHpJy7o9jZPLWhOeRPxOEb1Yx0Egomd-0-c8af14b08acc72a335580ec684a503d4)
图8-9 矩阵转置运算
在ANN_V1.py代码中,layer0是输入层,layer1是隐藏层,输入层的数据通过和权重的计算,结果到达隐藏层,隐藏层有一个Sigmoid激活函数的操作。神经网络是一个前向传播、反向传播的训练过程,前向传播使用Sigmoid函数对数据进行处理,反向传播是对Sigmoid函数进行求导,导数是数值的变化度,就是对结果的负责程度。
nonlin函数对Sigmoid激活函数进行了封装,nonlin函数的第二个参数deriv使用了布尔值,默认值是False,将Sigmoid作为激活函数,在前向传播中使用;如果传入参数deriv为True,则对Sigmoid激活函数求导,在反向传播的时候使用,判断哪些特征对当前的误差结果负有更大的责任。
![](https://epubservercos.yuewen.com/A2E645/19549640608913906/epubprivate/OEBPS/Images/Figure-P132_130862.jpg?sign=1739036237-gxLA6baxZlmsjlSZSoFIGJxn4EGQpHJf-0-f8064ec511ecd762a5adbe30df84bfee)