在深度学习模型训练中 add 和 concat操作有什么区别?
add:逐元素按值相加
concat:按照指定的维度进行张量堆叠
- torch.cat在行方向上堆叠:
- torch.cat在列方向上堆叠:
ai = torch.arange(na, device=targets.device).float().view(na, 1).repeat(1, nt) 执行逻辑
- torch.arange: 分配一个张量为左闭右开区间[0, na),默认是int类型, device参数可以将张量加载到指定的设备上
- float: 将数据类型转换成float型
- view(na, 1):view方法用于改变张量形状,而不改变数据。view(na, 1)表示由一维张量变为二维张量。第二维的大小为1
- repeat(1, nt):表示在第二维的方向上重复nt次
targets = torch.cat((targets.repeat(na, 1, 1), ai[:, :, None]), 2) 的执行逻辑
- targets.repeat(na, 1, 1) :targets 在行的方向上堆叠na次
- ai[:, :, None]:用来扩展张量ai的维度,张量ai增加第三个维度,并且大小为1
- torch.cat(…, 2):将两个张量沿着第三个维度拼接
torch.tensor(p[i].shape)[[3, 2, 3, 2]] 执行逻辑
- p[i].shape:从p中找到索引为i的张量,并返回该张量的shape,用元组表示
- torch.tensor(p[i].shape):将元组类型的元素转换成tensor类型
- [[3,2,3,2]]:这是索引列表,返回索引指向的元素值
torch.max(r, 1. / r).max(2)[0] 执行逻辑
- torch.max(r, 1. / r):
t = t[j] t的维度是[3, 42, 7] 的float张量 j是[3 , 42]的bool型张量,这是怎么过滤的?
j = torch.stack((torch.ones_like(j), j, k, l, m) 执行逻辑
- torch.ones_like(j):创建一个与张量j形状相同的新张量,其中所有元素都是1。
- (torch.ones_like(j), j, k, l, m):这是一个包含五个张量的元组。这些张量将被堆叠在一起。为了成功堆叠,所有张量的形状必须相同,除了堆叠的维度。
torch.cat([pxy, pwh], dim=-1)
-1表示最后一个维度
pair_wise_iou.shape[1]
获取张量pair_wise_iou 第二个维度的大小
F.one_hot(this_target[:, 1].to(torch.int64), self.nc)
将this_target[:, 1]上所有的元素值,用one-hot向量的形式表示,向量的维度为self.nc
unsqueeze(1)
第二个维度(索引为1)处添加一个大小为1的新维度。这通常用于增加张量的维度数。
先贴一段yolov7中回归预测值的代码
def __call__(self, p, targets, imgs): # predictions, targets, model
device = targets.device
lcls, lbox, lobj = torch.zeros(1, device=device), torch.zeros(1, device=device), torch.zeros(1, device=device)
bs, as_, gjs, gis, targets, anchors = self.build_targets(p