Pytorch阅读文档之reshape,view,flatten, transpose函数

本文详细介绍了PyTorch中张量重塑方法,包括reshape、view和flatten函数的使用技巧,通过实例演示了如何调整张量的形状,以及在多维数据处理中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Pytorch阅读文档之reshape,view,flatten函数

flatten函数

之前写过相关的文章,链接再此,对比总结会写在最后,看官别着急吼。

torch.reshape()函数

#reshape(*shape) → Tensor
#参数:
#shape (tuple of python:ints or int...) – 想要转换的形状
#返回具有与self相同的数据和元素数量但具有指定形状的张量。
#如果shape与当前形状兼容,则此方法返回一个视图。
#有关何时可以返回视图,请参见torch.Tensor.view()。view之后再说,先看reshape
torch.reshape(input, shape) → Tensor
#返回具有与input相同的数据和元素数量,但具有指定形状的张量。如果可能,返回的张量将是input视图。否则,它将是copy的版本。连续输入和具有兼容步幅的输入可以在不复制的情况下进行重塑,但是您不应该依赖复制与查看行为。
#某个尺寸可能为-1,在这种情况下,它是根据剩余尺寸和输入的元素数推断出来的。(后面会有栗子)
#参数:input (Tensor) – 原始的shape
#shape (tuple of python:ints) – 需要的shape
>>> a = torch.arange(4.)
>>> torch.reshape(a, (2, 2))
tensor([[ 0.,  1.],
        [ 2.,  3.]])
>>> b = torch.tensor([[0, 1], [2, 3]])
#只有一个-1的话,就是直接展开
>>> torch.reshape(b, (-1,))
tensor([ 0,  1,  2,  3])
#给定一个的时候,另外一个就能就算出来
>>> torch.reshape(b, (-1, 2))
tensor([[0, 1],
        [2, 3]])
>>>  b = torch.tensor([[[0, 1], [2, 3]], [[0, 1], [2, 3]], [[0, 1], [2, 3]]])
>>> torch.reshape(b, (-1, 2, -1))
RuntimeError: only one dimension can be inferred
>>> torch.reshape(b, (2, 2, -1))
tensor([[[0, 1, 2],
         [3, 0, 1]],

        [[2, 3, 0],
         [1, 2, 3]]])

torch.Tensor.view()函数

#view(*shape) → Tensor
#返回一个新张量,其数据与self张量相同,但shape是不同。 返回的张量共享相同的数据,并且必须具有相同数量的元素,但可能具有不同的大小。一个张量可以被view,new view的尺寸必须与其原始尺寸和stride兼容,也就是说每个新视图尺寸必须是原始尺寸的子空间,或者只能跨越原始的d,d+1,...,d+k这些要满足以下的连续性条件,stride[i]=stride[i+1]×size[i+1] 对于任意的i=0,...,k-1
#一个tensor必须是连续的,才能被contiguous()查看。
>>> x = torch.randn(4, 4)
>>> x.size()
torch.Size([4, 4])
>>> y = x.view(16)
>>> y.size()
torch.Size([16])
>>> z = x.view(-1, 8)  # the size -1 的位置是可以推断出来
>>> z.size()
torch.Size([2, 8])

>>> a = torch.randn(1, 2, 3, 4)
>>> a.size()
torch.Size([1, 2, 3, 4])
>>> b = a.transpose(1, 2)  # 交换第二维度和第三维度,改变了内存的位置
>>> b.size()
torch.Size([1, 3, 2, 4])
>>> c = a.view(1, 3, 2, 4)  # 不改变内存中的位置
>>> c.size()
torch.Size([1, 3, 2, 4])
>>> torch.equal(b, c) #所以不是一个
False
>>> torch.equal(a, c) #还是不是一个,不清楚官方给这个栗子想说明什么
False

#顺便说一下contiguous()
#返回一个包含与self张量相同数据的连续张量。如果self张量是连续的,则此函数返回self张量。其实就是返回一个结果
#torch.transpose(input, dim0, dim1) → Tensor
#返回张量,该张量是输入的转置版本。
#给定的尺寸dim0和dim1被交换。
#生成的张量与输入张量共享其基础存储,因此更改其中一个的内容将更改另一个的内容。
>>> x = torch.randn(2, 3)
>>> x
tensor([[ 1.0028, -0.9893,  0.5809],
        [-0.1669,  0.7299,  0.4942]])
#第一维度和第二维度转换
>>> torch.transpose(x, 0, 1)
tensor([[ 1.0028, -0.1669],
        [-0.9893,  0.7299],
        [ 0.5809,  0.4942]])
### Vision Transformer在PyTorch中的实现代码示例 以下是一个基于PyTorch的Vision Transformer(ViT)的基本实现代码。该代码展示了如何构建一个简单的ViT模型,包括Patch Embedding、Multi-Head Self-Attention和Feed-Forward Network等关键组件[^1]。 ```python import torch import torch.nn as nn import math class PatchEmbedding(nn.Module): def __init__(self, img_size=224, patch_size=16, in_channels=3, embed_dim=768): super().__init__() self.img_size = img_size self.patch_size = patch_size self.n_patches = (img_size // patch_size) ** 2 self.projection = nn.Conv2d(in_channels, embed_dim, kernel_size=patch_size, stride=patch_size) def forward(self, x): x = self.projection(x) # (batch_size, embed_dim, n_patches**0.5, n_patches**0.5) x = x.flatten(2).transpose(1, 2) # (batch_size, n_patches, embed_dim) return x class Attention(nn.Module): def __init__(self, dim, num_heads=12, qkv_bias=False): super().__init__() self.num_heads = num_heads head_dim = dim // num_heads self.scale = head_dim ** -0.5 self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias) self.proj = nn.Linear(dim, dim) def forward(self, x): B, N, C = x.shape qkv = self.qkv(x).reshape(B, N, 3, self.num_heads, C // self.num_heads).permute(2, 0, 3, 1, 4) q, k, v = qkv.unbind(0) attn = (q @ k.transpose(-2, -1)) * self.scale attn = attn.softmax(dim=-1) x = (attn @ v).transpose(1, 2).reshape(B, N, C) x = self.proj(x) return x class MLP(nn.Module): def __init__(self, in_features, hidden_features, out_features): super().__init__() self.fc1 = nn.Linear(in_features, hidden_features) self.act = nn.GELU() self.fc2 = nn.Linear(hidden_features, out_features) def forward(self, x): x = self.fc1(x) x = self.act(x) x = self.fc2(x) return x class Block(nn.Module): def __init__(self, dim, num_heads, mlp_ratio=4.0, qkv_bias=False): super().__init__() self.norm1 = nn.LayerNorm(dim) self.attn = Attention(dim, num_heads=num_heads, qkv_bias=qkv_bias) self.norm2 = nn.LayerNorm(dim) self.mlp = MLP(dim, int(dim * mlp_ratio), dim) def forward(self, x): x = x + self.attn(self.norm1(x)) x = x + self.mlp(self.norm2(x)) return x class VisionTransformer(nn.Module): def __init__(self, img_size=224, patch_size=16, in_channels=3, embed_dim=768, depth=12, num_heads=12, mlp_ratio=4.0, qkv_bias=True, num_classes=1000): super().__init__() self.patch_embed = PatchEmbedding(img_size, patch_size, in_channels, embed_dim) self.cls_token = nn.Parameter(torch.zeros(1, 1, embed_dim)) self.pos_embed = nn.Parameter(torch.zeros(1, self.patch_embed.n_patches + 1, embed_dim)) self.blocks = nn.Sequential(*[Block(embed_dim, num_heads, mlp_ratio, qkv_bias) for _ in range(depth)]) self.norm = nn.LayerNorm(embed_dim) self.head = nn.Linear(embed_dim, num_classes) def forward(self, x): B = x.shape[0] x = self.patch_embed(x) cls_tokens = self.cls_token.expand(B, -1, -1) x = torch.cat((cls_tokens, x), dim=1) x += self.pos_embed x = self.blocks(x) x = self.norm(x) x = self.head(x[:, 0]) return x ``` 此代码实现了一个基本的Vision Transformer架构,适用于图像分类任务。它包含以下几个主要部分: - `PatchEmbedding`:将输入图像分割为固定大小的patches,并将其映射到嵌入空间。 - `Attention`:实现多头自注意力机制。 - `MLP`:实现前馈网络。 - `Block`:组合注意力机制和前馈网络,形成ViT的一个基本块。 - `VisionTransformer`:整合所有组件,构建完整的ViT模型。 ### 注意事项 在实际使用中,可能需要对模型进行微调或优化以适应特定任务。此外,可以参考PyTorch官方文档或相关开源项目以获取更多实现细节[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值