PyTorch框架理解 MSD 代码理解

系列文章目录

提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
例如:第一章 Python 机器学习入门之pandas的使用


提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

提示:这里可以添加本文要记录的大概内容:

例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


提示:以下是本篇文章正文内容,下面案例可供参考

一、认识PyTorch的总体架构

提示:首先,PyTorch的设计哲学很像是一个高度模块化可插拔的系统。

主要划分为四个模块:

  • 模型(Model)
  • 数据处理(Data Handling)
  • 训练控制(Training Control)
  • 优化器(Optimizer)

以下我分别介绍这些模块,作用以及调用方式和调用逻辑。

1.1 模型(Model)

在PyTorch中,所有的模型都是从nn.Module基类继承而来。这个基类让用户可以定义自己的前向传播逻辑。每个模型可以有多个子模块,这些子模块也是继承自nn.Module,这就形成了一个可以任意扩展的层次结构。

  • 调用机制:
    当你调用一个模型的时候,实际上你是在调用它的forward方法。
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.layer1 = nn.Linear(10, 20)
        self.layer2 = nn.Linear(20, 10)

    def forward(self, x):
        x = torch.relu(self.layer1(x))
        return torch.relu(self.layer2(x))

model = Net()
output = model(input_data)  # 实际上调用 model.forward(input_data)

1.2 数据处理(Data Handling)

数据处理在PyTorch中通过Dataset和DataLoader进行。Dataset负责管理数据集的加载和预处理,DataLoader负责以一个可迭代的方式提供批量的数据。

  • 调用机制:
    DataLoader 内部使用了 Python 的迭代器,每次迭代提供一个批次的数据,这一点和 Java 的迭代器非常类似。
dataset = CustomDataset()
dataloader = DataLoader(dataset, batch_size=10, shuffle=True)

for data in dataloader:
    inputs, labels = data
    outputs = model(inputs)

1.3 训练控制(Training Control)

这一部分通常包括设置训练循环,监控训练过程中的损失等。它可以比作是业务逻辑层,控制着模型的训练过程。
调用机制:
使用显式的循环来迭代数据集,对每个批次的数据调用模型的前向传播和后向传播方法。

for epoch in range(total_epochs):
    for inputs, labels in dataloader:
        optimizer.zero_grad()
        outputs = model(inputs)
        loss = loss_function(outputs, labels)
        loss.backward()
        optimizer.step()

1.4 优化器(Optimizer)

优化器负责更新模型的权重,以优化模型的性能。这个概念在Java中没有直接的对应,但可以理解为后台管理或维护任务,例如垃圾收集器或者数据库的优化操作。
调用机制:
优化器在训练循环中被调用,使用模型的loss.backward()生成的梯度来更新模型参数。

optimizer = optim.SGD(model.parameters(), lr=0.01)

for inputs, labels in dataloader:
    optimizer.zero_grad()
    outputs = model(inputs)
    loss = loss_function(outputs, labels)
    loss.backward()
    optimizer.step()

1.5 小总结

在PyTorch中,每个组件都有其专责,通过组合使用这些组件,你可以构建出功能强大且灵活的深度学习应用。模型定义了计算的结构,数据加载器提供了输入数据,训练控制管理了学习过程,优化器负责改进学习效果。这种设计使得PyTorch在科研和工业界都非常受欢迎。

二、知识补充 什么是继承 以及python中继承的表现形式

2.1 简介

在Python中,继承是面向对象编程的一个基本概念,其作用是允许一个类(称为子类派生类)继承另一个类(称为父类或基类)的属性和方法。这样做的主要目的是代码的重用,以及实现接口一致性

2.2 继承的作用

  1. 代码重用:
    继承允许我们定义一个通用的基类,它实现了在多个地方需要的功能。然后,我们可以创建多个派生类,这些派生类继承基类的功能,并添加特定于派生类的功能

  2. 实现接口的一致性:
    通过继承,所有的派生类都可以拥有相同的接口(即方法和属性)。这使得使用任何派生类的对象都非常方便,因为他们有共同的操作方式,这是面向对象设计的一个重要方面。

  3. 多态:
    继承允许实现多态,即同一个接口可以有不同的实现。这意味着一个函数可以使用多个类型的对象,只要这些对象来自同一个基类。

# 定义一个基类 Animal
class Animal:
    def __init__(self, name):
        self.name = name  # 每个动物都有一个名字

    def speak(self):
        raise NotImplementedError("Subclass must implement abstract method")

# 定义一个派生自Animal的类 Dog
class Dog(Animal):
    def speak(self):
        return f"{self.name} says Woof!"

# 定义另一个派生自Animal的类 Cat
class Cat(Animal):
    def speak(self):
        return f"{self.name} says Meow!"

# 使用基类和派生类
animals = [Dog("Buddy"), Cat("Whiskers"), Dog("Fido")]

for animal in animals:
    print(animal.speak())

三、通过上述框架分析 vision_text_display_model.py 代码结构

  1. 模型(Model)

    这个类定义了你的神经网络架构,其中包括前向传播的逻辑。它从nn.Module基类继承,这是所有PyTorch模型的基础。

    主要组件:

    多个神经网络层(例如:nn.Linear, nn.Conv2d, nn.ReLU等)
    forward方法定义了数据如何通过这些层流动。
    
class MSD_Net(nn.Module):
    def __init__(self, args):
        # 初始化各种层
    def forward(self, vision_embeddings, text_embeddings, text_sentiment):
        # 定义前向传播
        return fuse_final_cls

作用:在调用model(input)时,自动调用forward方法

  1. 数据处理(Data Handling)

这个类处理数据的加载和预处理,使其适合模型使用。
主要方法:

	__init__:设置基本参数,加载数据。
	__getitem__:返回一条数据,供DataLoader使用。
	__len__:返回数据集的总大小。
class MultiModalDataset(Dataset):
    def __init__(self, text_tools, vision_transforms, args, mode):
        # 初始化,加载数据
    def __getitem__(self, idx):
        # 返回单个数据项
    def __len__(self):
        # 返回数据集大小

作用:这个类通过提供标准接口简化了数据操作,并且使得数据加载更加模块化。

  1. 数据处理(Data Handling)

这部分通常是指训练脚本,其中可能包括模型的实例化、训练循环等。
训练循环可能包括:

加载数据
执行前向传播
计算损失
执行后向传播(通过.backward())
更新模型参数(通过调用优化器)
  1. 优化器配置(Optimizer Configuration)
    这个函数负责创建和配置优化器,它定义了如何更新模型的权重。
    主要组件:

    optim.Adam: 定义了优化算法。
    学习率调度器(如get_linear_schedule_with_warmup)
    
def get_multimodal_configuration(args, model):
    optimizer = optim.Adam(model.parameters(), lr=args.multimodal_lr)
    scheduler = get_linear_schedule_with_warmup(optimizer, ...)
    criterion = nn.BCEWithLogitsLoss()
    return optimizer, scheduler, criterion

作用:配置如何根据损失函数来调整网络参数,这对学习过程至关重要。

四、重点分析 vision_text_display_model.py 模型

  1. 类定义和初始化

这段代码初始化了一个神经网络模型,它继承自 nn.Module —— PyTorch中所有神经网络模块的基类。

class MSD_Net(nn.Module):
    def __init__(self, args):
        super().__init__()
        self.args = args  # 存储传入的参数,可能包括配置选项如模式选择等
  1. 网络层的定义

这些是模型中使用的神经网络层,包括线性层(全连接层)、ReLU激活函数、丢弃层用于防止过拟合,以及损失函数的选择。

# 定义多个全连接层和卷积层以及激活函数和丢弃层
self.sentiment_fc1 = nn.Linear(768, 768, bias=True)
self.ReLu = nn.ReLU()
self.dropout = nn.Dropout(p=0.1, inplace=False)
self.sentiment_fc2 = nn.Linear(768, 1, bias=True)
self.sentiment_criterion = nn.MSELoss()  # 定义损失函数
  1. 前向传播定义

forward 方法定义了数据通过网络的流程,这是执行网络计算的核心。

    def forward(self, vision_embeddings, text_embeddings, text_sentiment, TFlagNow=None, label=None):
        # 进行前向传播,处理视觉和文本嵌入
        ...
        return fuse_final_cls  # 返回最终的融合结果
  1. 数据处理与特征融合

这部分代码通过生成和应用注意力图来处理和融合视觉和文本数据。这包括矩阵乘法、应用卷积层和计算融合后的嵌入。

        # 处理视觉和文本数据,生成注意力图并应用卷积层
        text_embedd = text_embeddings.transpose(1, 2)
        vision_embedd = vision_embeddings
        attention_map = torch.bmm(vision_embedd, text_embedd)
        ...
        aligned_vision_embeddings =  vision_attention_unsqueeze_minus1 * vision_embedd
  1. 新增功能与计算

这里添加了新的计算层和进行了额外的语义相关的计算,用于增强模型对特定特征的理解和处理。

        # 新增的卷积层处理和语义计算
        attention_map_new = attention_map * TFlagNow
        ...
        semantic_vision_embeddings = vision_CLS + vision_CLS * variance_vision.unsqueeze(0).repeat(batch_size,1)
  1. 结果融合和输出

这一部分代码进行了多层次的特征和结果融合,使用自定义的融合函数和配置参数来调整融合过程。

        # 结果融合
        semantic_cls = self.fusion(semantic_vision_embeddings, semantic_text_embeddings, self.multimodal_fusion)
        final_cls = self.fusion(semantic_cls, sentiment_cls, self.multilevel_fusion)
        final_cls = self.final_fc(final_cls).squeeze()
        fuse_final_cls = final_cls + self.args.lambda_sentiment * lamda_sentiment + self.args.lambda_semantic * lamda_semantic - self.args.constant

4.1 网络层的定义

这段代码是一个深度神经网络模型的定义部分,使用的是PyTorch框架。代码详细定义了多个网络层、损失函数、以及一些用于数据处理和决策支持的队列。下面是对每个部分的详细中文注解:

  1. 网络层的定义与功能
# 定义情感分析的全连接层,输入和输出都是768维,使用偏置
self.sentiment_fc1 = nn.Linear(768, 768, bias=True)
# 激活函数ReLU,用于添加非线性,帮助网络学习复杂的功能
self.ReLu = nn.ReLU()
# Dropout层,概率为0.1,用于防止过拟合,随机丢弃一部分网络连接
self.dropout = nn.Dropout(p=0.1, inplace=False)
# 第二个全连接层,将768维数据压缩到1维
self.sentiment_fc2 = nn.Linear(768, 1, bias=True)
# 均方误差损失函数,用于在训练过程中评估模型的预测结果与实际结果的误差
self.sentiment_criterion = nn.MSELoss()

# 用于处理相关性的卷积层序列,第一个卷积层将1通道扩展到64通道,第二个卷积层将64通道压缩回1通道
self.correlation_conv = nn.Sequential(
    nn.Conv2d(1, 64, 3, stride=1, padding=1),
    nn.Conv2d(64, 1, 3, stride=1, padding=1),
    nn.ReLU()
)

# 另一个卷积层序列,处理流程与上面相似,但通道数较少
self.my_conv_1 = nn.Sequential(
    nn.Conv2d(1, 32, 3, stride=1, padding=1),
    nn.Conv2d(32, 1, 3, stride=1, padding=1),
    nn.ReLU()
)

  1. 融合策略与最终决策层
# 根据参数选择融合策略
self.multimodal_fusion = args.multimodal_fusion
self.multilevel_fusion = args.multilevel_fusion
# 根据融合策略选择最终的全连接层结构
if self.multilevel_fusion != 'concat' and self.multimodal_fusion != 'concat':
    self.final_fc = nn.Linear(768, 1, bias=True)
elif self.multilevel_fusion == 'concat' and self.multimodal_fusion == 'concat':
    self.final_fc = nn.Linear(4*768, 1, bias=True)
else:
    self.final_fc = nn.Linear(3*768, 1, bias=True)  # 如果是其他情况,默认使用3倍768维的输入
  1. 内存队列用于存储历史信息
# 定义内存长度参数
self.memory_length = args.memory_length
# 使用队列存储历史中的讽刺性和非讽刺性信息,用于后续处理
self.sarcasm_bank = Queue(maxsize=self.memory_length)
self.non_sarcasm_bank = Queue(maxsize=self.memory_length)

这段代码中,网络通过多个卷积层和全连接层处理输入数据,使用ReLU激活函数增加非线性,Dropout防止过拟合。通过特定的融合策略和决策层输出最终结果。同时,通过队列记录历史信息,可能用于动态调整模型策略或进行时间序列分析。

4.2 forward 方法中包含重要模块

  • 15
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值