cs231n assignment3 q3 Image Captioning with Transformers

news2024/12/28 6:01:47

文章目录

  • 先啰嗦直接看代码
  • 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

输出

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

在这里插入图片描述

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

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

相关文章

c++ style casting

https://www.youtube.com/watch?vUfrR1nNfoeY&listPLE28375D4AC946CC3&index17

Python3 列表

Python3 列表 序列是 Python 中最基本的数据结构。 序列中的每个值都有对应的位置值,称之为索引,第一个索引是 0,第二个索引是 1,依此类推。 Python 有 6 个序列的内置类型,但最常见的是列表和元组。 列表都可以进…

TensorBoard的使用

TensorBoard:对图像进行变换 1. SummaryWriter的使用 ctrl类出现注释解析: 将条目直接log_dir写入要成为由TensorBoard使用。 “摘要编写器”类提供了一个高级 API 来创建事件文件,并在给定目录中添加摘要和事件。该类更新文件内容异步。…

Python系统监控利器

迷途小书童的 Note 读完需要 3分钟 速读仅需 1 分钟 1 简介 计算机系统监控对保证服务质量和排查故障非常重要。psutil 是一个用于 Python 的跨平台系统监控和过程管理工具,为我们提供便捷的监控方案。 2 基本工作原理 psutil 使用 Python 封装了系统调用&#xff0…

C++学习记录——이십팔 C++11(4)

文章目录 包装器1、functional2、绑定 这一篇比较简短,只是因为后要写异常和智能指针,所以就把它单独放在了一篇博客,后面新开几篇博客来写异常和智能指针 包装器 1、functional 包装器是一个类模板,对可调用对象类型进行再封装…

安全学习DAY20_自动化工具项目武器库介绍

信息打点-自动化工具 文章目录 信息打点-自动化工具本节思维导图&概述 各类红蓝队优秀工具项目集合:All-Defense-Tool 自动化-武器库部署F8x 自动化信息搜集-网络空间AsamF 自动化信息搜集-企查信息ENScan 自动化信息搜集-综合架构-ARL&NemoARL灯塔Nemo_Go …

MySQL 特殊语法时间格式以及Greadb连接

一、时间语法 DATE_FORMAT和to_char() select to_char(now(),%Y-%m-%d %H:%i:%s) from dual; select DATE_FORMAT(now(),%Y-%m-%d %H:%i:%s) from dual; 2.to_date() 和STR_TO_DATE(#{date},%Y-%m-%d ) select to_date(now(),yyyy-mm-dd hh24:mi:ss) from dual;

null和undefined区别

1.undefined,表示无值。 比如下面场景: a. 变量被声明了,但是没有被赋值; b. 调用函数的时候,应该给函数传参却没有给函数传这个参数打印出来就是 undefined; c. 访问一个对象中没有的属性;…

Blender给一个对象添加多个动画

最近在做一个类似元宇宙的项目,需要使用3D建模软件来给3D模型添加动画,3D建模软件选择Blender(因为开源免费…),版本: V3.5 遇到的需求是同一个对象要添加多个动画,然后在代码里根据需要调取动画来执行。本…

飞腾CPU FT-2000/4 uboot下PHY调试记录

一、环境说明 板子是FT-2000/4的开发板: 固件版本: ft-2004c_u-boot-v2-Ver0.3_202112231001.tar.gz ft2004c_v2.06_image_fix.rar 二、调试命令说明 调试PHY主要用到的命令是mii,先查看下可用的命令: mii device,缩写mii dev,查看网络控制器mac。mii device,缩写mi…

【C++】初始化列表

前言:这个知识点的细节比较多,且有些细节不太容易理解,要做好准备哟👻 Ⅰ.构造函数的不完美😭 初始化列表,顾名思义,用列表一样的格式将其初始化。 🤔奇怪啊,构造函数的…

DOCKER 部署 webman项目

# 设置基础镜像 FROM php:8.2-fpm# 安装必要的软件包和依赖项 RUN apt-get update && apt-get install -y \nginx \libzip-dev \libpng-dev \libjpeg-dev \libfreetype6-dev \&& rm -rf /var/lib/apt/lists/*# 安装 PHP 扩展 RUN docker-php-ext-configure gd …

Uniapp笔记(八)初识微信小程序

一、微信小程序基本介绍 1、什么是微信小程序 微信小程序简称小程序,英文名Mini Program,是一种不需要下载安装即可使用的应用,它实现了应用“触手可及”的梦想,用户扫一扫或搜一下即可打开应用 小程序是一种新的开放能力&#…

嵌入式学习之指针

今天周天,主要对linux系统编程的知识进行了学习,但是很多精华还是没有学到位,重点的学习内容是把linux 中open,write,lseek,close的相关操作进行了学习。其次再次把函数指针,数组指针,指针函数,指针数组进行…

线性代数的学习和整理13: 函数与向量/矩阵

目录 1 函数与 向量/矩阵 2 函数的定义域,值域,到达域 3 对应关系 1 函数与 向量/矩阵 下面两者形式类似,本质也类似 函数的: axy ,常规函数里,a,x,y 一般都是单个数矩阵: AXY &a…

[管理与领导-54]:IT基层管理者 - 扩展技能 - 1 - 时间管理 -1- 时间管理的基本理念和五大原则

前言: 管理学大师彼得 德鲁克曾说过:“不能管理时间,便什么也不能管理” 。论语中说:逝者如斯 夫!不舍昼夜。时间对任何一个人来说都是十分重要的,对于惜时如金的管理者来说更是如此。 时间也是一种资源,对所有的人…

TIM输入捕获笔记 (计算编码电机的频率和占空比)

1. 输入捕获简介 IC (Input Capture) 输入捕获输入捕获模式下,当通道输入引脚出现指定电平跳变时,当前CNT的值将被锁存到CCR中,可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数每个高级定时器和通用定时器都拥有4个输入捕获…

Docker网络原理及案例详解

文章目录 简介Docker网络产生的过程Docker network的作用网络模式网络模式---bridge网络模式---host网络模式---none 自定义网络 简介 Docker网络实现容器之间通信和连接外部网络的功能,主要的网络连接方式有桥接网络(Bridge Network、主机网络(Host Ne…

【LeetCode75】第三十九题 二叉树的右视图

目录 题目: 示例: 分析: 代码: 题目: 示例: 分析: 题目给我们一棵二叉树,让我们返回站在二叉树右边从上到下看到的节点。 那实际上就是要我们对二叉树进行层序遍历&#xff0c…

CS144(2023 Spring)Lab 0:networking warmup(环境搭建 webget bytestream)

文章目录 前言其他笔记相关链接 1. Set up GNU/Linux on your computer2. Networking by hand3. Writing a network program using an OS stream socket3.1 Linux配置3.2 C规范3.3 Writing webget3.3.1 实现3.3.2 测试 4. An in-memory reliable byte stream4.1 思路分析4.2 代…