cs231n assignment3 q3 Image Captioning with Transformers

文章目录

  • 先啰嗦直接看代码
  • Q3 Image Captioning with Transformers
    • MultiHeadAttention.forward
      • 题面
      • 解析
      • 代码
      • 输出
    • Positional Encoding
      • 题面
      • 解析
      • 代码
      • 输出
    • transformer.forward
      • 题面
      • 解析
      • 代码
      • 输出

先啰嗦直接看代码

Q3 Image Captioning with Transformers

MultiHeadAttention.forward

题面

在这里插入图片描述
在这里插入图片描述

解析

让我们实现多头注意力的前向计算

可以先看看这篇李沐老师对transformer的讲解

如果你看了上面的这个视频,那么你应该能大概明白多头注意力是个什么东西
然后我们来看init部分的代码
在这里插入图片描述

首先多头注意力让我们对单纯的注意力的Q,K,V,计算的时候进行了投影,那么具体的投影方法,就是上面定义的

  1. self.key 投影key
  2. self.query 投影query
  3. self.value 投影 value

我们可以看到,这几个线性层的输入输出维度是相同的,接下来只需要计算单纯的权重就好了,如果看不懂我的解析,可以看我的代码注释,同时建议看看上面那个链接的视频

代码

    def forward(self, query, key, value, attn_mask=None):
        """
        Calculate the masked attention output for the provided data, computing
        all attention heads in parallel.

        In the shape definitions below, N is the batch size, S is the source
        sequence length, T is the target sequence length, and E is the embedding
        dimension.

        Inputs:
        - query: Input data to be used as the query, of shape (N, S, E)
        - key: Input data to be used as the key, of shape (N, T, E)
        - value: Input data to be used as the value, of shape (N, T, E)
        - attn_mask: Array of shape (S, T) where mask[i,j] == 0 indicates token
          i in the source should not influence token j in the target.

        Returns:
        - output: Tensor of shape (N, S, E) giving the weighted combination of
          data in value according to the attention weights calculated using key
          and query.
        """
        N, S, E = query.shape
        N, T, E = value.shape
        # Create a placeholder, to be overwritten by your code below.
        output = torch.empty((N, S, E))
        ############################################################################
        # TODO: Implement multiheaded attention using the equations given in       #
        # Transformer_Captioning.ipynb.                                            #
        # A few hints:                                                             #
        #  1) You'll want to split your shape from (N, T, E) into (N, T, H, E/H),  #
        #     where H is the number of heads.                                      #
        #  2) The function torch.matmul allows you to do a batched matrix multiply.#
        #     For example, you can do (N, H, T, E/H) by (N, H, E/H, T) to yield a  #
        #     shape (N, H, T, T). For more examples, see                           #
        #     https://pytorch.org/docs/stable/generated/torch.matmul.html          #
        #  3) For applying attn_mask, think how the scores should be modified to   #
        #     prevent a value from influencing output. Specifically, the PyTorch   #
        #     function masked_fill may come in handy.                              #
        ############################################################################
        # *****START OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****

        # 投影QKV
        Q = self.query(query)
        K = self.key(key)
        V = self.value(value)

        # 获取投影个数
        H = self.n_head
        # 获取投影维度
        D = self.head_dim
        # 矩阵分割 与 转置 这里需要结合QKV的形状来理解
        Q = Q.reshape(N, S, H, D).transpose(1, 2)  # (N H S D)
        K = K.reshape(N, T, H, D).transpose(1, 2)  # (N H T D)
        V = V.reshape(N, T, H, D).transpose(1, 2)  # (N H T D)

        # 矩阵乘法算权重  (N, H, S, K) * (N, H, K, T) -> N, H, S, T
        energy = torch.matmul(Q, K.transpose(-2, -1)) / math.sqrt(D)  # (N H S T)

        # 判断是否需要mask
        if attn_mask is not None:
            energy = energy.masked_fill(attn_mask == 0, float('-inf'))

        # softmax计算
        A = torch.softmax(energy, dim=3)  # 对第四维度进行softmax

        # 使用dropout
        A = self.attn_drop(A)

        # 计算加权和  (N, H, S, T) * (N, H, T, K) -> (N, H, S, K)
        Y = A.matmul(V)

        # 再投影回去
        Y = Y.transpose(1, 2).reshape(N, S, E)  # (N, S, E)
        output = self.proj(Y)  # (N, S, E)

        # *****END OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****
        ############################################################################
        #                             END OF YOUR CODE                             #
        ############################################################################
        return output

输出

在这里插入图片描述

Positional Encoding

题面

在这里插入图片描述
因为transformer能够很容易的主要的输入的任何部分,但是注意力机制没有顺序的概念,但是,对于许多人物,尤其是自然语言处理任务,顺序非常重要,因此作者添加了位置标记对每个单词的token

定于矩阵p为
在这里插入图片描述

我们并不直接把x输入进网络,而是将 x + p输入进来

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

解析

看懂上面的题面,就好了,还不懂就看代码

代码

class PositionalEncoding(nn.Module):
    """
    Encodes information about the positions of the tokens in the sequence. In
    this case, the layer has no learnable parameters, since it is a simple
    function of sines and cosines.
    """

    def __init__(self, embed_dim, dropout=0.1, max_len=5000):
        """
        Construct the PositionalEncoding layer.

        Inputs:
         - embed_dim: the size of the embed dimension
         - dropout: the dropout value
         - max_len: the maximum possible length of the incoming sequence
        """
        super().__init__()
        self.dropout = nn.Dropout(p=dropout)
        assert embed_dim % 2 == 0
        # Create an array with a "batch dimension" of 1 (which will broadcast
        # across all examples in the batch).
        pe = torch.zeros(1, max_len, embed_dim)
        ############################################################################
        # TODO: Construct the positional encoding array as described in            #
        # Transformer_Captioning.ipynb.  The goal is for each row to alternate     #
        # sine and cosine, and have exponents of 0, 0, 2, 2, 4, 4, etc. up to      #
        # embed_dim. Of course this exact specification is somewhat arbitrary, but #
        # this is what the autograder is expecting. For reference, our solution is #
        # less than 5 lines of code.                                               #
        ############################################################################
        # *****START OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****

        # 创建一个 0 到 maxlen 的行向量并转为列向量 就相当于公式里的i
        col = torch.arange(max_len)[:, None]
        # 获取公式中的矩阵的行向量
        row = torch.pow(10000, -torch.arange(0, embed_dim, 2) / embed_dim)

        # 计算p 矩阵
        pe[0, :, 0::2] = torch.sin(col * row)
        pe[0, :, 1::2] = torch.cos(col * row)

        # *****END OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****
        ############################################################################
        #                             END OF YOUR CODE                             #
        ############################################################################

        # Make sure the positional encodings will be saved with the model
        # parameters (mostly for completeness).
        self.register_buffer('pe', pe)

    def forward(self, x):
        """
        Element-wise add positional embeddings to the input sequence.

        Inputs:
         - x: the sequence fed to the positional encoder model, of shape
              (N, S, D), where N is the batch size, S is the sequence length and
              D is embed dim
        Returns:
         - output: the input sequence + positional encodings, of shape (N, S, D)
        """
        N, S, D = x.shape
        # Create a placeholder, to be overwritten by your code below.
        output = torch.empty((N, S, D))
        ############################################################################
        # TODO: Index into your array of positional encodings, and add the         #
        # appropriate ones to the input sequence. Don't forget to apply dropout    #
        # afterward. This should only take a few lines of code.                    #
        ############################################################################
        # *****START OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****

        output = x + self.pe[:, :S]
        output = self.dropout(output)

        # *****END OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****
        ############################################################################
        #                             END OF YOUR CODE                             #
        ############################################################################
        return output

输出

在这里插入图片描述

transformer.forward

题面

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

解析

如果是正确理解了transformer模型的话,应该不会在这里卡壳,建议多看看相应的课程和论文讲解,我在代码中也写上了详尽的注释

代码

    def forward(self, features, captions):
        """
        Given image features and caption tokens, return a distribution over the
        possible tokens for each timestep. Note that since the entire sequence
        of captions is provided all at once, we mask out future timesteps.

        Inputs:
         - features: image features, of shape (N, D)
         - captions: ground truth captions, of shape (N, T)

        Returns:
         - scores: score for each token at each timestep, of shape (N, T, V)
        """
        N, T = captions.shape
        # Create a placeholder, to be overwritten by your code below.
        scores = torch.empty((N, T, self.vocab_size))
        ############################################################################
        # TODO: Implement the forward function for CaptionTransformer.             #
        # A few hints:                                                             #
        #  1) You first have to embed your caption and add positional              #
        #     encoding. You then have to project the image features into the same  #
        #     dimensions.                                                          #
        #  2) You have to prepare a mask (tgt_mask) for masking out the future     #
        #     timesteps in captions. torch.tril() function might help in preparing #
        #     this mask.                                                           #
        #  3) Finally, apply the decoder features on the text & image embeddings   #
        #     along with the tgt_mask. Project the output to scores per token      #
        ############################################################################
        # *****START OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****

        # 第一步,嵌入说明和添加位置编码
        # captions: (N, T) -> (N, T, W)
        captions = self.embedding(captions)
        captions = self.positional_encoding(captions)

        # 第二步,将图像特征投影到相同的维度
        # features: (N, D) -> (N,W) -> (N, T, W)
        features_projected = self.visual_projection(features).unsqueeze(1)

        # 第三步,准备一个掩码(tgt_mask)来屏蔽说明中的未来时间步骤
        tgt_mask = torch.tril(torch.ones((T, T), dtype=torch.bool))

        # 第四部,将解码器特征应用于文本和图像嵌入以及tgt_mask
        # scores: (N, T, W) -> (N, T, V)
        scores = self.transformer(captions, features_projected, tgt_mask=tgt_mask)
        scores = self.output(scores)

        # *****END OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****
        ############################################################################
        #                             END OF YOUR CODE                             #
        ############################################################################

        return scores

输出

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Docker容器:Harbor 私有仓库迁移

文章目录 一.私有仓库迁移的介绍1.为何要对Harbor 私有仓库的迁移2.Harbor 私有仓库的迁移特点3. Harbor 私有仓库的迁移注意要点 二.私有仓库迁移配置1.源Harbor配置(192.168.198.11)(1)接着以下操作查看容器状况及是否可以登录 …

自动化备份方案

背景说明 网上有很多教程,写的都是从零搭建一个什么什么,基本上都是从无到有的教程,但是,很少有文章提及搭建好之后如何备份,这次通过请教GitHub Copilot Chat,生成几个备份脚本,以备后用。 注…

功能强大的网站检测工具Web-Check

什么是 Web-Check ? Web-Check是一款功能强大的一体化工具,用于查找有关网站/主机的信息。目前仪表版上可以显示:IP 信息、SSL 信息、DNS 记录、cookie、请求头、域信息、搜索爬虫规则、页面地图、服务器位置、开放端口、跟踪路由、DNS 安全扩…

解决报错: Could not initialize class com.platform.cache.J2CacheUtils

今天运行一个比较久远的SSM项目,访问接口时报错: Could not initialize class com.platform.cache.J2CacheUtils 找了半天也没有发现问题所在,突然发现报错里面有ShiroFilter字样,然后想起以前shiro好像是要跟redis对接&#xff0…

css滚动条的使用

前言: css滚动条的使用。 1、使用案例1:背景不要,只展示一个滚动条 如果是默认整体,::就够用了,如果是某个元素,可以 .abc:: ,如果是scss这种的 &:: ::-webkit-scrollbar {width: 6px; } ::-webkit…

mysql下载

网址 MySQL :: Download MySQL Community Serverhttps://dev.mysql.com/downloads/mysql/ 2、选择MSI进行安装 3、这里我选择离线安装 4、这里我选择直接下载 5、等待下载安装即可

怎么对App进行功能测试

测试人员常被看作是bug的寻找者,但你曾想过他们实际是如何开展测试的吗?你是否好奇他们究竟都做些什么,以及他们如何在一个典型的技术项目中体现价值?本文将带你经历测试人员的思维过程,探讨他们测试app时的各种考虑. …

ArcGIS API开发介绍

本来想自己总结写一下的,但是发现有个网站总结的特别好。所以直接给大家分享一下地址: 起步 - Start | ArcGis中文网 当然系统性的学习和使用还的看官网文档Quick Links | API Reference | ArcGIS Maps SDK for JavaScript 4.27 | ArcGIS Developers …

Nuxt 菜鸟入门学习笔记三:视图

文章目录 入口文件组件 Components页面 Pages布局 Layouts Nuxt 官网地址: https://nuxt.com/ Nuxt 提供多个组件层来实现应用程序的用户界面。 入口文件 App.vue组件 Components页面 Pages布局 Layouts 下面逐一进行介绍。 入口文件 默认情况下,Nu…

时序预测 | MATLAB实现DBN-SVM深度置信网络结合支持向量机时间序列预测(多指标评价)

时序预测 | MATLAB实现DBN-SVM深度置信网络结合支持向量机时间序列预测(多指标评价) 目录 时序预测 | MATLAB实现DBN-SVM深度置信网络结合支持向量机时间序列预测(多指标评价)效果一览基本描述程序设计参考资料 效果一览 基本描述 MATLAB实现DBN-SVM深度置信网络结合支持向量机…

Go语言入门记录:从基础到变量、函数、控制语句、包引用、interface、panic、go协程、Channel、sync下的waitGroup和Once等

程序入口文件的包名必须是main,但主程序文件所在文件夹名称不必须是main,即我们下图hello_world.go在main中,所以感觉package main写顺理成章,但是如果我们把main目录名称改成随便的名字如filename也是可以运行的,所以…

印花税减半!上次调整A股全部涨停

财政部、税务总局公告,为活跃资本市场、提振投资者信心,自2023年8月28日起,证券交易印花税实施减半征收。 值得一提的是,8月初,证券时报、经济日报、央广网等三大官媒共同发声,为活跃资本市场、提振投资者信…

echart 图表添加数据分析功能,(右上控制选择)

echart 图表添加数据分析功能,可区域选择数据,右上按钮,控制echart行为 chart.on(globalcursortaken, onGlobalcursortaken); //绑定事件chart.off("brushSelected");//解绑事件处理函数chart.on(brushSelected, renderBrushed);getBarDev2(eIndex, eTimeArr, eSerie…

RISC-V IOPMP实际用例-Andes SoC‘s Rapid-k模型

安全之安全(security)博客目录导读 2023 RISC-V中国峰会 安全相关议题汇总 说明:本文参考RISC-V 2023中国峰会如下议题,版权归原作者所有。

GDB用法(一)

预备 测试代码 main.cpp #include <iostream> #include <vector> #include "student.h"using namespace std;int add(int a, int b) {return a b; }int main() {vector<int> v {1, 3};Student* s1 new Student("zz", 20);Student* …

电路学习+硬件每日学习十个知识点(40)23.8.20 (希腊字母读音,阶跃信号和冲激信号的关系式,信号的波形变换,信号的基本运算,卷积积分,卷积和)

文章目录 1.信号具有时间特性和频率特性。2.模拟转数字&#xff0c;抽样、量化、编码3.阶跃信号和冲激信号4.信号的波形变换&#xff08;时移、折叠、尺度变换&#xff09;5.信号的基本运算&#xff08;加减、相乘、微分与积分、差分与累加&#xff09;5.1 相加减5.2 相乘5.3 微…

Android JNI系列详解之AS创建Native C++项目

一、前提 Android Studio版本&#xff1a;Android Studio Electric Eel | 2022.1.1 Patch 1 二、创建Native C项目 1.新建项目 2.选择新建Native C项目 3.New Project 4.选择C标准库的支持版本 5.项目自带的默认生成的代码 6.buil.gradle中也自带了CMakeList的配置&#xff08;…

4、Spring之Bean生命周期源码解析(创建)

Spring最重要的功能就是帮助程序员创建对象(也就是IOC),而启动Spring就是为创建Bean对象做准备,所以我们先明白Spring到底是怎么去创建Bean的,也就是先弄明白Bean的生命周期。 Bean的生命周期就是指:在Spring中,一个Bean是如何生成的,如何销毁的。 Bean生命周期流程图…

微服务dubbo

微服务是一种软件开发架构风格&#xff0c;它将一个应用程序拆分成一组小型、独立的服务&#xff0c;每个服务都可以独立部署、管理和扩展。每个服务都可以通过轻量级的通信机制&#xff08;通常是 HTTP/REST 或消息队列&#xff09;相互通信。微服务架构追求高内聚、低耦合&am…

Matlab图像处理-乘法运算

乘法运算 两幅图像进行乘法运算主要实现两个功能&#xff1a; 一是可以实现掩模操作&#xff0c;即屏蔽图像的某些部分&#xff1b; 二是如果一幅图像乘以一个常数因子&#xff0c;如果常数因子大于1&#xff0c;将增强图像的亮度&#xff0c;如果因子小于1则会使图像变暗。…