- 企业级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=1739588768-biuLP349kqYhdDEX7fvynZhdkosq0fOf-0-d7c21f7471511a9c9ef07cfa194bc184)
在Spyder集成开发环境中运行代码ANN_V1.py,运行结果如下:
![](https://epubservercos.yuewen.com/A2E645/19549640608913906/epubprivate/OEBPS/Images/Figure-P127_130853.jpg?sign=1739588768-eGEK63az39CvuMizee3cT80m6NaZWH9H-0-6919d2a234f12d5784e7ead35633eb36)
第一个预测值是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=1739588768-NPXekeeFBk8OuTemIrzMdW2jyPcH8taf-0-f3fe1c119fde9d2bd66feb607faa9e22)
输入特征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=1739588768-JCN8gdw2RDktQqWZbZctHi0ucE3z4I8i-0-6559a4f44e64aff509dfcbbc10b9cb08)
图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=1739588768-FtUtpUJWDpMAG0IKdHn8WCxD9oqdwDZI-0-50d65086bbad3bb895bf6e00673e83c1)
图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=1739588768-CRb8zWNzjIensIPJosRlOmVlqJrP3MhN-0-f9e44f680065970b49ad75e209a259ee)
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=1739588768-3iOVJFwK592M9yJFXmaaHwdT0WnIqNsa-0-74ee2c633efd5976314ad44c19665e12)
矩阵对象包括很多方法,其中一个方法是矩阵转置(transpose),在IPython console栏中输入help(X.T),可查询矩阵转置的使用方法。矩阵转置是将行变成列,将列变成行。矩阵转置的示例如下:
![](https://epubservercos.yuewen.com/A2E645/19549640608913906/epubprivate/OEBPS/Images/Figure-P129_130858.jpg?sign=1739588768-vvRY62i3NAbUywgZ2HdWZJsqHrb8g9lA-0-569138d81d367096a3132f041f36ee4b)
第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=1739588768-O0LbaWURRf3ztaiG8m958WHVDpqWCIp2-0-72a444e695532cc367f6e5446620cfcb)
图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=1739588768-H1XxYz6wDigxn4hAvS53VUHYN55tjZVD-0-75d08cd9ff6996e3e5ee305cee9cadd0)
图8-4 不做转置运算
![](https://epubservercos.yuewen.com/A2E645/19549640608913906/epubprivate/OEBPS/Images/Figure-P130_22321.jpg?sign=1739588768-2z6u1FYzVzldwaYNzWFEr5ocrnEA8yor-0-8567783693fd38cf5ab0951445da9fe4)
图8-5 转置运算、不做转置运算的对比
在Spyder右下角的IPython console栏,在提示符后输入y,查询y的值,如图8-6所示。
![](https://epubservercos.yuewen.com/A2E645/19549640608913906/epubprivate/OEBPS/Images/Figure-P130_130861.jpg?sign=1739588768-5JDVM2vUogfwUToWTZSIuY9KpRU8fZNo-0-b47cc62615441ec94fb40176d68b7672)
图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=1739588768-NhgFe1Xm8Fs3ZyZ7edSEC0w6fAjAW2Ha-0-9b23b19c3e73dede48abdc5e09c57231)
图8-7 np.array方法
![](https://epubservercos.yuewen.com/A2E645/19549640608913906/epubprivate/OEBPS/Images/Figure-P131_22348.jpg?sign=1739588768-gtFkVohsqR5UZaYWIyLunmkC0vWsR6wC-0-c3e2f3f0626f6775f846084db7089385)
图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=1739588768-YnCtO16az1m1LwI2DFhWhcQZPcAQQ81H-0-25c65a2bff1fa02a052092e851a165bf)
图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=1739588768-asOiGlDlkfAbtn4s67MIpN0yh6wfe8A7-0-a665cb546384d30bffc0dadcb5e45e05)