本博客是本人用来记录零散知识的笔记,可能记得有点乱。
pytorch冷知识
1、除了MLP和bn层好像都是要特征作用于最后一维,MLP,maxpool、bn层要将特征放在batch号的后边。
linear:channel放在最后
性质
torch.max()
就是求最大值
l=torch.tensor([[1,2,3],[4,6,5]])
torch.max(l,1)
torch.return_types.max(
values=tensor([3, 6]),
indices=tensor([2, 1]))
第二个参数dim理解为要压缩的维度是哪一维,比如dim=1,那么列要被压缩(2,3)要变成(2)即一行挑出最大的,如果是行即dim=0那么(2,3)要变为(3),就是一列挑出最大的
torch.sum()
相较于普通sum[]
l1=torch.tensor([[1,2,3],[4,6,5]])
sum(l1)
tensor([5, 8, 8])
普通sum就相当于将每个元素进行加和即变化为[1,2,3]+[4,6,5]=[5, 8, 8],严格按照去一层括号,逗号变加号的规则来运算
l1=torch.tensor([[1,2,3],[4,6,5]])
torch.sum(l1)
```¥¥
> tensor(21)
torch.sum不加dim就是所有元素取和
```python
l1=torch.tensor([[1,2,3],[4,6,5]])
torch.sum(l1,1)
tensor([ 6, 15])
加dim相当于压缩,和 torch.max()同理
torch.manual_seed()
使本cell的随机数都确定
torch.manual_seed(1412)
batchdata1=DataLoader([1,2,3],1,shuffle=True)
batchdata2=DataLoader([1,2,3,4],1,shuffle=True)
for i in batchdata1:
print(i)
print('\n')
for i in batchdata2:
print(i)
tensor([2])
tensor([1])
tensor([3])
第二结果
tensor([4])
tensor([1])
tensor([2])
tensor([3])
运行几次都是不变的,值得注意只对本单元格生效
F.softmax()
作为激活函数,他并不会改变输入特征的维度
重要参数dim,参考
https://blog.csdn.net/sunyueqinghit/article/details/101113251
意思就是dim等于哪一个维度,就按哪一个维度将元素进行划分,比如2维
1,2,3
4,5,6
,我dim=1就是按列进行划分,1列就是一个整体,1和2,3的概率相加为1,4和5,6的概率相加为一,实际运用中特征经常为列即dim=1,就是按特征划分,不同特征的加和概率为1
torch.cat(tensors, dim=0, *, out=None)
拼接函数,Concatenates the given sequence of seq
tensors in the given dimension. All tensors must either have the same shape (except in the concatenating dimension) or be empty.
对指定维度进行拼接,除了拼接的维度,其他的维度必须完全相同
import torch
a=[[1,2,3]]
b=[[4,5,6],[7,8,9]]
a=torch.tensor(a)
b=torch.tensor(b)
print(a.shape,b.shape)
result=torch.cat([a,b],0)
print(result.shape)
torch.Size([1, 3]) torch.Size([2, 3])
torch.Size([3, 3])
拼接0维,其他维度要完全相同,然后0维上进行相加
torch.unsqueeze(input, dim) → Tensor
将指定维度扩展到第几维,将其他维度往后排一位
import torch
b=[[4,5,6],[7,8,9]]
b=torch.tensor(b)
print(b.shape)
print(torch.unsqueeze(b,-1).shape)
torch.Size([2, 3])
torch.Size([2, 3, 1])
此时扩展最后一维
b有两维,那么第二个参数的可选值为0~2,0就是插在头部,2为插在尾部,和-1一个作用
torch.nn.identity()
torch.nn.identity()方法详解_sigmoidAndRELU的博客-CSDN博客
就是占个位置,输入是啥,直接给输出,不做任何的改变,减少了if none的一些判断
torch.nn.Sequential
顺序容器。模块将按照它们在构造函数中传递的顺序添加到其中。或者,可以传入一个OrderedDict
到模块。该forward()
方法Sequential
。接受任何输入并将其转发到它包含的第一个模块,然后它为每个后续模块按顺序将输出“链接”到输入,最后返回最后一个模块的输出。
Sequential
与手动调用一系列模块相比, a 提供的价值在于它允许将整个容器视为单个模块,Sequential中
每个模块都是 的注册子模块。
比如我定义
self.model = nn.Sequential(
Conv2d(1,20,5),
nn.ReLU(),
Conv2d(20,64,5),
nn.ReLU()
)
那么里面四个模块最终都是model模块下的子模块,也就是名称前缀都有model.conv1 moudel.relu1等等,像这种子模块不是传入字典的,就等于没有指定模块名字,会自动分配名字,比如conv1 ,relu1等等。
模块名字取决于self后的名字,比如 self.model在模块中就叫做model
timm 或pytorch的trzuounc_normal_
截断正态分布,参数
Args:
tensor: an n-dimensional `torch.Tensor`
mean: the mean of the normal distribution
std: the standard deviation of the normal distribution
a: the minimum cutoff value
b: the maximum cutoff value
return
tensor:也就是传入的tensor,实际上不接收返回值也可,因为传入的tensor已经改变了
Examples:
>>> w = torch.empty(3, 5)
>>> nn.init.trunc_normal_(w)
作用:就是将mean,std生成的一个正态分布,且截断到[a,b]的区间,并将传入的tensor在这个区间上生成数字,这个tensor的每个位置生成的数字都在[a,b]之间,这个tensor的全部位置都生成好数字之后将该tensor返回
图片来自pytorch中trunc_normal_原理_音程的博客-CSDN博客
torch.cat与torch.stack
这两个很相近,都是将多个tensor整合起来
torch.cat
和numpy的一样,都是沿特征拼接
要求除了被拼接的维度,其他维度必须完全一致
a的shape为[3,4,5]
b的shape为[3,2,5]
对1维度进行拼接,得到[3,6,5]
torch.stack
也是拼接也可以叫堆叠,并多出一维,要求所有的tensor 的shape都相等
a的shape为[3,4,5]
b的shape为[3,4,5]
对0维度进行拼接,得到[2,3,4,5]
对1维度进行拼接,得到[3,2,4,5]
torch.cumsum(input, dim, *, dtype=None, out=None) → Tensor
返回累加,第i个数是前i个(当然包括这个位置的数本身的加和)
torch.unique(input, sorted=True, return_inverse=False, return_counts=False, dim=None)
→ Tuple[Tensor, Tensor, Tensor]
返回输入张量的唯一元素。
笔记
目前在指定 dim 的 CUDA 实现和 CPU 实现中, 无论排序参数如何, torch.unique总是在开头对张量进行排序。排序可能会很慢,所以如果您的输入张量已经排序,建议使用它来 torch.unique_consecutive()避免排序。
输入
-
input ( Tensor ) – 输入张量
-
sorted ( bool ) – 在作为输出返回之前是否按升序对唯一元素进行排序。
-
return_inverse ( bool ) – 是否还返回原始输入中元素最终出现在返回的唯一列表中的索引,也就是最后一个。
-
return_counts ( bool ) – 是否还返回每个唯一元素的计数。
-
dim ( int ) – 应用unique的维度。如果
None
,则返回扁平化输入的唯一性。默认:None
返回
张量或张量元组包含
1 输出output(张量):唯一标量元素的输出列表。
2 inverse_indices ( Tensor ):(可选)size=input。如果
return_inverse
为真,将有一个额外的返回张量(与输入相同的形状)表示原始输入中的元素映射到输出中的索引;否则,此函数将只返回一个张量也就是input对应的该元素在output中的哪个位置,也就是在output哪个下标。
如果在input中这两个元素相同,那么他们有相同的indices
3 counts ( Tensor ):(可选)如果
return_counts
为 True,是对output中每一个元素的计数(与 output 或 output.size(dim) 相同的形状,如果指定了 dim)表示每个唯一值或张量的出现次数。
例子:
>>> output = torch.unique(torch.tensor([1, 3, 2, 3], dtype=torch.long))
>>> output
tensor([1, 2, 3])
>>>output, inverse_indices,count = torch.unique(
torch.tensor([1, 3, 2, 3], dtype=torch.long), sorted=True, return_inverse=True,return_counts=True)
>>> output
tensor([1, 2, 3])
>>> inverse_indices
tensor([0, 2, 1, 2])
count
tensor([1, 1, 2])
>>> output, inverse_indices = torch.unique(
torch.tensor([[1, 3], [2, 3]], dtype=torch.long), sorted=True, return_inverse=True)
>>> output
tensor([1, 2, 3])
>>> inverse_indices
tensor([[0, 2],
[1, 2]])
torch_geometric/nn/pool/voxel_grid.py voxel_grid
将所有的点分簇,其实还是根据voxel去划分点,一个voxel中的为1簇,不同batch有不同的voxel编号,注意这里的一个voxel是包含左下点,也就是边界只有左下角的边界的点属于自己,其他的边界的点都不属于自己。
pos通常指点的坐标x,y,z
batch指batch编号
size:指我们指定voxel 的大小
start指定voxel的起始划分点,从哪开始划分,如果不指定默认从点云中左下的边界开始,min(x),min(y)...
end 指定最大的边界,如果设置为none,就设置最大的x,y,z为边界
示例
import torch
from torch_cluster import grid_cluster
pos = torch.tensor([[0., 0.], [2., 2.],[4.9,4.9],[5.0,5.0],[6.0,6.0],[6,3],[7,4]])
size = torch.Tensor([5, 5])
cluster = grid_cluster(pos, size)
print(cluster)
结果
tensor([0, 0, 0, 3, 3, 1, 1])
import torch
from torch_cluster import grid_cluster
pos = torch.tensor([[0., 1.], [1., 0.],[2., 2.],[4.9,4.9],[5.0,5.0],[6.0,6.0],[6,3],[7,4]])
size = torch.Tensor([5, 5])
cluster = grid_cluster(pos, size)
print(cluster)
tensor([0, 0, 0, 0, 3, 3, 1, 1])
边界确实是min(x),min(y)...
源码
def voxel_grid(pos, batch, size, start=None, end=None):
r"""Voxel grid pooling from the, *e.g.*, `Dynamic Edge-Conditioned Filters
in Convolutional Networks on Graphs <https://arxiv.org/abs/1704.02901>`_
paper, which overlays a regular grid of user-defined size over a point
cloud and clusters all points within the same voxel.
Args:
pos (Tensor): Node position matrix
:math:`\mathbf{X} \in \mathbb{R}^{(N_1 + \ldots + N_B) \times D}`.
batch (LongTensor): Batch vector :math:`\mathbf{b} \in {\{ 0, \ldots,
B-1\}}^N`, which assigns each node to a specific example.
size (float or [float] or Tensor): Size of a voxel (in each dimension).
start (float or [float] or Tensor, optional): Start coordinates of the
grid (in each dimension). If set to :obj:`None`, will be set to the
minimum coordinates found in :attr:`pos`. (default: :obj:`None`)
end (float or [float] or Tensor, optional): End coordinates of the grid
(in each dimension). If set to :obj:`None`, will be set to the
maximum coordinates found in :attr:`pos`. (default: :obj:`None`)
:rtype: :class:`LongTensor`
"""
if grid_cluster is None:
raise ImportError('`voxel_grid` requires `torch-cluster`.')
pos = pos.unsqueeze(-1) if pos.dim() == 1 else pos #没用
num_nodes, dim = pos.size()
size = size.tolist() if torch.is_tensor(size) else size
start = start.tolist() if torch.is_tensor(start) else start#将二者转换为list
end = end.tolist() if torch.is_tensor(end) else end
size, start, end = repeat(size, dim), repeat(start, dim), repeat(end, dim)#都变为长度为3
pos = torch.cat([pos, batch.unsqueeze(-1).type_as(pos)], dim=-1) #batch号拼接在pos后面
size = size + [1] #为啥加个1
start = None if start is None else start + [0]
end = None if end is None else end + [batch.max().item()]
size = torch.tensor(size, dtype=pos.dtype, device=pos.device)#转换类型
if start is not None:
start = torch.tensor(start, dtype=pos.dtype, device=pos.device)
if end is not None:
end = torch.tensor(end, dtype=pos.dtype, device=pos.device)
return grid_cluster(pos, size, start, end)#把cluster看看
def repeat(src, length):
#将src扩展到length长度
def repeat(src, length):
if src is None:#sec为none还返回none
return None
if isinstance(src, numbers.Number):
return list(itertools.repeat(src, length))
if (len(src) > length):
return src[:length]
if (len(src) < length):#如果少于length,则最后1个元素重复length - len(src))次
return src + list(itertools.repeat(src[-1], length - len(src)))
return src #如果sec刚好长度为length,那刚好返回
grid_cluster
def grid_cluster(pos: torch.Tensor, size: torch.Tensor,
start: Optional[torch.Tensor] = None,
end: Optional[torch.Tensor] = None) -> torch.Tensor:
"""A clustering algorithm, which overlays a regular grid of user-defined
size over a point cloud and clusters all points within a voxel.
Args:
pos (Tensor): D-dimensional position of points.
size (Tensor): Size of a voxel in each dimension.
start (Tensor, optional): Start position of the grid (in each
dimension). (default: :obj:`None`)
end (Tensor, optional): End position of the grid (in each
dimension). (default: :obj:`None`)
:rtype: :class:`LongTensor`
.. code-block:: python
import torch
from torch_cluster import grid_cluster
pos = torch.Tensor([[0, 0], [11, 9], [2, 8], [2, 2], [8, 3]])
size = torch.Tensor([5, 5])
cluster = grid_cluster(pos, size)
"""
return torch.ops.torch_cluster.grid(pos, size, start, end)