【传知代码】掩码自回归编码器法(论文复现)

news2024/11/20 15:19:36

前言:在探索现代数据科学的前沿领域时,掩码自回归编码器法(Masked Autoencoder,简称MAE)无疑是一个引人注目的亮点。这一技术,凭借其独特的训练机制和卓越的性能,已经在图像识别、自然语言处理以及众多其他领域展现出强大的潜力。今天,我们就来深入剖析掩码自回归编码器法的核心原理、应用前景以及它如何引领我们迈向更加智能的数据分析新时代。

本文所涉及所有资源均在传知代码平台可获取

目录

概述

演示效果

核心代码

写在最后


概述

        掩码自动编码器MAE是一款具有可扩展性的计算机视觉自我监控学习器。它可以从一个不完整或错误的图像序列中提取出感兴趣的信息来进行分类和识别,在图像处理领域得到了广泛的应用。MAE的核心策略包括:对输入图像的随机补丁进行屏蔽,并对遗失的像素进行重建,这一策略是基于两个主要的设计思路,如下:

1)一种非对称编码器-解码器架构,其中编码器只对可见的补丁子集进行操作(没有掩码标记)

2)一个轻量级解码器,它根据潜在表示和掩码标记重建原始图像

        MAE的掩码自编码器是一种简单地自编码方法,它在给定原始信号的部分观测值的情况下重建原始信号。和所有的自编码器一样,MAE有一个将观察到的信号映射到潜在表示的编码器,以及一个从潜在表示重建原始信号的解码器,如下图所示:

与经典的自编码器不同,MAE采用了一种非对称设计,允许编码器仅对部分观察到的信号进行操作(没有掩码标记),并采用了一个轻量级解码器,该解码器根据潜在表示和掩码标记重建全部信号,以下是对相关概念的讲解:

掩码

        与ViT方法相似,MAE将图像分为有规律的非重叠部分,然后MAE对补丁的子集进行取样,并对剩下的补丁进行屏蔽或移除。对于每个候选补丁而言,它是由一系列不同大小和位置分布的样本构成的集合,因此可以用多个阈值来确定这些样本的权重。MAE的取样方法相当直接,它对补丁进行随机取样,不做替换,并按照均匀的方式分布。为了提高效率和减少计算量,提出一种基于均匀抽样技术的快速修复算法。随机采样具有较高的掩码比(即去除补丁的比例),这在很大程度上减少了数据冗余。因此,这导致了一个问题,即不能仅通过从相邻的明显补丁中进行外推来解决。通过均匀分布,可以避免中心偏差(即图像中心附近的掩码补丁越多)。最后一个高度稀疏的输入为设计一个高效的编码器提供了可能性。

MAE编码器

        MAE中编码器为ViT,但仅适用于可见和不屏蔽补丁。与标准ViT类似,MAE中编码器也是通过增加位置嵌入线性投影嵌入补丁再经过一系列Transformer块对结果集进行处理。然而,MAE的编码器只对全集的一小部分(例如25%)进行操作。带MAE可以只利用小部分计算与内存,就可以训练出很大的编码器。

MAE解码器

        MAE解码器输入为编码器可见补丁与掩码令牌构成一个完整令牌集合。每一个掩码标记为共享和学习向量,表示是否有丢失补丁需要被预测。MAE将位置嵌入添加到该全集中的所有令牌中,如果没有这一点,掩码令牌将没有关于其在图像中的位置信息。MAE解码器仅在预训练期间用于执行图像重建任务(仅使用编码器生成识别用图像表示。)因此,可以以独立于编码器设计的方式灵活地设计解码器架构。

重建目标

        MAE通过预测每个掩码补丁的像素值来重建输入,解码器输出中的每个元素是表示补丁的像素值的矢量。解码器末层为线性投影且输出通道个数与块内像素值个数相等。重建解码器输出,形成重建图像。在像素空间中,MAE的损失函数用于计算重建图像与原始图像的均方误差(MSE),这与BERT是一致的,而MAE仅用于计算掩码补丁上的损失。MAE也研究了以各屏蔽补丁归一化像素为重构对象的变体。具体而言,MAE在一个Patch上计算所有像素的均值与标准差并用其归一化这个patch。以归一化像素为重构对象,改善表示质量。

简单实现

        首先,MAE为每个输入补丁生成一个标记(通过添加位置嵌入的线性投影),接下来,MAE随机打乱令牌列表,并根据屏蔽比率删除列表的最后一部分。这个过程为编码器生成一小部分标记,相当于采样补丁而不进行替换。编码后,MAE将一个掩码令牌列表添加到编码补丁列表中,并对这个完整列表纪念性unshuffle(反转随机混洗操作),以将所有标记与其目标对齐。编码器应用于该完整列表(添加了位置嵌入)。如前所述,不需要稀疏运算,这种简单地实现引入了可忽略不计的开销,因为混洗和取消混洗操作很快。

该编码方式参考如下论文内容,地址 :

演示效果

通过如下的方式对项目进行相关部署:

#  linux系统下python=3.7
conda create -n mae python=3.7
conda activate mae

# 下载torch
wget https://download.pytorch.org/whl/cu116/torch-1.13.0%2Bcu116-cp37-cp37m-linux_x86_64.whl
pip install 'torch的下载地址'
# 下载torchvision
wget https://download.pytorch.org/whl/cu116/torchvision-0.14.0%2Bcu116-cp37-cp37m-linux_x86_64.whl
pip install 'torchvision的下载地址'

pip install timm==0.4.5
pip install ipykernel
pip install matplotlib
pip install tensorboard

MAE随机掩码图像实现的效果如下:

核心代码

随机掩码的实现逻辑如下:

def random_masking(self, x, mask_ratio):
        """
        Perform per-sample random masking by per-sample shuffling.
        Per-sample shuffling is done by argsort random noise.
        x: [N, L, D], sequence
        """
        N, L, D = x.shape  # batch, length, dim
        # 确定需要保存多少个patch
        len_keep = int(L * (1 - mask_ratio))
        # [1,196] 用batch此时输入的图片可能不止一个,196表示patch的个数
        noise = torch.rand(N, L, device=x.device)  # noise in [0, 1]      
        # sort noise for each sample 
        # 默认按升序排序,此时返回的是序号,首先获取从低到高排列的序号
        ids_shuffle = torch.argsort(noise, dim=1)  # ascend: small is keep, large is remove
        # 获取ids_shuffle从低到高排列的序号,这样就能还原原始的noise的情况
        ids_restore = torch.argsort(ids_shuffle, dim=1)

        # keep the first subset
        ids_keep = ids_shuffle[:, :len_keep] # 保存数据少的情况
        # [1,49,1024] dim=0 按列进行索引,dim=1按行进行索引,获取x的取值
        x_masked = torch.gather(x, dim=1, index=ids_keep.unsqueeze(-1).repeat(1, 1, D))

        # generate the binary mask: 0 is keep, 1 is remove
        mask = torch.ones([N, L], device=x.device)
        mask[:, :len_keep] = 0
        # unshuffle to get the binary mask 为0表示没有被掩码,1表示被掩码
        # 将是否被掩码通过mask表示出来
        mask = torch.gather(mask, dim=1, index=ids_restore)

        return x_masked, mask, ids_restore

编码器的实现逻辑如下:

def forward_encoder(self, x, mask_ratio):
        # embed patches [1,3,224,224]->[1,196,1024]
        x = self.patch_embed(x)

        # add pos embed w/o cls token 除了全局特征,全部加上了位置信息
        x = x + self.pos_embed[:, 1:, :]

        # masking: length -> length * mask_ratio
        x, mask, ids_restore = self.random_masking(x, mask_ratio)
        # id_restore保存的是原来的位置
        # append cls token
        cls_token = self.cls_token + self.pos_embed[:, :1, :]
        cls_tokens = cls_token.expand(x.shape[0], -1, -1) # [1,1,1024]
        # [1,50,1024] 要包含一个class的情况
        x = torch.cat((cls_tokens, x), dim=1) 

        # apply Transformer blocks
        for blk in self.blocks:
            x = blk(x)
        x = self.norm(x)

        return x, mask, ids_restore

解码器的实现逻辑如下:

def forward_decoder(self, x, ids_restore):
        # embed tokens [1,50,1024]->[1,50,512]
        x = self.decoder_embed(x)

        # append mask tokens to sequence 获取被掩码的token [1,147,512]
        mask_tokens = self.mask_token.repeat(x.shape[0], ids_restore.shape[1] + 1 - x.shape[1], 1)
        # 将经过编码的数据和原始的初始化为0的数据编码在一起。
        x_ = torch.cat([x[:, 1:, :], mask_tokens], dim=1)  # no cls token
        # 将编码的和为编码的重新转变为原始的patch大小,其实本质上只需要考虑编码的位置,因为其余都是随机初始化的
        x_ = torch.gather(x_, dim=1, index=ids_restore.unsqueeze(-1).repeat(1, 1, x.shape[2]))  # unshuffle
        x = torch.cat([x[:, :1, :], x_], dim=1)  # append cls token
        # add pos embed
        x = x + self.decoder_pos_embed

        # apply Transformer blocks
        for blk in self.decoder_blocks:
            x = blk(x)
        x = self.decoder_norm(x)

        # predictor projection 将其转换为所有像素
        x = self.decoder_pred(x)

        # remove cls token
        x = x[:, 1:, :]

        return x

写在最后

        掩码自回归编码器法(Masked Autoencoder, MAE)作为一种前沿的深度学习架构,尤其在处理大规模数据集和复杂特征空间时展现出了其独特的优势。通过对输入数据进行部分掩码(即随机遮盖部分输入),MAE迫使模型从剩余的可见数据中预测被遮盖的部分,这种自监督的学习方式有效地提高了模型的泛化能力和鲁棒性。然而,MAE也面临着一些挑战和限制。例如,如何确定最佳的掩码比例和策略仍然是一个开放的问题。此外,MAE在处理某些特定任务时可能不如其他方法有效,这需要根据具体任务和数据集进行选择和调整,我们有望进一步优化和完善MAE的性能,并将其应用于更加广泛和复杂的任务中。

详细复现过程的项目源码、数据和预训练好的模型可从该文章下方附件获取。

【传知科技】关注有礼     公众号、抖音号、视频号

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1691711.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

K8s 搭建 FileBeat+ELK 分布式日志收集系统 以及 KQL 语法介绍

一、K8s FileBeat ELK 介绍 ELK,即Elasticsearch、Logstash和Kibana三个开源软件的组合,是由Elastic公司提供的一套完整的日志管理解决方案。Elasticsearch是一个高度可扩展的开源全文搜索和分析引擎,它允许你快速地、近乎实时地存储、搜索…

PCB设计——返回路径

回流基本概念 从电路理论上看,信号是由电流传播的,明确的说是电子的运动,电子流的特性之一就是电子从不在任何地方停留,无论电流流到哪里,必然要回来,因此电流总是在环路中流动,从源到负载然后从…

高效使用 LaTeX 技巧

但对于一般人而言,你不需要通过学习 Vim 来达到高效编辑 LaTeX 的方式。而是通过一些比较容易实现的方式,使得你能够在原来的基础上更加高效得使用 LaTeX,并达到以思考的速度输入 LaTeX 的方式。 在第一部分,我会首先介绍高效编辑…

1301-习题1-1高等数学

1. 求下列函数的自然定义域 自然定义域就是使函数有意义的定义域。 常见自然定义域: 开根号 x \sqrt x x ​: x ≥ 0 x \ge 0 x≥0自变量为分式的分母 1 x \frac{1}{x} x1​: x ≠ 0 x \ne 0 x0三角函数 tan ⁡ x cot ⁡ x \tan x \cot x …

告别登录烦恼,WPS免登录修改器体验!(如何实现不登录使用WPS)

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 解决方案 📒🎈 获取方式 🎈⚓️ 相关链接 ⚓️ 📖 介绍 📖 想象一下,如果你能够绕过繁琐的登录流程&#x…

探秘机器学习经典:K-近邻算法(KNN)全解析

在浩瀚的机器学习宇宙中,K-近邻算法(K-Nearest Neighbors,简称KNN)如同一颗璀璨的明星,以其简洁直观的原理和广泛的应用范围,赢得了众多数据科学家的喜爱。今天,让我们一起揭开KNN的神秘面纱,深入探讨它的运作机制、优缺点、应用场景,以及如何在实际项目中灵活运用。 …

从零到一建设数据中台 - 数据治理路径

一、数据治理的内容 数据治理用于规范数据的生成以及使用,改进数据质量,对数据进行加工处理,提升数据价值。提供识别和度量数据质量能力、数据清洗转换能力、数据加工三个核心能力。 数据汇集:数据汇集是数据中台数据接入的入口,所有数据来自于业务系统、日志、文件、网络…

JDBC总结

目录 JDBC(java database connection) JDBC连接数据库步骤: 1. 在项目中添加jar文件,如图所示 2.加载驱动类 向数据库中插入数据代码示例: 第一种: 第二种: 查询操作 : 第一种: 第二种: JDBC(java database connection) java数据库连接.api(应用程序编程接口) ,可…

esp32开发中CMakeLists.txt文件在编译时添加打印信息

在使用CMakeLists.txt文件时,我们时常会对一些宏定义表示的具体路径表示迷茫,不太确定具体表示的路径是哪个,这个时候就希望能在编译的时候打印当前文件中使用的宏定义表示的路径的具体信息。 就像下图中,编译时打印出 CMAKE_CU…

牛客NC391 快乐数【simple 模拟法 Java/Go/PHP】

题目 题目链接: https://www.nowcoder.com/practice/293b9ddd48444fa493dd17da0feb192d 思路 直接模拟即可Java代码 import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值…

serverless在点淘的质量保障实践

SERVERLESS能够将应用分为研发域和运维域,使两者独立迭代,降低运维成本,提升研发效率。点淘作为试点项目,经历了包括功能回归、压力测试和监控验证在内的质量保障流程,并在实践中遇到了各种问题,如依赖梳理…

VOS3000被DDOS攻击后该怎么办

VOS3000遭受DDoS攻击的应对措施 当VOS3000遭受DDoS攻击时,可以采取以下几个步骤来应对: 立即启动防火墙:尽管难以完全阻止DDoS攻击,但防火墙可以在一定程度上帮助抵御攻击,减轻其造成的危害。 联系服务器提供商&#…

抖音小店新规重磅来袭!事关店铺流量!商家的福音来了?

大家好,我是喷火龙。 就在前两天,抖店发布了新规,我给大家总结了一下,无非就是两点。 第一点:保证金下调,一证开多店。 第二点:新品上架破10单,有流量扶持。 咱来细细的解读&…

人生苦短,我学python之数据类型(下)

个人主页:星纭-CSDN博客 系列文章专栏:Python 踏上取经路,比抵达灵山更重要!一起努力一起进步! 目录 一.集合 1.1子集与超集 1.2交集,并集,补集,差集 1.intersection(英文&a…

学习笔记——STM32F103V3版本——HC-05模块控制数码管

一.硬件 1.HC-05模块 2.数码管 3.连接硬件 二.在keil5中的代码 main.c代码: #include "stm32f10x.h" #include "buletooth.h" #include "led.h" #include "sys.h" #include "usart.h" #include "delay.…

python实用系列:按顺序重命名文件

啊,好久没更博客了,今天偶然想换个桌面壁纸,于是上网搜了两个比较满意的桌面壁纸,都是压缩包: 当我想要给他们放到我的桌面壁纸文件里的时候患了难,因为他们的名字有相同的: anime文件夹里边&a…

el-select可选择可搜索可输入新内容

需求:el-form-item添加el-select,并且el-select可选择可搜索可输入新内容,并且和其他的el-input做联动,如果是选择,那么el-input自动回填数据并且不可编辑,如果el-select输入新的内容,那么el-in…

js禁止使用浏览器的前进后退按钮的方法

效果图: // 替换当前页面的历史记录,使用户不能通过浏览器的前进后退按钮导航 history.replaceState(null, null, location.href);// 监听浏览器的历史记录变化事件 window.onpopstate function(event) {// 再次替换当前页面的历史记录,确保…

接口使用实例——数组排序

对于基本数据类型的大小比较&#xff0c;我们可以使用<,>,或者equals方法进行比较&#xff0c;但是对象之间如何进行比较呢&#xff1f;要对对象进行比较&#xff0c;我们必须对同一个成员变量进行比较&#xff0c;如我们可以通过比较name的大小来得出两个对象的大小&…

四万字长文详解——node.js使用移动云,EOS对象存储

目录 前言 安装及安装前的操作 前置条件 如何创建认证信息 使用npm安装SDK开发包 安装开发包命令 初始化操作 存储桶 查看结果命令 查看桶列表 查看结果命令 删除桶 查看结果命令 创建桶 获取桶列表 判断桶是否存在 查询桶所属地域 查询桶的访问权限 管理桶的…