1)该文章整理自网上的大牛和机器学习专家无私奉献的资料,具体引用的资料请看参考文献。
2)本文仅供学术交流,非商用。所以每一部分具体的参考资料并没有详细对应。如果某部分不小心侵犯了大家的利益,还望海涵,并联系博主删除。
3)博主才疏学浅,文中如有不当之处,请各位指出,共同进步,谢谢。
4)此属于第一版本,若有错误,还需继续修正与增删。还望大家多多指点。大家都共享一点点,一起为祖国科研的推进添砖加瓦。
学到现在,你需要知道常用的python的编译器,推荐使用anaconda而不是官方的python,这样的话更容易安装各种第三方库,如何安装可以看一下这个博客——Windows10 下 Anaconda和 PyCharm 的详细的安装教程(图文并茂)。
至于IDE的话,pycharm 适合于大型项目的编写和调试,Jupyter Notebook 适合于学习和数据挖掘探索,这里我们就快速地学习一下 Jupyter Notebook 工具。
在你的计算机上,运行 cell 的键盘快捷方式是 Ctrl + enter。但是也可以使用 shift + enter 来运行 cell,不过这样会默认跳转到下一个代码区域。
所以,如果只是运行相对较小的工作并且才刚刚启动你的台式电脑或笔记本电脑,这种情况应该是不会发生的。但是,如果你看见错误信息,比如 Kernel 已经中断或者其他信息,你可以试着重启 Kernel,这样就简单地重启程序了。
你会发现这种交互式的 shell 命令,在 Notebooks 是非常有用的,能使你快速地实现代码并且查看输出结果,便于学习,同时还可以记录在这个过程中的想法。好好学习它的使用,你会发现更多的惊喜。
那么,现在假设我们想要计算不同食物中不同营养成分中的卡路里百分比,应该怎么做?
以计算苹果中的碳水化合物卡路里百分比含量为例,首先计算苹果(Apples)(100g)中三种营养成分卡路里总和 56+1.2+1.8 = 59
,然后用 56 / 59 = 94.9%
算出结果。可以明显地看出苹果(Apples)中的卡路里大部分来自于碳水化合物(Carb),而牛肉(Beef)则不同。对于其他食物,计算方法类似。首先,按列求和,计算每种食物中(100g)三种营养成分总和,然后分别用不用营养成分的卡路里数量除以总和,计算百分比。
那么,能否在向量化(深度学习入门笔记(四):向量化)的基础上用代码完成这样的一个计算过程呢?
当然是可以的,假设上图的表格是一个4行3列的矩阵 AA,记为 A3×4A3×4,接下来使用 Python 的 numpy 库完成这样的计算。使用两行代码就可以完成整个过程,第一行代码对每一列进行求和,第二行代码分别计算每种食物每种营养成分的百分比。
在 jupyter notebook 中输入如下代码,按 Ctrl + Enter 运行,输出如下:
sum
的参数 axis=0
表示求和运算按列执行,之后会详细解释。接下来计算百分比,这条指令将 3×43×4 的矩阵 AA 除以一个 1×41×4 的矩阵,得到了一个 3×43×4 的结果矩阵,这个结果矩阵就是要求的百分比含量。
A.sum(axis = 0)
中的参数 axis
。axis用来指明将要进行的运算是沿着哪个轴执行,在numpy中,0轴是垂直的,也就是列,而1轴是水平的,也就是行。 而第二个 A / cal.reshape(1, 4)
指令则调用了 numpy 中的广播机制。这里使用 3×43×4 的矩阵 AA 除以 1×41×4 的矩阵 calcal。技术上来讲,其实并不需要再将矩阵 calcal reshape
(重塑)成 1×41×4,因为矩阵 calcal 本身已经是 1×41×4 了。但是当我们写代码的过程中出现不确定矩阵维度的时候,通常会对矩阵进行重塑来确保得到想要的列向量或行向量。重塑操作 reshape
是一个常量时间的操作,时间复杂度是 O(1)O(1),它的调用代价极低,所以使用是没问题的,也推荐大家使用。那么一个 3×43×4 的矩阵是怎么和 1×41×4 的矩阵做除法的呢?来看一些广播的例子:
再看下一个例子。
下面是最后一个例子。
广播机制的一般原则如下:
首先是 numpy 广播机制
这里的广播和播音广播是完全不同的,它的要求是什么呢?什么样的条件下可以使用广播?
要求:如果两个数组的后缘维度的轴长度相符或其中一方的轴长度为1,则认为它们是广播兼容的。广播会在缺失维度和轴长度为1的维度上进行。
如何计算后缘维度的轴长度?可以使用代码 A.shape[-1]
即矩阵维度元组中的最后一个位置的值,就是矩阵维度的最后一个维度,比如卡路里计算的例子中,矩阵 A3,4A3,4 后缘维度的轴长度是4,而矩阵 cal1,4cal1,4 的后缘维度也是4,故满足了后缘维度轴长度相符的条件,可以进行广播。广播会在轴长度为1的维度上进行,轴长度为1的维度对应 axis=0
,即垂直方向,矩阵 cal1,4cal1,4 沿 axis=0
(垂直方向)复制成为 calTemp3,4calTemp3,4 ,之后两者进行逐元素除法运算。
简单概括总结就是,先变成一样大,再逐元素除法。
然后解释图中的例子
矩阵 Am,nAm,n 和矩阵 B1,nB1,n 进行四则运算,后缘维度轴长度相符,符合条件,可以广播,广播沿着轴长度为1的轴进行,即 B1,nB1,n 广播成为 Bm,n′Bm,n′ ,之后做逐元素四则运算。
矩阵 Am,nAm,n 和矩阵 Bm,1Bm,1 进行四则运算,后缘维度轴长度不相符,但其中一方轴长度为1,符合条件,可以广播,广播沿着轴长度为1的轴进行,即 Bm,1Bm,1 广播成为 Bm,n′Bm,n′ ,之后做逐元素四则运算。
矩阵 Am,1Am,1 和常数 RR 进行四则运算,后缘维度轴长度不相符,但其中一方轴长度为1,符合条件,可以广播,广播沿着缺失维度的轴进行,缺失维度就是 axis=0
,轴长度为1的轴是 axis=1
,即 RR 广播成为 Bm,1′Bm,1′ ,之后做逐元素四则运算。
最后总结一下 broadcasting
,可以看看下面的图:
Python 的特性允许你使用 广播(broadcasting) 功能,这是 Python 的 numpy 程序语言库中最灵活的地方,但这是程序语言的优点,也是缺点。
优点的原因,在于它们创造出语言的表达性,Python 语言巨大的灵活性使得你仅仅通过一行代码就能做很多事情。
缺点的原因,由于广播巨大的灵活性,有时候对于广播的特点以及广播的工作原理这些细节不熟悉的话,可能会产生很细微或者看起来很奇怪的 bug。
为了演示 Python-numpy 的一个容易被忽略的效果,特别是怎样在 Python-numpy 中构造向量,来做一个快速示范。
首先设置 a=np.random.randn(5)a=np.random.randn(5),这样会生成存储在数组 aa 中的5个高斯随机数变量;然后输出 aa,从屏幕上可以得知,此时 aa 的 shape(形状) 是一个 (5,)(5,) 的结构同样地,a.Ta.T 的 shape 也是这样的。这在 Python 中被称作 一个一维数组。它既不是一个行向量也不是一个列向量,这也导致它有一些不是很直观的效果。
比如 aa 和 aa 的转置阵最终结果看起来一样,shape 也是一样的。但是输出 aa 和 aa 的转置阵的内积,你可能会想,aa 乘以 aa 的转置,返回的可能会是一个矩阵。但如果这样做,你只会得到一个数。
(5,)
、(n,)
或者其他一维数组的数据结构。相反,设置 aa 为 (5,1)(5,1),这样就是一个5行1列的向量。在先前的操作里 aa 和 aa 的转置看起来一样,而现在这样的 aa 变成一个新的 aa 的转置,并且它是一个行向量。当输出 aa 的转置时有两对方括号,而之前只有一对方括号,所以这就是 1行5列的矩阵和一维数组的差别。除了,输入确定维度的矩阵或向量之外,还有一件事,就是如果你不能完全确定一个向量的维度,建议你扔一个 断言语句(assertion statement) 进去。这样,就可以确保在这种情况下是否是一个 (5,1)(5,1) 向量了,或者说是一个列向量。
这个我在 大话卷积神经网络CNN(干货满满) 中讲过,目前主流的是 Google的TensorFlow、Facebook的pytorch 还有 百度的paddlepaddle,如果是研究的话,我建议使用TensorFlow,因为它更好理解一下基础原理,而不是单纯的调包侠。大话卷积神经网络CNN(干货满满) 博客中也写了相关的资源推荐,这里就不详细说了。
联系客服