boradcasting简而言之有两大特点:(1)功能类似于上期讲的expand,可以实现维度扩展。(2)但它不需要复制数据,因此可以极大的节省内存空间。
boradcasting的实现主要有以下两个步骤点:(1)先从最小的维度上进行匹配,如果没有则会在前面插入一个新的维度。(2)将新加的维度扩展成需要的维度。
如想把[32, 1, 1] broadcasting成 [4, 32, 28, 28],需要经过以下过程:
[32, 1, 1] => [1, 32, 1, 1] => [4, 32, 28, 28]
在图片处理过程中,维度的意义依次为[图片数量,单张图片的通道,单张图片的高,单张图片的宽],因此按照其意义一般将图片矩阵从左向右的顺序定义为大维度至小维度。
因此本例中broadcasting处理过程是先将3维扩展成4维,再将按维度从小到大的顺序依次扩展。
各矩阵的size一致后,才可以进行加减计算。
使用broadcasting的好处在于可以满足实际的运算需求,并且可以极大的节省人力和计算量。如在计算一个[4, 32, 8]的矩阵相加运算时需要1024次计算,而使用broadcasting向矩阵上增加一个数值时,只需要一次计算就可以啦。
broadcasting的应用
如[4, 3, 32, 32]
(1) +[32, 32] :可以理解为每一张图片上都加一个基底(base)。
(2) +[3, 1, 1] :对每个channel通道上都叠加一个像素值,如RGB通道,弥补某一属性。
(3) +[1, 1, 1, 1] :对所有照片都加一数值,进行抬高等扩展过程。
合并与分割是pytorch中常用的操作,本节介绍几个常用API
(1) .cat (拼接函数)
(2) .stack (拼接函数)
(3) .split (分割函数,按长度分割)
(4) .chunk (分割函数,按数量分割)
下面依次介绍用法
.cat .cat(tensors, dim) 使用时需要给出tensors和合并位置的dim
import torch
a = torch.rand(4, 3, 28, 28)
b = torch.rand(5, 3, 28, 28)
c = torch.cat([a, b], dim=0)
# c是a和b在dim=0位置上的合并, 因此在batch_size上进行了4+5=9
print(c.shape)
输出为
torch.Size([9, 3, 28, 28])
如将上式中的dim=0改为dim=1,输出变回报错
c = torch.cat([a, b], dim=1)
print(c.shape)
RuntimeError: invalid argument 0: Sizes of tensors must match except in dimension 1. Got 4 and 5 in dimension 0 at ..\aten\src\TH/generic/THTensor.cpp:711
因此在进行合并操作时,必须确保其他维度上的数据相同。
在不同维度上进行合并时,要具有实际物理意义。
与.cat相对应的是.stack,.stack也可以完成.cat的相关操作,但是会创建一个新的维度。
其API为:.stack(tensors, dim)
举例说明
a = torch.rand(3, 28, 28)
b = torch.rand(3, 28, 28)
c = torch.stack([a, b], dim=0)
# a和b分别是单张的带有3通道、28*28像素点的照片,通过stack操作在batch_size上将两组数据合并,成了两张照片。
print(c.shape)
输出
torch.Size([2, 3, 28, 28])
.stack必须保持其他维度上的size相同,这点与.cat近似。
.cat和.stack都是重要的函数,用于满足具体场景下的实际需求。
本文分享自 python pytorch AI机器学习实践 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!