pytorch接口

本文介绍了PyTorch中的一些关键概念和操作,如线性层的通道处理,最大值和求和函数的使用,手动设置随机种子确保可复现性,F.softmax激活函数的应用,以及张量的拼接、展平和堆叠操作。此外,还讨论了截断正态分布初始化权重的方法和torch.unique函数的用法。
摘要由CSDN通过智能技术生成

本博客是本人用来记录零散知识的笔记,可能记得有点乱。

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(tensorsdim=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(inputdim) → 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(inputsorted=Truereturn_inverse=Falsereturn_counts=Falsedim=None

→ Tuple[TensorTensorTensor]

返回输入张量的唯一元素。

笔记

目前在指定 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)

对于 PyTorch,数据接口准备有多种方法,下面我将介绍三种常用的方法: 1. 自定义数据集类:你可以创建一个继承自 `torch.utils.data.Dataset` 的自定义数据集类,其中需要实现 `__len__` 方法返回数据集的大小,以及 `__getitem__` 方法根据索引返回数据集中的样本。这个类可以用来加载和预处理数据。 ```python import torch from torch.utils.data import Dataset class CustomDataset(Dataset): def __init__(self, data): self.data = data def __len__(self): return len(self.data) def __getitem__(self, idx): sample = self.data[idx] # 进行数据预处理 # 返回预处理后的样本 return sample ``` 2. 数据加载器:数据加载器是一个能够方便地迭代数据集的对象,可以使用 `torch.utils.data.DataLoader` 创建。你需要将自定义数据集对象传递给数据加载器,并指定一些参数,如批量大小、是否打乱数据等。 ```python from torch.utils.data import DataLoader dataset = CustomDataset(data) dataloader = DataLoader(dataset, batch_size=32, shuffle=True) ``` 3. 数据转换:你可以使用 `torchvision.transforms` 模块中的转换函数对数据进行预处理和增强操作。例如,你可以使用 `transforms.Compose` 将多个转换函数组合起来,并在数据加载时应用这些转换。 ```python from torchvision import transforms transform = transforms.Compose([ transforms.ToTensor(), # 将数据转换为张量 transforms.Normalize(mean=[0.5], std=[0.5]) # 标准化数据 ]) dataset = CustomDataset(data) dataloader = DataLoader(dataset, batch_size=32, shuffle=True, transform=transform) ``` 这些方法可以帮助你准备数据接口,以便在 PyTorch 中进行训练和评估。希望能对你有所帮助!如果有更多问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值