ICCV2023-一个模型助你实现图像分类和文本生成(代码开源)¶
论文题目:TOAST: Transfer Learning via Attention Steering
中文译名:TOAST:通过注意力引导的迁移学习
原文链接:http://export.arxiv.org/abs/2305.15542
代码链接:https://github.com/bfshi/TOAST
1 论文摘要¶
迁移学习需要将预训练好的模型适应新的下游任务。然而,作者观察到,当前的迁移学习方法通常无法关注与任务相关的特征。在这项工作中,作者探索了重新聚焦模型注意力以进行迁移学习。作者提出了自上而下的注意力引导(TOAST),这是一种新的迁移学习算法,它可以冻结预先训练的骨干模型,选择与任务相关的特征输出,并将这些特征反馈到模型中,以引导注意力关注特定任务的特征。仅通过重新聚焦注意力,TOAST在多个迁移学习基准测试中取得了最先进的结果,而只需调整很少的参数。与完全微调、LoRA和提示调优相比,TOAST在各种细分类图像上(例如FGVC上平均准确率81.1% → 86.2%)性能都大大提高。在语言生成方面,TOAST还优于完全微调的Alpaca和Vicuna模型 。
2 模型简介¶
首先使用ImageNet预训练的ViT,并使用不同的迁移学习算法将其转移到下游鸟类分类中。在这里,将这些模型的注意力图可视化。每个注意力图在ViT的最后一层中的不同头部之间进行平均。(a) TOAST方法能够将预先训练的骨干的注意力重新集中在特定任务的特征上,从而大幅提高下游性能。(b) 先前的迁移学习方法,如微调、LoRA和VPT,未能专注于与任务相关的对象,从而实现了次优性能。
在这项工作中,作者表明重新聚焦注意力是迁移学习的关键。作者提出了自上而下的注意力引导(TOAST),这是一种新的迁移学习方法,它通过将注意力重新聚焦到任务相关特征来学习新任务。这是通过自上而下的注意力模块实现的,该模块允许模型以适应任务的方式调整其注意力。自上而下的注意力模块获取来自骨干网络的输出特征,选择与任务相关的特征,然后将这些特征反馈到骨干网络中的每个自注意力层。这些自上而下的信号将增强每层中的任务相关特征,并且带有增强特征的前馈骨干网络再次运行,实现对任务相关信号的更强注意力。在迁移到不同的下游任务时,TOAST简单地冻结预训练骨干网络,并调整自上而下的注意力模块以将注意力引导到特定任务的信号(图1(a))。
值得注意的是,仅通过重新聚焦注意力,TOAST在各种迁移学习基准测试中取得了最先进的结果。与完全微调、LoRA和VPT相比,TOAST显著提高了FGVC细分类上的性能(例如,在平均准确率上比完全微调提高了5%)。TOAST还优于完全微调的Alpaca和Vicuna模型,用于指令遵循语言生成。这些观察加强了作者的观点,即重新聚焦注意力是迁移学习的关键,并为该领域的未来探索提供了启发。
3 算法设计流程¶
论文提出了自上而下注意力引导(TOAST),这是一种新的迁移学习方法,它给预训练模型添加一个自上而下的注意力模块,并只在迁移到下游任务时调整自上而下的注意力。论文首先简要介绍自上而下注意力(第3.1节),然后描述TOAST的详细流程(第3.2节)。注意,尽管TOAST适用于不同的模型体系结构,如transformer和Convnets,但在下面的讨论中,论文假设是一个transformer骨干网络。
3.1 自上而下注意力transformer的预备知识¶
transformer模型通常是自下而上的,即它的注意力仅取决于输入,因此,它通常会突出输入信号中的所有显著特征。与自下而上注意力相反,自上而下注意力具有根据高层目标或任务调整注意力的能力,即它只关注与任务相关的特征,同时忽略其他特征。
本设计遵循图2(a)所示的自上而下注意力设计。具体来说,对于一个纯前馈transformer,论文添加一个特征选择模块和一个反馈路径用于自上而下注意力。网络推理包含四个步骤:(i)输入经过前馈路径获得初始输出,(ii)选择输出中的对当前工作有用的特征,(iii)选择的特征通过反馈路径发送回每个自注意力模块,(iv)再次运行前馈传递,但每个自注意力都接收附加的自上而下输入。通过这种方式,任务相关信息在每个层中被增强,实现自上而下注意力。
在网络中,前馈路径是一个常规transformer,其余部分如下所述:
特征选择(步骤(ii))。从前馈骨干网络的输出中,该模块选择对当前任务有用的特征。这包括选择与任务相关的标记和通道。图2(b)说明了该过程。具体来说,表示前馈传递的第一个输出为(z_i)^{N}_{i=1},其中z_i\in \mathbf{R}^d是第i个输出标记,特征选择对每个标记运算,并输出\tilde{z}_i=P\cdot \text{sim}(z_i,\xi)\cdot z_i,其中\xi\in \mathbf{R}^d和P\in \mathbf{R}^{d\times d}是特定于任务的参数,sim(·,·)是限制在[0,1]之间的余弦相似度。这里,\xi作为任务嵌入,编码对任务重要的标记类型,每个标记z_i由其与任务嵌入的相关性(用余弦相似度测量)重新加权,模拟标记选择。然后,通过P的线性变换执行每个标记的通道选择。
反馈路径(步骤(iii))。在特征选择之后,输出标记通过反馈路径发送回网络。反馈路径包含与前馈路径相同数量的层,每层是一个简单的线性变换。每层的输出经过另一个线性变换,作为第二次前馈中的自上而下输入发送到自注意力模块。
带自上而下输入的自注意力(步骤(iv))。在第二次前馈传递中,每个自注意力模块接收一个额外的自上而下输入。如图2(c)所示,论文简单地将其添加到值矩阵中,同时保持查询和键不变,即Q,K,V=W_QX,W_KX,W_V(X+X_{\text{td}}),其中X是自注意力模块的常规自下而上输入,X_{\text{td}}是自上而下输入。然后是对Q,K,V的常规自注意力。
3.2 自上而下注意力引导¶
给定一个预训练transformer,TOAST随机初始化一个自上而下的注意力模块,并遵循两阶段流程:(i)在通用公共数据集(例如视觉的ImageNet或语言的OpenWebText)上预调整自上而下的注意力以获得更好的初始化,(ii)在下游任务上调整自上而下的注意力。在两阶段中,论文冻结预训练骨干网络,仅调整自上而下的注意力模块(图2(a))。
预调整阶段。由于自上而下的注意力模块是随机初始化的,因此直接在下游任务上调整可能会导致次优性能。为此,论文提出先在通用公共数据集(如ImageNet或OpenWebText)上预调整自上而下的注意力以获得更好的初始化。在预调整过程中,除了常规的有监督或无监督损失之外,论文还添加了的变分损失,它鼓励反馈路径从输出重构输入,作为反馈权重的正则化。
调整阶段。迁移到下游任务时,TOAST仅调整自上而下注意力模块中的参数。在这种情况下,更新了大约15%的参数。论文注意到大多数可调参数来自反馈层,每个反馈层都包含一个d\times d矩阵,当特征维度d很高时,这个矩阵很大。为进一步提高参数效率,论文还提出了TOAST-Lite,它对反馈层应用LoRA。通过这种方式,调整的参数不到1%。论文通过经验证明,尽管TOAST-Lite调整的参数比TOAST少得多,但在某些任务上的性能与TOAST相当,而在其他任务上略差。
4 TOAST中的注意力重新聚焦分析¶
从相似的角度,我们来解释来为什么TOAST比其他基准模型性能优越。如图3所示,对于鸟类分类,TOAST明确关注前景鸟,而其他方法要么具有关注噪声,要么完全忽略前景对象。在汽车分类中,TOAST倾向于集中在车头灯和徽标上,这有助于区分不同品牌的汽车,而其他方法具有更少可解释性并且容易被噪声干扰。
5 效果展示¶
图像分类效果展示:¶
语言生成效果展示:¶
6 结论¶
这项工作的灵感来自于经验性观察到以前的迁移学习方法通常无法关注与任务相关的信号,这可能导致下游任务的次优性能。论文展示了重新聚焦注意力方法是实现更好迁移学习性能的关键。论文提出了自上而下的注意力引导(TOAST),它通过将注意力引导到特定任务的特征来迁移到新任务。具体来说,TOAST冻结预训练骨干网络,并在下游任务上调整附加的自上而下注意力模块以引导注意力。与以前的基线相比,TOAST能够在细分类视觉分类以及指令遵循语言生成上实现最先进的结果,同时仅调整很小一部分参数。
----------------------下面是这篇论文的源码解读-----------------------
(收藏)一文搞定迁移学习!原理+分类+代码+实战全都有!¶
前言¶
最近阅读了一篇名为《TOAST: Transfer Learning via Attention Steering》的论文,论文中,作者使用了一个迁移学习模型,既可以实现图像分类算法的迁移,又可以实现文本生成算法的迁移,令人振奋的是:这两种迁移都展示了惊艳的效果。
1.迁移学习的概念¶
迁移学习是指在一个领域(源领域)学习到的知识,用来帮助另一个领域(目标领域)的学习,从而减少目标领域所需的数据量和训练时间。
传统的机器学习方法往往需要大量的数据和时间来从零开始学习,这样既不高效也不灵活。相反,迁移学习可以借鉴已经存在的模型的能力,利用已有的相关知识,加速和优化新问题的解决。传统机器学习方法和迁移学习方法对比如下图所示。
(图片来源:A Comprehensive Hands-on Guide to Transfer Learning with Real-World Applications in Deep Learning,Dipanjan (DJ) Sarkar)
2.迁移学习的分类¶
(1)根据源领域和目标领域之间的关系,分为同构迁移学习和异构迁移学习。
同构迁移学习是指源领域和目标领域具有相同的特征空间和标签空间,只是数据分布不同。也就是说,它们的数据具有相同的属性和类别,只是数据分布不同。例如,从一个图像分类任务迁移到另一个图像分类任务,如果它们都使用相同的像素值作为特征,且都有相同的类别标签,那么就是同构迁移学习。同构迁移学习的主要挑战是如何处理源领域和目标领域之间的概率分布差异,即如何处理数据之间分布的差异。
异构迁移学习是指源领域和目标领域具有不同的特征空间或标签空间,或者两者都不同。也就是说,它们的数据具有不同的属性或类别。例如,从一个文本分类任务迁移到一个图像分类任务,如果它们使用不同的特征表示方法,如词向量和像素值,且有不同的类别标签,那么就是异构迁移学习。异构迁移学习的主要挑战是如何建立源领域和目标领域之间的特征映射或标签对应关系,即处理不同数据之间的语义的差异。
(2)根据所要迁移的知识类型,分为基于实例的迁移学习、基于特征的迁移学习、基于模型的迁移学习、基于关系的迁移学习和基于对抗的迁移学习。
基于实例的迁移学习是指利用特定的权重调整策略,从源领域中选择部分实例作为目标领域训练集的补充的方法。这种方法的假设是源领域和目标领域中存在一部分相似或相关的实例,在这部分实例上,源领域和目标领域的数据分布是一致或接近的。这种方法通常适用于独立同分布的数据,即每个数据点都是独立生成的。这种方法的优点是方法简单,容易实现;缺点是权重选择与相似度的度量过于依赖经验,且源域与目标域的数据分布往往不同。因此对差异稍大的数据集泛化能力较差。
基于特征的迁移学习是指寻找或构造一个共享的特征空间,使得源领域和目标领域在该空间中具有相似的数据分布,从而减少数据分布不匹配带来的负面影响的方法。这种方法的假设是源领域和目标领域存在一部分公共的特征,在这部分公共特征上,源领域和目标领域的数据分布是一致或相近的。这种方法通常适用于领域适应,也就是源领域和目标领域具有相同的标签空间,但是不同的特征空间或特征分布。例如,在文本分类中,可以利用词嵌入或主题模型等方法,将不同语言或不同风格的文本映射到一个共享的语义空间中,从而进行跨语言或跨风格的文本分类。这种方法的优点是对大多数方法适用,效果好;缺点是难以求解,容易发生过拟合。
基于模型的迁移学习是指利用源领域已经训练好的模型或参数来初始化或约束目标领域的模型,从而提高目标领域学习效果的方法。这种方法的假设是源领域和目标领域在模型层面有共同的知识,可以通过共享模型或参数来实现知识转移。这种方法通常适用于任务迁移学习,也就是源领域和目标领域具有相同的特征空间和标签空间,但是不同的任务。例如,在图像分类中,可以利用在大规模数据集上预训练好的卷积神经网络模型,通过微调或剪枝等方法来适应新的图像分类任务 。这种方法优点是可以充分利用模型之间存在的相似性;缺点是模型参数不易收敛。
基于关系的迁移学习是指利用源领域和目标领域之间的关系知识来进行知识迁移的方法。这种方法的假设是源领域和目标领域中,数据之间的联系关系是相同或相似的,可以通过类比或推理等方式来实现知识转移。这种方法通常适用于非独立同分布的数据,即每个数据点都与其他数据点存在关联。例如,在推荐系统中,可以利用用户和物品之间的评分矩阵,将一个域中的用户或物品映射到另一个域中,从而进行跨域推荐。这种方法的优点是可以处理源域和目标域之间分布差异较大的情况,可以处理类别不平衡的问题,并且对少量标注数据也能取得不错的效果;缺点是需要构建类别之间的关系网络,关系提取不准确会对迁移产生负面影响,计算关系网络的空间和时间复杂度较高。
基于对抗的迁移学习是指利用生成对抗网络(GAN)或其他对抗性技术来缩小源域和目标域之间的差异,从而提高目标域学习效果的方法。这种方法的假设是“为了有效的迁移,良好的表征应该是对主要学习任务的区别性,以及对源域和目标域的不加区分。”基于对抗性的深度迁移学习是指在生成对抗性网络 (GAN)的启发下,引入 对抗性技术 ,寻找既适用于源域又适用于目标域的可迁移表达。它基于这样的假设:“为了有效的迁移,良好的表征应该是对主要学习任务的区别性,以及对源域和目标域的不加区分。”例如,在图像转换中,可以利用CycleGAN等方法,将一个域中的图像风格转换为另一个域中的图像风格。这种方法的优点是可自动适应不同分布,无需目标域标注;缺点是训练稳定性差,难以收敛,效果不稳定。
3.迁移学习的应用¶
为了帮助大家更好地理解迁移学习,这里举了两个常见的例子 ^ v ^
图像分类:图像分类是指根据图像的内容,将其分为不同的类别,如猫、狗、飞机等。图像分类是计算机视觉中的一个基本任务,但是对于一些特定的领域,如医学图像、卫星图像等,可能没有足够的标注数据来训练一个有效的分类器。这时,可以利用迁移学习,将一个在大规模通用数据集(如ImageNet)上训练好的分类器,迁移到目标领域上,通过微调或者特征提取等方法,来提高目标领域的分类效果。例如,使用迁移学习将在ImageNet上训练好的ResNet模型迁移到医学图像上,实现肺炎检测、皮肤癌诊断等工作。
自然语言处理:自然语言处理(NLP)是指让计算机理解和生成自然语言(如中文、英文等)的技术。NLP涉及很多子任务,如情感分析、机器翻译、文本摘要等。由于不同的语言或者不同的领域(如新闻、社交媒体、法律等)有着不同的语法和语义规则,因此需要大量的数据来训练一个通用的NLP模型。迁移学习可以帮助解决这个问题,通过将一个在大量文本上预训练好的NLP模型(如BERT、GPT等),迁移到目标语言或者目标领域上,通过微调或者适配等方法,来提高目标任务的效果。例如,使用迁移学习将在英文文本上预训练好的BERT模型迁移到中文文本上,实现命名实体识别、情感分析等任务。
4.迁移学习的常见模型¶
基于实例的迁移学习:TrAdaBoost1、BIW2等。
基于特征的迁移学习:TCA3、DAN4等。
基于模型的迁移学习:fine-tuning5、LwF等。
基于模型的迁移学习:GraphMix、MetaMIML等。
基于对抗的迁移学习:DANN、CycleGAN等。
5.迁移学习的优势¶
迁移学习的主要优势可归纳如下:
提高模型泛化能力:迁移学习通过从相关任务中获取先验知识,可以提高模型在目标任务上泛化的能力,避免从头训练。
减少标注数据依赖:迁移学习可以在目标任务标注数据不足时,利用源任务的知识提高模型性能,减少对大规模标注数据的依赖。
加速模型训练:基于预训练模型的迁移学习可以跳过模型初始化和预训练过程,直接进行微调,大大加速模型的训练。
提高性能上限:迁移学习通过引入外部信息,可以使模型超越仅从目标任务数据中学习的性能上限。
扩展模型应用范围:迁移学习训练出的模型可以超越源数据集和目标数据集,应用到更广泛的领域。
更好引导特征学习:迁移学习可以更好地引导模型学习任务相关的特征表示,并抑制无关特征的负面影响。
6.算法实例详解¶
下面,我将根据不同的模型分类,分别提供对应的代码详解。
6.1实例迁移¶
直接重用源域数据,可以对源域样本进行重新加权,使其分布适应目标域。
# 源域数据
source_data = [图片数据]
# 目标域数据
target_data = [图片数据]
# 计算源域数据在目标域中的权重
weights = compute_weight(source_data, target_data)
# 加权源域数据
weighted_source_data = [w * img for w, img in zip(weights, source_data)]
# 合并源域和目标域数据进行训练
combined_data = target_data + weighted_source_data
6.2特征迁移¶
使用源域模型提取特征,转移到目标模型中。
# 源域模型
source_model = pretrain_model()
# 固定源域模型参数
source_model.trainable = False
# 提取源域模型最后一层前的特征
target_features = source_model(target_data)
# 目标模型,将源域特征作为输入
target_model = tf.keras.models.Sequential()
target_model.add(tf.keras.layers.InputLayer(input_shape=target_features.shape[1:]))
target_model.add(tf.keras.layers.Dense(num_classes))
# 训练
target_model.compile(optimizer='adam', loss='categorical_crossentropy')
target_model.fit(target_features, target_labels)
6.3参数迁移¶
初始化目标模型的参数为源模型的参数。
# 源域模型
source_model = pretrain_model()
# 目标模型,结构与源域模型相同
target_model = Model()
# 初始化目标模型的参数
target_model.set_weights(source_model.get_weights())
# 训练
target_model.compile(optimizer='adam', loss='categorical_crossentropy')
target_model.fit(target_data, target_labels)
6.4关系迁移¶
建模源域和目标域之间的相关性,加入目标模型的损失函数中。
# 源域数据
source_data = [图片数据]
# 目标域数据
target_data = [图片数据]
# 源域模型
source_model = Model()
# 目标模型
target_model = Model()
# 相关性损失
correlation_loss = compute_correlation_loss(source_model, target_model)
# 目标域损失
target_loss = compute_target_loss(target_model)
# 总损失
total_loss = target_loss + λ * correlation_loss
# 训练
target_model.compile(loss=total_loss)
target_model.fit(target_data, target_labels)
6.5模式迁移¶
在目标模型中加入正则项,使其学习到源模型的部分特征模式。
# 源域模型
source_model = pretrain_model()
# 目标模型
target_model = Model()
# 定义模式正则项
pattern_reg = compute_pattern_reg(target_model, source_model)
# 目标域损失
target_loss = compute_target_loss(target_model)
# 总损失
total_loss = target_loss + λ * pattern_reg
# 训练
target_model.compile(loss=total_loss)
target_model.fit(target_data)
6.6多任务迁移¶
同时优化源域任务和目标域任务的损失。
# 源域模型
source_model = Model()
# 源域数据
source_data = [图片数据]
# 目标模型
target_model = Model()
# 目标域数据
target_data = [图片数据]
# 源域任务损失
source_loss = compute_source_loss(source_model, source_data)
# 目标域任务损失
target_loss = compute_target_loss(target_model, target_data)
# 多任务损失
total_loss = source_loss + target_loss
# 训练
model.compile(loss=total_loss)
model.fit(source_data + target_data)
6.7对抗迁移¶
使用对抗训练,使模型适应目标域。
# 源域数据
source_data = [图片数据]
# 目标域数据
target_data = [图片数据]
# 特征提取器
feature_extractor = Model()
# 源域判别器
source_discriminator = Discriminator()
# 目标域判别器
target_discriminator = Discriminator()
# 对抗损失
adversarial_loss = compute_adversarial_loss(feature_extractor, source_discriminator) + compute_adversarial_loss(feature_extractor, target_discriminator)
# 训练
model.compile(loss=adversarial_loss)
model.fit(source_data + target_data)
7. 从图像分类到目标检测的实战¶
最后,我用训练好的ResNet50作为被迁移源对象,在其基础上增加目标检测模块,之后在PASCAL VOC数据集进行训练,实现目标检测任务的迁移学习。
具体代码如下:
import tensorflow as tf
from tensorflow.keras.applications import ResNet50
from tensorflow.keras.layers import Conv2D, Flatten, Dense
# 加载预训练模型作为特征提取器
feature_extractor = ResNet50(weights='imagenet',include_top=False)
# 冻结预训练模型所有层
for layer in feature_extractor.layers:
layer.trainable = False
# 构建检测模型
inputs = tf.keras.Input(shape=(224, 224, 3))
x = feature_extractor(inputs)
x = Conv2D(filters=256, kernel_size=3)(x)
x = Flatten()(x)
x = Dense(256, activation='relu')(x)
predictions = Dense(10, activation='softmax')(x) # 10个检测目标
model = tf.keras.Model(inputs=inputs, outputs=predictions)
# 编译模型
model.compile(optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy'])
# 加载PASCAL VOC数据并训练
voc_data = # 加载PASCAL VOC数据集
model.fit(voc_data, voc_labels, epochs=5)
这里我们加载了在ImageNet上预训练的ResNet50作为特征提取器,冻结了其权重不更新。然后在它之上构建了一个新的卷积和全连接层来进行目标分类。这样通过迁移ResNet50提取的图像特征,可以减少目标检测模型对大量标注数据的需求。只需要小量样本训练全连接分类层即可。这种做法属于迁移学习中的特征迁移和Fine Tuning技术,是目标检测领域中非常常用的迁移学习实践。
8.迁移学习的前景¶
多源迁移学习的探索:现有方法主要基于单一源域进行迁移,未来可研究如何有效集成多个源域的信息。
异构迁移学习的发展:研究如何在源域和目标域特征空间、分布差异大的情况下进行有效迁移。
迁移学习理论的完善:加强对迁移学习内在机理的理解,建立更统一完备的理论指导框架。
迁移学习算法的优化:提出更有效的迁移学习算法,缩小理论和实践的差距。
9.文章总结¶
本文介绍了迁移学习的概念、分类、应用、模型、优势、代码示例、项目示例和发展前景。目前,迁移学习仍有很多值得探索的方向,未来它将推动人工智能技术向通用和自动化方向发展。最后,由于本人知识范围有限,有疏漏之处,麻烦大家指出。
本文总阅读量次