可以和b站视频配合观看。
1.如何给张量命名?
可以这样做:
import torch
_ = torch.tensor([0.2126,0.5428,0.1475],names=['c'])
接着会报以下的warning:大致的意思就是,这个names的功能还在试验阶段,不建议在重要环节使用。
ipython-input-20-b0d73aac2096:2: UserWarning: Named tensors and all their associated APIs are an experimental feature and subject to change. Please do not use them for anything important until they are released as stable. (Triggered internally at …/c10/core/TensorImpl.h:1758.)
_ = torch.tensor([0.2126,0.5428,0.1475],names=[‘c’])
2.如何使用张量的命名?
以【将三位彩色照片转化为灰白照片】为任务,来了解如何使用:
(1)常规方式
首先定义一个图片img_t(355),其值是随机化得来的。
import torch
#一张彩色的图片一般是3通道(rgb),这里定义大小为5*5
img_t = torch.randn(3,5,5) # shape [channels, rows, columns]
#随机赋予rgb的权重:红色0.2126,绿色0.5428,蓝色0.2446
weights = torch.tensor([0.2126,0.5428,0.2446])
再定义一个batch_t用以对比,加入了batch_size在第0维(235*5)
batch_t = torch.randn(2,3,5,5) # shape [batch, channels, rows, columns]
将彩色变成灰白的思路即使-3维上的rgb值取平均,可以看到最后的结果变成了5*5的,原来rgb各对应一个值,现在三者取平均转化成了一个值:
#将channels维度上的值取平均,变成灰度
#这里用"-3"是因为通常多个维度中,channels的都排在-3的位置上
img_gray_naive = img_t.mean(-3)
img_gray_naive.shape
>>>torch.Size([5, 5])
同理,batch_t:
batch_gray_mean = batch_t.mean(-3)
batch_gray_mean.shape
>>>torch.Size([2, 5, 5])
刚刚是直接加和取平均,现在使用加权平均:
weights是一个1维张量,如果想和img_t(3x5x5)的张量相乘,需要扩展两个维度
weights = torch.tensor([0.2126,0.5428,0.2446])
unsqueezed_weights = weights.unsqueeze(-1).unsqueeze(-1)
unsqueezed_weights.shape
>>>torch.Size([3, 1, 1])
img_weights = (img_t * unsqueezed_weights)
img_weights.shape
>>>torch.Size([3, 5, 5])
在batch_t这里我本身是有困惑的,为什么上一步需要将weights扩展到3维,而这里却不需要扩展成4维呢?答案参见
batch_weights = (batch_t * unsqueezed_weights)
batch_weights.shape
>>>torch.Size([2, 3, 5, 5])
将-3维度即channels求和,即得到了灰色图片
img_gray_weights = img_weights.sum(-3)
batch_gray_weighted = batch_weights.sum(-3)
batch_gray_weighted.shape
>>>torch.Size([2, 5, 5])
还有介绍另一个函数:爱因斯坦sum函数einsum(),它可以帮助我们更便捷的将两个维度不同的的张量对应相乘计算。
(2)einsum()函数
#爱因斯坦sum函数
#'...chw,c->...hw' 是自己给维度名的名字,主要是为了说明需要操作的位置
img_gray_weighted_fancy = torch.einsum('...chw,c->...hw',img_t,weights)
img_gray_weighted_fancy.shape
>>>torch.Size([5, 5])
(3)使用张量的命名
首先给权重起名channels,weights_name为1维张量:
#起名
weights_name = torch.tensor([0.2126,0.5428,0.2446],names = ['channels'])
weights_name
再给需要进行加权平均的对象对应维度起名:
img_named = img_t.refine_names(...,'channels','rows','columns')
batch_named = batch_t.refine_names(...,'channels','rows','columns')
效果如下:
batch_namesd本身有4维,因为只命名了最后3个维度,所以未命名部分标记为None:
维度对齐
因为weights只有一维并且名字叫"channels",在于img_named相乘计算时是不符合计算规则的,因而需要维度对齐,扩展到3维.
weights_aligned = weights_name.align_as(img_named)
weights_aligned
#扩展到了3维,多了rows,columns
此时就可以进行对应的计算了。