二进制数组操作的数组维度必须匹配_【AI学习篇】实战深度学习(4):张量操作第一弹...

医工荟萃,不是萝卜开会,融合创新才是硬道理!

预计阅读时间: 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)。这种取编号的秘诀,荟荟称之为“编号从零始,包头不包尾”。

661292fa65fde4d3b97c396c7530a8b1.png

图 1

(2) 用“:”代替某维度的全部

如图2所示,我们指定了批量维度的取子集范围,像素维度因为都要取出,所以直接用“:”代替。

5b819568a05c4c31236bd510d089e766.png

图 2

(3) 按顺序省略全部都要取的维度

如图3所示,只在批量维度取子集,默认像素维度都要,那么两个像素维度的范围压根就不需要写。

ca756b07906f33698937bcc973ad177a.png

图 3

类似地,我们也可以取出图像的一个区域,如右下角的14*14的图像区域(图4), “14:”的意思就是从编号14的行/列开始直到最后一行/列。又如取出图像中心位置14*14的区域(图5),“7:-7”就是从编号7的行/列到编号28-7-1=20的行/列,依旧是“不包尾”

a09f48d29c46e18eb07bd307d7b4244d.png

图4

a6a2d21ce93014af10b3745cfdf40a68.png

图5

2. 张量逐元素运算

逐元素运算,顾名思义就是将张量的每个元素进行逐一运算,比如前面讲的非线性激活运算ReLU。如图6所示,在深度神经网络中,如果一个输入向量经过加权叠加后形成一个新向量,这个向量的每个元素需要依次进行ReLU运算进行非线性激活,形成输出向量输入下一层网络,即把每一个元素都和0比较一下,大于等于0的保持不变,小于0的都等于0。又或是需要将两个张量的元素对应一一相加。

2444b4ef648b3ef0f5fb1c4349a5b0cb.png

图 6 y向量的每个元素都要ReLU一下

使用Numpy通用函数可以把这种张量运算推送至底部的编译层,执行效率比起python本身的解释型操作效率高得多,运算速度飞快(不懂我在说啥的话,知道用Numpy数组进行张量运算非常快就行。)逐元素相加和逐元素ReLU运算实例如图7所示,其中np.arange(x,y)是用来生成一个从x到y,步长为1的1D张量(向量);接下来的maximum运算就是逐元素比大小(下例中每个元素分别和0比),保留较大的那一个,也就是咱们的ReLU了。此外对于如图8所例举的一般数学运算都可进行逐元素操作,当然不限于这些,荟荟并没有写全。

d22891d19460c23cd919919b35d1a358.png

图 7

647e8af78fa83032b2bb767d61caa4a7.png

图 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给出了一个形状不同的两个张量进行比大小的实例。

ca48b711589cbf6a6e52f6987f00a2b1.png

图 9

4a65f540b1655f788364d75d0a0fc45d.png

图 10

Sorry,写着写着又超时了,还好控制在6分钟。总结一下,本节主要讲了张量切片、逐元素运算和张量广播三种操作,下一讲再谈谈张量乘法又叫点积,还有张量变形,咱就算暂时基本够用了。更多numpy数组详细操作内容,推荐Jake VanderPlas的《Python数据科学手册》一书。

更多精彩内容,搜索并关注微信公众号"医工荟"。

需要本系列源代码的同学,请关注公众号,后台留言,荟荟会发给你哟。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值