图像 patch Embedding

本文介绍了一种将图像转换为一系列补丁的嵌入方法,该方法通过使用卷积层来实现。此过程能够有效地将输入图像分解为固定大小的补丁,并将其映射到高维空间中。
import torch
import torch.nn as nn


class PatchEmbed(nn.Module):
    """ Image to Patch Embedding
    """

    def __init__(self, img_size=224, patch_size=16, in_chans=3, embed_dim=768):
        super().__init__()
        img_size = (img_size, img_size)
        patch_size = (patch_size, patch_size)
        num_patches = (img_size[1] // patch_size[1]) * (img_size[0] // patch_size[0])
        self.img_size = img_size
        self.patch_size = patch_size
        self.num_patches = num_patches

        self.project = nn.Conv2d(in_chans, embed_dim, kernel_size=patch_size, stride=patch_size)

    def forward(self, x):
        B, C, H, W = x.shape
        # FIXME look at relaxing size constraints
        assert H == self.img_size[0] and W == self.img_size[1], \
            f"Input image size ({H}*{W}) doesn't match model ({self.img_size[0]}*{self.img_size[1]})."
        x = self.project(x)
        x = x.flatten(2)
        x = x.transpose(1, 2)
        return x


if __name__ == "__main__":
    x = torch.rand([1, 3, 224, 224])
    model = PatchEmbed()
    y = model(x)
    print(y.shape)

torch.Size([1, 196, 768])

Process finished with exit code 0
### 将 Patch Embedding 转换为图像 为了将 patch embedding 转换回原始图像,通常需要执行一系列逆操作。这些操作大致可以概括为以下几个方面: #### 1. 数据重塑 首先,假设输入的 patch embedding 形状为 `[batch_size, num_patches, embed_dim]`。由于 `embed_dim` 是由卷积层映射得到的一个高维特征空间,在反向转换过程中,必须先将其恢复成原来的通道数(通常是3)。这可以通过一个线性变换来完成。 ```python import torch.nn as nn class PatchEmbedToImage(nn.Module): def __init__(self, img_size=224, patch_size=16, in_chans=3, embed_dim=768): super().__init__() self.patch_size = patch_size self.num_patches = (img_size // patch_size)**2 # 定义一个线性层用于降维 self.linear_layer = nn.Linear(embed_dim, in_chans * (patch_size ** 2)) def forward(self, x): b, n, d = x.shape # 获取批次大小、补丁数量以及嵌入维度 assert n == self.num_patches and d == 768, "Input dimensions do not match expected values" # 使用线性层降低维度至原通道数乘以单个patch像素总数 patches_flattened = self.linear_layer(x) # 改变形状回到[B,N,C*P*P], 其中 P 表示 patch 大小 patches_reshaped = patches_flattened.view(b, n, -1, self.patch_size*self.patch_size).permute(0, 2, 1, 3) return patches_reshaped.reshape((b, -1, int(patches_reshaped.size(-1)**0.5), int(patches_reshaped.size(-1)**0.5))) ``` 这段代码定义了一个简单的 PyTorch 模型类 `PatchEmbedToImage`,它接受已经编码好的 patch embeddings,并尝试重构出接近原始尺寸的图像数据[^1]。 #### 2. 图像重组 上述过程结束后,还需要进一步处理才能获得完整的二维图像表示形式。具体来说就是把所有的小方块重新拼接在一起形成一张大图。这里的关键在于理解如何排列各个patches的位置关系,使其能够无缝对接构成整张图片。 对于给定的 `(H,W)` 像素级别的图像被划分为多个相同大小的小区域(即 patches),每个这样的子集都对应着特定的空间位置信息。因此,在重建阶段,应该按照原来划分时所遵循的方式依次放置每一个经过解码后的 patch 片段,最终合成一幅连贯一致的新图像。 需要注意的是,实际应用中的模型可能会更加复杂一些,可能涉及到更精细的设计细节比如正则化项的选择或是额外加入跳跃连接机制等等,但基本原理保持不变[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值