GNN Algorithms(9): 多模态Multi-Modal、多任务Multi-Task

目录

Background

concept

区别与联系 

算法原理 

1. Multi-Modal 多模态 

1.1 4种跨模态特征融合方法

1.1.1 SumFusion,相加

1.1.2 ConcatFusion,拼接

1.1.3 FiLM,Clip相乘

 1.1.4 GatedFusion,Gated相乘

1.2 TorchMultiModal 库

1.3 多模态implementation

1.3.1 key_fc1: self.resnet.fn = nn.Identity() # 移除ResNet模型的最后一层全连接层

1.3.2 key_fc2: Bert_output.last_hidden_state

1.3.3 implementation codes

Reference


Background

concept

多任务学习和多模态学习是CV领域的两个热门研究方向。

  • 多任务学习 (Multi-Task Learning, MTL)是一种将多个相关任务学习到一个模型中的方法,以提高模型的泛化能力和学习效率。在CV领域,多任务学习常用于图像分类、目标检测、语义分割等任务的联合学习。
  • 多模态学习 (Multi-Modal Learning, MML)是一种将多种类型的数据(e.g. image, text, audio, v ideo等)作为输入的学习方法,以提高模型的表现力和泛化能力。

区别与联系 

区别:

  • 多任务学习MTL,是将多个相关任务学习到一个模型中。
  • 多模态学习MML,是将多种数据类型作为输入input。

联系:MTL和MML在多种数据类型上进行多任务学习! 

算法原理 

  • 多任务学习MTL,是通过共享底层特征,提高模型泛化能力和学习效率,如torch.nn.ModuleList; torch.nn.ModuleDict。
  • 多模态学习MML,是将多种类型数据输入,如torch.nn.Sequential; torch.nn.ModuleList。

1. Multi-Modal 多模态 

1.1 4种跨模态特征融合方法

1.1.1 SumFusion,相加

将多个单模态output embeddings相加


import torch
import torch.nn as nn
 
#------------------------------------------#
# SumFusion的定义,为两者过全连接层后进行直接相加
#------------------------------------------#
class SumFusion(nn.Module):
    def __init__(self, input_dim=512, output_dim=100):
        super(SumFusion, self).__init__()
        #---------------------------------------#
        # 针对x以及y两个特征张量,分别定义了两个全连接层
        #---------------------------------------#
        self.fc_x = nn.Linear(input_dim, output_dim)
        self.fc_y = nn.Linear(input_dim, output_dim)
 
    def forward(self, x, y):
        output = self.fc_x(x) + self.fc_y(y)
1.1.2 ConcatFusion,拼接

将多个单模态output embeddings拼接起来 -> 全连接层 

#------------------------------------------#
# ConcatFusion的定义,只定义一个全连接层
# 首先将两者堆叠,之后再将堆叠后的向量送入至全连接层
#------------------------------------------#
class ConcatFusion(nn.Module):
    def __init__(self, input_dim=1024, output_dim=100):
        super(ConcatFusion, self).__init__()
        self.fc_out = nn.Linear(input_dim, output_dim)
 
    def forward(self, x, y):
        output = torch.cat((x, y), dim=1)
        output = self.fc_out(output)
        return x, y, output
1.1.3 FiLM,Clip相乘

将一个单模态output embedding切分后,与另一个单模态output embedding相乘相加

  • torch.split()函数,将tensor按特定维度dim切分成若干块,每块大小为dim_size

#------------------------------------------#
# FiLM融合方法的定义,只定义一个全连接层
#------------------------------------------#
class FiLM(nn.Module):
    """
    FiLM: Visual Reasoning with a General Conditioning Layer,
    https://arxiv.org/pdf/1709.07871.pdf.
    """
    def __init__(self, input_dim=512, dim=512, output_dim=100, x_film=True):
        super(FiLM, self).__init__()
        self.dim    = input_dim
        self.fc     = nn.Linear(input_dim, 2 * dim)
        self.fc_out = nn.Linear(dim, output_dim)
        self.x_film = x_film
 
    def forward(self, x, y):
        if self.x_film:
            film = x
            to_be_film = y
        else:
            film = y
            to_be_film = x
 
        gamma, beta = torch.split(self.fc(film), self.dim, 1)
 
        output = gamma * to_be_film + beta
        output = self.fc_out(output)
 
        return x, y, output
 1.1.4 GatedFusion,Gated相乘

将一个单模态output embedding gated激活后,与另一个单模态output embedding相乘 -> 输出

#------------------------------------------#
# GatedFusion方法的定义
#------------------------------------------#
class GatedFusion(nn.Module):
    """
    Efficient Large-Scale Multi-Modal Classification,
    https://arxiv.org/pdf/1802.02892.pdf.
    """
 
    def __init__(self, input_dim=512, dim=512, output_dim=100, x_gate=True):
        super(GatedFusion, self).__init__()
        self.fc_x    = nn.Linear(input_dim, dim)
        self.fc_y    = nn.Linear(input_dim, dim)
        self.fc_out  = nn.Linear(dim, output_dim)
        self.x_gate  = x_gate  # whether to choose the x to obtain the gate
        self.sigmoid = nn.Sigmoid()
 
    def forward(self, x, y):
        out_x = self.fc_x(x)
        out_y = self.fc_y(y)
 
        if self.x_gate:
            gate   = self.sigmoid(out_x)
            output = self.fc_out(torch.mul(gate, out_y))
        else:
            gate   = self.sigmoid(out_y)
            output = self.fc_out(torch.mul(out_x, gate))
 
        return out_x, out_y, output

1.2 TorchMultiModal 库

Facebook AI Research (FAIR) 开发的TorchMultiModal库是一个用于多模态学习的库,继承了多模态数据处理和模型训练流程,旨在简化多模态任务的开发。 

其他的多模态模型

  • Meta -> CM3
  • google -> Parti
  • OpenAI -> CLIP,clip component是一个在学习text和image表征方面非常有效的model。

1.3 多模态implementation

1.3.1 key_fc1: self.resnet.fn = nn.Identity() # 移除ResNet模型的最后一层全连接层
self.resnet.fn = nn.Identity()  # 移除ResNet模型的最后一层全连接层
'''
ResNet模型的最后一层通常是一个全连接层,用于分类任务。对于pretrained ResNet-50模型,这个全连接层的的作用是讲ResNet的output features (通常是一个2048维的向量)映射到一个指定数量的类别上。例如,Rest在ImageNet数据集上预训练,最后一层全连接层输出维度是1000,对应于ImageNet的1000个类别。在多模态学习中,我们通常不需要最后一层的分类器,而是需要获取iamge embeddings,以便与其他模态(i.e. text)特征进行融合。
这种情况下,我们需要移除最后一层全连接层,只保留ResNet的特征提取部分。
nn.Identity作用是torch的一个占位符层,它不改变输入的值,只是简单地返回输入。使用nn.Identity可以方便地移除某一层而不改变模型地其他部分!!!
'''

self.resnet.fn = nn.Identity()  # 移除ResNet模型的最后一层全连接层
'''
ResNet模型的最后一层通常是一个全连接层,用于分类任务。对于pretrained ResNet-50模型,这个全连接层的的作用是讲ResNet的output features (通常是一个2048维的向量)映射到一个指定数量的类别上。例如,Rest在ImageNet数据集上预训练,最后一层全连接层输出维度是1000,对应于ImageNet的1000个类别。在多模态学习中,我们通常不需要最后一层的分类器,而是需要获取iamge embeddings,以便与其他模态(i.e. text)特征进行融合。
这种情况下,我们需要移除最后一层全连接层,只保留ResNet的特征提取部分。
nn.Identity作用是torch的一个占位符层,它不改变输入的值,只是简单地返回输入。使用nn.Identity可以方便地移除某一层而不改变模型地其他部分!!!
''' 

1.3.2 key_fc2: Bert_output.last_hidden_state

text_features = text_outputs.last_hidden_state
'''
transformers.BertModel默认输出是BaseModelOutputWithPoolingAndCrossAttention,这是一个包含多个字段命名元组NamedTuple。
last_hidden_state是bert_model最后一层的隐藏状态, 是一个shape=(batch_size, seq_len, hidden_size)的tensor。
NamedTuple还包括的其他参数:
- pooler_output,表示池化后的输出,这个输出可以用于分类任务。
- attention_weights,
''' 

1.3.3 implementation codes

My github repository: GitHub - yuyongsheng1990/Multi_Modal_Models

- Multi_Modal_01: GPT Generated Codes.

- Multi_Modal_02: Cross-Attention: image to text. 

Reference

https://juejin.cn/post/7326266639284453403

多模态学习中四种常用的跨模态特征融合方法定义与PyTorch实现-CSDN博客

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-17 13:06:01       66 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-17 13:06:01       70 阅读
  3. 在Django里面运行非项目文件

    2024-07-17 13:06:01       57 阅读
  4. Python语言-面向对象

    2024-07-17 13:06:01       68 阅读

热门阅读

  1. Julia 流程控制

    2024-07-17 13:06:01       24 阅读
  2. 关于C# 开发Winfrom事后总结

    2024-07-17 13:06:01       25 阅读
  3. 什么是决策树?

    2024-07-17 13:06:01       28 阅读
  4. android binder如何实现异步

    2024-07-17 13:06:01       17 阅读
  5. 基于STM32设计的物联网智能鱼缸(微信小程序)(187)

    2024-07-17 13:06:01       26 阅读
  6. 文件查找和文件删除

    2024-07-17 13:06:01       20 阅读
  7. axios

    2024-07-17 13:06:01       22 阅读