医工荟萃,不是萝卜开会,融合创新才是硬道理!
预计阅读时间: 6 分钟
上一讲,荟荟介绍了什么是张量,即矩阵向各个维度的扩展。这一讲,我们来说一说张量的常见操作和运算,主要包括:张量切片、逐元素运算、广播、张量乘法、变形。这五种操作在深度学习里最最常见,当然张量的运算远不止这5种,还有拼接、迭代、卷积等等,so many。篇幅有限,本讲主要介绍深度学习里最常用的五种中的前三种,其他的运算在实际应用中遇到了再学习也不迟,打好根基,见招拆招。下面容荟荟一一道来。
1. 张量切片(取子集)
根据上一讲的介绍,张量是层层叠叠的一个大家伙,1D张量(向量)的构成元素是0D张量(标量),2D张量(矩阵)的构成元素是1D张量(向量), 3D张量就是一堆2D张量矩阵构成,可以类似的向更高维度的张量拓展。那么对于这么一个大家伙,除了整体把握,我们肯定想时不时地看看它的局部,这种操作就是切片(Slicing),就是用小刀割一部分下来瞅瞅,荟荟称之为取子集。
在keras中,张量使用Numpy数组表示,所以张量的切片就是Numpy的切片。下面用一个具体实例来讲解一下比较常用的切片操作。
还是以第二讲中的Mnist数据集为例(首先使用第二讲中同样的方法加载Minst数据集)。该数据集是由60000张28*28的灰度图像构成的,也就是说它的shape属性是(60000,28,28),其中60000是批量维度,代表有60000个样本、第一个28是像素行、第二个28像素列。现在我们只想把其中的第11张到第100张(共90个)取出来,可以有三种方式进行操作。
(1) 指定每个维度的取值范围:
操作方法如图1所示,需要注意,每个维度都是从0开始编号的,第11张到第100张,是10:100, 包含编号10但不包含编号100。同理,像素全部都取的话就是0:28,包含编号为0像素,但是不包含编号28(本来就一共28个像素,即从编号0到编号28-1)。这种取编号的秘诀,荟荟称之为“编号从零始,包头不包尾”。
(2) 用“:”代替某维度的全部
如图2所示,我们指定了批量维度的取子集范围,像素维度因为都要取出,所以直接用“:”代替。
(3) 按顺序省略全部都要取的维度
如图3所示,只在批量维度取子集,默认像素维度都要,那么两个像素维度的范围压根就不需要写。
类似地,我们也可以取出图像的一个区域,如右下角的14*14的图像区域(图4), “14:”的意思就是从编号14的行/列开始直到最后一行/列。又如取出图像中心位置14*14的区域(图5),“7:-7”就是从编号7的行/列到编号28-7-1=20的行/列,依旧是“不包尾”。
2. 张量逐元素运算
逐元素运算,顾名思义就是将张量的每个元素进行逐一运算,比如前面讲的非线性激活运算ReLU。如图6所示,在深度神经网络中,如果一个输入向量经过加权叠加后形成一个新向量,这个向量的每个元素需要依次进行ReLU运算进行非线性激活,形成输出向量输入下一层网络,即把每一个元素都和0比较一下,大于等于0的保持不变,小于0的都等于0。又或是需要将两个张量的元素对应一一相加。
使用Numpy通用函数可以把这种张量运算推送至底部的编译层,执行效率比起python本身的解释型操作效率高得多,运算速度飞快(不懂我在说啥的话,知道用Numpy数组进行张量运算非常快就行。)逐元素相加和逐元素ReLU运算实例如图7所示,其中np.arange(x,y)是用来生成一个从x到y,步长为1的1D张量(向量);接下来的maximum运算就是逐元素比大小(下例中每个元素分别和0比),保留较大的那一个,也就是咱们的ReLU了。此外对于如图8所例举的一般数学运算都可进行逐元素操作,当然不限于这些,荟荟并没有写全。
3. 张量广播(Broadcasting)
看到这里,有一个疑问没有解决,如果两个输入张量形状一样,进行逐元素运算完全没有问题,那如果两个输入张量形状不一样,逐点运算如何进行?很贴心的是,Numpy具有这种防止运算歧义的机制,叫做广播(Broadcasting),也就是将形状较小的张量进行扩张,以匹配形状较大的张量。其基本规则为:
(1) 如果两个张量的维度不一样,那么小维度的张量形状会在最左边补1。比如输入x的形状是(20,10), y的形状是(10,)则先把y变成(1,10)。
(2) 如果两个张量形状在任何一个维度都不匹配,那么张量的形状会沿着维度为1的维度扩展以匹配另一个张量的形状。接着上面的例子,y为1的维度重复20次,y形状变成(20,10),这样就和x匹配了。
(3) 如果两个数组的形状在任何一个维度上都不匹配,且没有任何一个维度等于1,则会引发异常。
看上去有点晕对不对,没关系,研究一下图9就很好理解了。图10给出了一个形状不同的两个张量进行比大小的实例。
Sorry,写着写着又超时了,还好控制在6分钟。总结一下,本节主要讲了张量切片、逐元素运算和张量广播三种操作,下一讲再谈谈张量乘法又叫点积,还有张量变形,咱就算暂时基本够用了。更多numpy数组详细操作内容,推荐Jake VanderPlas的《Python数据科学手册》一书。
更多精彩内容,搜索并关注微信公众号"医工荟"。
需要本系列源代码的同学,请关注公众号,后台留言,荟荟会发给你哟。