計算機視覺系列案例 | 基於注意力機制的編碼器-解碼器結構的圖像描述生成

2021-02-21 數據科學人工智慧

圖像描述技術,是指生成連貫流暢的語句描述圖像內容。對網際網路中圖像信息的檢索、兒童的早期教育、視障人士的生活輔助等方面都有重要的意義。因此,圖像描述領域受到越來越多的關注。

本案例將採用帶有注意力機制的編碼器-解碼器網絡結構,生成語句來描述圖像內容。

目錄

1. 數據集簡介
2. 模型介紹
3. 模型結構
    3.1 編碼器
    3.2 注意力機制
    3.3 解碼器
4. 構建模型
5. 圖像描述生成
6. 總結

1 數據集簡介

本案例採用的模型,已經在MSCOCO 2014數據集上進行了預訓練。MSCOCO 2014的訓練集包含82783張圖像,大小為13.5GB,驗證集包含40504張圖像,大小為6.6GB。

這一數據集收集並標註複雜的日常場景圖像,常用於訓練圖像描述的模型。圖像標註出80類物體,如:人、車輛類、動物類等,同時包含對圖像的文本描述。

2 模型介紹

帶有注意力機制的編碼器-解碼器結構:編碼器能夠將輸入圖像轉為向量;解碼器能夠將向量轉化為語句,描述輸入圖像。

引入注意力機制,解碼器能夠在逐字生成語句時,把注意力集中於圖像中與當前詞最相關的部分。

下圖展示了該網絡結構的主要思想:


3 模型結構

接下來我們分別構建編碼器和解碼器網絡。

3.1 編碼器

首先構建編碼器(Encoder),本案例中的編碼器為在MSCOCO 2014數據集上進行預訓練的ResNet-101網絡。

先加載需要使用的庫:

cp models.py ../

import models
import torch
from torch import nn
import torchvision
import torch.nn.functional as F
import numpy as np
import json
import os
import torchvision.transforms as transforms
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import skimage.transform
from skimage import img_as_ubyte
from skimage.transform import resize
from imageio import imread
from PIL import Image
import random

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

編碼器使用預訓練的模型,可以節省訓練時間。預訓練的ResNet-101結構中,最後一層池化層和全連接層用於圖像分類,而編碼過程不需要進行圖像分類,因此我們刪除這兩層。

增加自適應池化層,將特徵向量調整為一致大小,使模型可以接收任意像素大小的輸入圖像。此外,在網絡結構內,添加對ResNet-101網絡2-4層卷積層進行微調的模塊。


# 編碼器
class Encoder(nn.Module):
    def __init__(self, encoded_image_size=14): # encoded_image_size: 生成的特徵圖的大小
        super(Encoder, self).__init__()
        self.enc_image_size = encoded_image_size
        
        # 加載預訓練的ResNet-101模型
        resnet = torchvision.models.resnet101(pretrained=True) 

        # 刪去最後一層池化層和全連接層(該層用於分類)
        modules = list(resnet.children())[:-2]
        self.resnet = nn.Sequential(*modules)

        # 調整特徵向量大小
        self.adaptive_pool = nn.AdaptiveAvgPool2d((encoded_image_size, encoded_image_size))
        
        self.fine_tune()

    # 前向傳播 傳入圖片,提取特徵
    def forward(self, images):
        # 輸出特徵大小:(2048, image_size/32, image_size/32)
        out = self.resnet(images)      
        # 轉化為一致大小:(2048, encoded_image_size, encoded_image_size)
        out = self.adaptive_pool(out)  
        # 調換位置 (encoded_image_size, encoded_image_size, 2048)
        out = out.permute(0, 2, 3, 1) 
        
        # 輸出圖像經過編碼後,得到的向量
        return out
    
    # 微調模型
    def fine_tune(self, fine_tune=True):
        for p in self.resnet.parameters():
            p.requires_grad = False
        # 對2-4層卷積層進行微調
        for c in list(self.resnet.children())[5:]:
            for p in c.parameters(): # 微調某層參數
                p.requires_grad = fine_tune

3.2 注意力機制

在構建解碼器前,需要先定義注意力機制(Attention)。注意力機制返回加權的特徵向量。利用加權的特徵向量,與上一個預測的單詞,結合起來預測下一個單詞,解碼器能夠生成更加準確的語句。下圖展示了該機制的結構:


# 注意力機制
class Attention(nn.Module):
    def __init__(self, encoder_dim, decoder_dim, attention_dim):
        # encoder_dim: 編碼圖像的特徵維度 ; decoder_dim: decoder維度; attention_dim: 注意力機制層數
        super(Attention, self).__init__()
        # 兩個注意力機制模塊,分別針對編碼和解碼
        self.encoder_att = nn.Linear(encoder_dim, attention_dim)  # 全連接層轉換編碼的特徵向量
        self.decoder_att = nn.Linear(decoder_dim, attention_dim)  # 全連接層轉換解碼器的輸出
        self.full_att = nn.Linear(attention_dim, 1)  
        self.relu = nn.ReLU()
        self.softmax = nn.Softmax(dim=1)  # softmax層計算權重

    # 前向傳播
    def forward(self, encoder_out, decoder_hidden):
        att1 = self.encoder_att(encoder_out)    # 將圖像特徵傳入att1
        att2 = self.decoder_att(decoder_hidden) # batch_size * attention_dim
        att = self.full_att(self.relu(att1 + att2.unsqueeze(1))).squeeze(2) # 每個像素的權重
        alpha = self.softmax(att)   # softmax計算權重
        attention_weighted_encoding = (encoder_out * alpha.unsqueeze(2)).sum(dim=1) 
        
        # 返回每個時刻加權的圖像特徵向量
        return attention_weighted_encoding, alpha

3.3 解碼器

最後構建帶有注意力機制的解碼器(Decoder)。本案例採用LSTM作為解碼器,逐字生成語句。因為注意力機制,解碼器在生成不同單詞的時候,會關注圖像不同部分。比如,生成"a man holds a football"中的"football"時,解碼器會關注圖像中的「足球」。

解碼器保留LSTM得到的中間輸出語句,並在生成新的單詞時,先用注意力機制,得到特徵向量的權重。通過之前預測的語句和新的權重,共同預測下一個單詞。

本案例中,帶有注意力機制的LSTM網絡結構包含:注意力機制、嵌入層、dropout層、通過前向傳播解碼。

class DecoderWithAttention(nn.Module):
    def __init__(self, attention_dim, embed_dim, decoder_dim, vocab_size, encoder_dim=2048, dropout=0.5):
        # attention_dim: 注意力機制的層數; embed_dim: 嵌入層; decoder_dim: 解碼器維度
        # vocab_size: 單詞表 word map; encoder_dim: 編碼器維度
        super(DecoderWithAttention, self).__init__()

        self.encoder_dim = encoder_dim
        self.attention_dim = attention_dim
        self.embed_dim = embed_dim
        self.decoder_dim = decoder_dim
        self.vocab_size = vocab_size
        self.dropout = dropout

        self.attention = Attention(encoder_dim, decoder_dim, attention_dim)  # 注意力機制

        self.embedding = nn.Embedding(vocab_size, embed_dim)  # 嵌入層 數據降維、轉換為稠密向量
        self.dropout = nn.Dropout(p=self.dropout)
        self.decode_step = nn.LSTMCell(embed_dim + encoder_dim, decoder_dim, bias=True) 
        
        # LSTM細胞
        self.init_h = nn.Linear(encoder_dim, decoder_dim)  # 初始隱藏狀態
        self.init_c = nn.Linear(encoder_dim, decoder_dim)  # 初始細胞狀態
        self.f_beta = nn.Linear(decoder_dim, encoder_dim)  
        self.sigmoid = nn.Sigmoid()      # sigmoid型激活門
        self.fc = nn.Linear(decoder_dim, vocab_size)  # 為單詞打分
        self.init_weights()  # 初始化權重為均勻分布
    
    # 將權重初始化為均勻分布
    def init_weights(self):
        self.embedding.weight.data.uniform_(-0.1, 0.1)
        self.fc.bias.data.fill_(0)
        self.fc.weight.data.uniform_(-0.1, 0.1)
    
    # 加載預訓練的嵌入層
    def load_pretrained_embeddings(self, embeddings):
        self.embedding.weight = nn.Parameter(embeddings)
    
    # 微調嵌入層
    def fine_tune_embeddings(self, fine_tune=True):
        for p in self.embedding.parameters():
            p.requires_grad = fine_tune
    
    # 隱藏層初始狀態
    def init_hidden_state(self, encoder_out):
        mean_encoder_out = encoder_out.mean(dim=1) # 對第二維求平均 如果已經展平 相當於求每層所有像素的平均值
        h = self.init_h(mean_encoder_out)  # 大小為 (batch_size, decoder_dim)
        c = self.init_c(mean_encoder_out)
        return h, c

    # 前向傳播
    def forward(self, encoder_out, encoded_captions, caption_lengths):
        batch_size = encoder_out.size(0)
        encoder_dim = encoder_out.size(-1)
        vocab_size = self.vocab_size
        
        # 編碼圖像
        encoder_out = encoder_out.view(batch_size, -1, encoder_dim)  # 輸出向量:(batch_size, num_pixels, encoder_dim)
        num_pixels = encoder_out.size(1)

        # 對句子長度進行排序
        caption_lengths, sort_ind = caption_lengths.squeeze(1).sort(dim=0, descending=True)
        encoder_out = encoder_out[sort_ind]
        encoded_captions = encoded_captions[sort_ind]
        
        # 嵌入層 將每個詞用512維的向量表示
        embeddings = self.embedding(encoded_captions)   # 嵌入層
        h, c = self.init_hidden_state(encoder_out)      # LSTM初始狀態
        decode_lengths = (caption_lengths - 1).tolist() # 在<end>部分停止解碼

        # max(decode_lengths): 最長詞語數量; vocab_size: 單詞表
        predictions = torch.zeros(batch_size, max(decode_lengths), vocab_size).to(device)
        # num_pixels: 像素總數
        alphas = torch.zeros(batch_size, max(decode_lengths), num_pixels).to(device)

        # 用之前的單詞和注意力機製得到的權重,解碼新的單詞
        for t in range(max(decode_lengths)): # max(decode_lengths): 句子最長長度
            batch_size_t = sum([l > t for l in decode_lengths])
            attention_weighted_encoding, alpha = self.attention(encoder_out[:batch_size_t],h[:batch_size_t]) # 每次循環都重新生成注意力權重
            gate = self.sigmoid(self.f_beta(h[:batch_size_t]))  # (batch_size_t, encoder_dim)
            attention_weighted_encoding = gate * attention_weighted_encoding # 每層的注意力權重
            h, c = self.decode_step(torch.cat([embeddings[:batch_size_t, t, :], attention_weighted_encoding], dim=1),
                (h[:batch_size_t], c[:batch_size_t]))  # (batch_size_t, decoder_dim)
            preds = self.fc(self.dropout(h))  # (batch_size_t, vocab_size)
            predictions[:batch_size_t, t, :] = preds # 生成預測
            alphas[:batch_size_t, t, :] = alpha # 每個像素的重點區域

        return predictions, encoded_captions, decode_lengths, alphas, sort_ind

4 構建模型

構建好上述編碼器、解碼器、注意力機制後,需要定義實現圖像描述的函數caption_image_beam_search,該函數連接編碼器、注意力機制、解碼器。即將圖像傳入編碼器後,計算得到特徵向量;將特徵向量傳入帶有注意力機制的解碼器,通過LSTM算法得到單詞表內生成語句對應的數字。

在搜索最優生成語句時,我們使用beam search(束搜索)算法,即每次挑選出所有生成語句中條件概率最大的k個,作為該時間步長下的候選輸出序列。始終保持k個候選語句,最後從k個候選中挑出最優的生成語句。

def caption_image_beam_search(encoder, decoder, image_path, word_map, beam_size=3):
    k = beam_size  # 每個解碼步驟中,選擇概率最大的k個詞
    vocab_size = len(word_map) # 單詞表個數

    # 讀取圖像
    img = imread(image_path)
    if len(img.shape) == 2:
        img = img[:, :, np.newaxis]
        img = np.concatenate([img, img, img], axis=2)
    img = img_as_ubyte(resize(img, (256, 256)))
    img = img.transpose(2, 0, 1)
    img = img / 255.
    img = torch.FloatTensor(img).to(device)
    normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406],
                                     std=[0.229, 0.224, 0.225])
    transform = transforms.Compose([normalize])
    image = transform(img)  # (3, 256, 256)

    # 編碼器
    image = image.unsqueeze(0)  # (1, 3, 256, 256)
    encoder_out = encoder(image)  # (1, enc_image_size, enc_image_size, encoder_dim)
    enc_image_size = encoder_out.size(1)
    encoder_dim = encoder_out.size(3)

    # 編碼得到的特徵向量
    encoder_out = encoder_out.view(1, -1, encoder_dim)  # (1, num_pixels, encoder_dim)
    num_pixels = encoder_out.size(1)

    # batch size = k
    encoder_out = encoder_out.expand(k, num_pixels, encoder_dim)  # (k, num_pixels, encoder_dim)

    # 每次儲存前k個單詞,初始狀態為<start>
    k_prev_words = torch.LongTensor([[word_map['<start>']]] * k).to(device)  # (k, 1)
    seqs = k_prev_words  # (k, 1)
    top_k_scores = torch.zeros(k, 1).to(device)  # (k, 1)

    # 初始權重
    seqs_alpha = torch.ones(k, 1, enc_image_size, enc_image_size).to(device)
    complete_seqs = list()
    complete_seqs_alpha = list()
    complete_seqs_scores = list()

    # 解碼
    step = 1
    h, c = decoder.init_hidden_state(encoder_out)

    # s <= k, 到達<end>時停止解碼
    while True:
        embeddings = decoder.embedding(k_prev_words).squeeze(1)  # 維度: (s, embed_dim)
        awe, alpha = decoder.attention(encoder_out, h)  # (s, encoder_dim), (s, num_pixels)
        alpha = alpha.view(-1, enc_image_size, enc_image_size)  # (s, enc_image_size, enc_image_size)
        gate = decoder.sigmoid(decoder.f_beta(h))  # gating scalar, (s, encoder_dim)
        awe = gate * awe

        h, c = decoder.decode_step(torch.cat([embeddings, awe], dim=1), (h, c))  # (s, decoder_dim)
        scores = decoder.fc(h)  # (s, vocab_size)
        scores = F.log_softmax(scores, dim=1)
        scores = top_k_scores.expand_as(scores) + scores  # (s, vocab_size)

        # 初始狀態下,分數相同
        if step == 1:
            top_k_scores, top_k_words = scores[0].topk(k, 0, True, True)  # (s)
        else:
            # 找到最高得分的單詞
            top_k_scores, top_k_words = scores.view(-1).topk(k, 0, True, True)  # (s)
            
        prev_word_inds = top_k_words // vocab_size  # (s)
        next_word_inds = top_k_words % vocab_size  # (s)

        # 輸出新單詞
        seqs = torch.cat([seqs[prev_word_inds], next_word_inds.unsqueeze(1)], dim=1)  # (s, step+1)
        seqs_alpha = torch.cat([seqs_alpha[prev_word_inds], alpha[prev_word_inds].unsqueeze(1)],
                               dim=1)  # (s, step+1, enc_image_size, enc_image_size)

        # 判斷是否可以停止解碼
        incomplete_inds = [ind for ind, next_word in enumerate(next_word_inds) if
                           next_word != word_map['<end>']]
        complete_inds = list(set(range(len(next_word_inds))) - set(incomplete_inds))

        # 完整語句
        if len(complete_inds) > 0:
            complete_seqs.extend(seqs[complete_inds].tolist())
            complete_seqs_alpha.extend(seqs_alpha[complete_inds].tolist())
            complete_seqs_scores.extend(top_k_scores[complete_inds])
        k -= len(complete_inds) 

        # 處理不完整的語句
        if k == 0:
            break
        seqs = seqs[incomplete_inds]
        seqs_alpha = seqs_alpha[incomplete_inds]
        h = h[prev_word_inds[incomplete_inds]]
        c = c[prev_word_inds[incomplete_inds]]
        encoder_out = encoder_out[prev_word_inds[incomplete_inds]]
        top_k_scores = top_k_scores[incomplete_inds].unsqueeze(1)
        k_prev_words = next_word_inds[incomplete_inds].unsqueeze(1)

        # 步驟過長則終止
        if step > 50:
            break
        step += 1
    i = complete_seqs_scores.index(max(complete_seqs_scores))
    seq = complete_seqs[i]
    alphas = complete_seqs_alpha[i]

    return seq, alphas

為了更好地展示輸出結果,我們定義visualize_att函數,將圖像注意力集中的位置和對應的輸出單詞,直觀展示出來。

def visualize_att(image_path, seq, alphas, rev_word_map, smooth=True):
    image = Image.open(image_path)    # 讀入圖像
    image = image.resize([14 * 24, 14 * 24], Image.LANCZOS) # 調整圖像大小
    words = [rev_word_map[ind] for ind in seq]
    plt.figure(figsize=(18,9))

    for t in range(len(words)):
        if t > 50:
            break
        plt.subplot(np.ceil(len(words) / 5.), 5, t + 1)
        
        # 將注意力集中的圖像部分高亮
        plt.text(0, 1, '%s' % (words[t]), color='black', backgroundcolor='white', fontsize=12)
        plt.imshow(image)
        current_alpha = alphas[t, :]
        if smooth:
            alpha = skimage.transform.pyramid_expand(current_alpha.numpy(), upscale=24, sigma=8)
        else:
            alpha = skimage.transform.resize(current_alpha.numpy(), [14 * 24, 14 * 24])
        if t == 0:
            plt.imshow(alpha, alpha=0)
        else:
            plt.imshow(alpha, alpha=0.8)
        plt.set_cmap(cm.Greys_r)
        plt.axis('off')
    plt.show()

5 圖像描述生成

現在我們可以通過調用上述定義的函數,對輸入的圖像生成對應的語句。考慮到訓練時間過長,本案例將加載訓練好的編碼器與解碼器參數。

from glob import glob

checkpoint = '/content/BEST_checkpoint_coco_5_cap_per_img_5_min_word_freq.pth.tar'  # 預訓練參數
word_map_file = '/content/WORDMAP_coco_5_cap_per_img_5_min_word_freq.json'  # 單詞表
beam_size = 5                   
smooth = True 

# 加載模型
checkpoint = torch.load(checkpoint, map_location=device)
decoder = checkpoint['decoder']
decoder = decoder.to(device)
decoder.eval()
encoder = checkpoint['encoder']
encoder = encoder.to(device)
encoder.eval()

加載單詞表,即每個數字對應的單詞。

# 加載單詞表
with open(word_map_file, 'r') as j:
    word_map = json.load(j)
# 轉換格式
rev_word_map = {v: k for k, v in word_map.items()} 
# 展示單詞表
for i in range(5):
    t = random.choice(list(rev_word_map))
    print(t,":",rev_word_map[t])

333 : chairs
505 : plant
1575 : snowboarder
1859 : indian
3049 : build

接下來,我們可以向模型輸入一張圖像進行描述,我們使用的數據如下圖所示:

Image.open("/content/surf.png")  # 打開圖像

my_files = np.array(glob("/content/surf.png"))
for img in my_files:

    # 生成圖像描述
    seq, alphas = caption_image_beam_search(encoder, decoder, img, word_map, beam_size)
    alphas = torch.FloatTensor(alphas)

    for i in seq:
        print(rev_word_map[i],end=' ')
    # 展示圖像描述結果
    visualize_att(img, seq, alphas, rev_word_map, smooth)

<start> a couple of people with surfboards in the water <end>


生成的語句為:"a couple of people with surfboards in the water",即「海裡有兩個人拿著衝浪板」,語句通順,且準確地描述出了圖像的內容,包含了「衝浪板」、「兩個人」、「海」這些關鍵詞語。

通過可視化注意力機制,我們看到在生成"people"這一單詞時,模型關注圖像中的「兩個人」;生成"surfboards"時,則關注人們手中的「衝浪板」。

6 總結

本案例構建了帶有注意力機制的ResNet-101和LSTM的模型,實現圖像描述。其中ResNet-101模型已經在MSCOCO 2014上進行了預訓練,節省了模型訓練的時間。在尋找最優語句時,使用beam search算法,實現搜索最優語句的任務。

觀察生成結果,可知模型的訓練結果較好,生成的語句能夠準確地描述圖像內容。

相關焦點

  • CVPR 2020|看圖說話之隨心所欲:細粒度可控的圖像描述自動生成
    因此,我們提出角色感知的圖編碼器,以區分不同節點的細粒度意圖,並利用圖中上下文信息增加每個節點的語義識別能力。第二,ASG不僅可以通過節點控制需要描述的圖片內容,同時也通過節點之間連接的方式隱含地控制了描述的結構順序。因此,我們提出的解碼器使用基於圖注意力機制分別考慮節點的語義內容和連接結構,使得模型可以基於圖流動順序描述指定的節點內容。
  • 將注意力機制引入RNN,解決5大應用領域的序列預測問題
    讀完這篇博客,你會知道:編碼器-解碼器結構和固定長度內部表徵的局限性讓網絡學會針對輸出序列的每一項去注意輸入序列中對應位置的注意力機制帶有注意力機制的循環神經網絡在文本翻譯、語音識別等 5 個領域中的應用。
  • 圖像描述開原始碼整理
    根據提取出的目標以及它們的屬性利用CRF或者是一些人為規則來生成出圖像的描述。這種做法非常依賴於1)圖像特徵的提取2)生成句子時所需要的規則。隨著深度學習技術的發展和COCO等圖像標註數據集的出現,圖像描述相關的技術得到了快速的發展。目前圖像描述的方法主要是在編碼器-解碼器框架上進行改進與不斷嘗試。
  • 基於注意力機制改進U-Net的醫學圖像分割算法
    近年來,由於深度學習方法的迅速發展,基於深度學習的圖像分割算法在醫學圖像分割領域取得了顯著的成就。其中依賴於編碼器-解碼器體系結構的U-Net被研究人員廣泛使用。但是U-Net網絡在下採樣的過程中卷積、池化都是局部算子,要獲取全局信息就需要深度編碼器,這樣會引入大量的訓練參數,並且丟失更多圖像的空間信息。而在上採樣過程中使用反卷積、反池化很難進行空間信息的恢復。
  • 計算機視覺中的注意力機制
    在此情形下,基於循環神經網咯(Recurrent Neural Network)的注意力機制(Attention Mechanism)進入了人們的視野。除了之前提到的機器翻譯和自然語言處理領域之外,計算機視覺中的注意力機制也是十分有趣的,本文將會簡要介紹一下計算機視覺領域中的注意力方法。
  • 一個用於代碼生成的基於語法的結構化CNN解碼器
    希望通過代碼生成得到目標代碼「f = open(『F1』,『r』)」。隨著深度學習的發展,編碼器-解碼器框架成為序列生成的主流方法。特別地,遞歸神經網絡(RNNs)可以充當典型的編碼器和解碼器;這種架構也被稱為序列到序列(Seq2Seq)模型(Sutskever,Vinyals,and Le 2014)。
  • CVPR 2020 | 京東AI研究院對視覺與語言的思考:從自洽,交互到共生
    與機器翻譯中不同自然語言間的轉化相仿,圖像描述生成任務可以提煉為從一種視覺語言(圖像特徵表達)到自然語言(描述語句)的轉換。現今主流的圖像描述生成算法的原型都可概括為兩個模塊:視覺編碼器(Visual Encoder)和語言解碼器(Language Decoder)。
  • CVPR 2020|京東AI研究院對視覺與語言的思考:從自洽、交互到共生
    與機器翻譯中不同自然語言間的轉化相仿,圖像描述生成任務可以提煉為從一種視覺語言(圖像特徵表達)到自然語言(描述語句)的轉換。現今主流的圖像描述生成算法的原型都可概括為兩個模塊:視覺編碼器(Visual Encoder)和語言解碼器(Language Decoder)。前者負責對視覺內容的理解,將視覺語言編碼為富含語義信息的特徵表達,後者則依據編碼後的特徵表達來解碼出相應的語言描述。
  • 視覺+Transformer最新論文出爐,華為聯合北大、雪梨大學發表
    作者 | CV君來源 | 我愛計算機視覺Transformer 技術最開始起源於自然語言處理領域,但今年5月份Facebook 的一篇文章將其應用於計算機視覺中的目標檢測(DETR算法,目前已有78次引用)使其大放異彩,並迅速得到CV研究社區的關注。
  • 【AAAI論文】阿里提出新圖像描述框架,解決梯度消失難題
    從粗略到精細的多級預測框架圖像描述的困難之處是讓設計的模型能有效地利用圖像信息和生成更接近人類的豐富的圖像描述。在自然語言處理近期進展的推動下,當前的圖像描述方法一般遵循編碼-解碼框架。這種框架由一個基於卷積神經網絡(CNN)的圖像編碼器和基於循環神經網絡(RNN)的句子解碼器構成,有多種用於圖像描述的變體。
  • 學界| 普適注意力:用於機器翻譯的2D卷積神經網絡,顯著優於編碼器...
    選自arXiv作者:Joe Davison機器之心編譯參與:李詩萌、張倩現有的當前最佳機器翻譯系統都是基於編碼器-解碼器架構的,二者都有注意力機制,但現有的注意力機制建模能力有限。本文提出了一種替代方法,這種方法依賴於跨越兩個序列的單個 2D 卷積神經網絡。
  • 一文解讀NLP中的注意力機制
    人類的視覺注意力雖然存在很多不同的模型,但它們都基本上歸結為給予需要重點關注的目標區域(注意力焦點)更重要的注意力,同時給予周圍的圖像低的注意力,然後隨著時間的推移調整焦點。而在NMT的翻譯模型中經典的做法是由編碼器 - 解碼器架構制定(encoder-decoder),用作encoder和decoder常用的是循環神經網絡。這類模型大概過程是首先將源句子的輸入序列送入到編碼器中,提取最後隱藏狀態的表示並用於解碼器的輸入,然後一個接一個地生成目標單詞,這個過程廣義上可以理解為不斷地將前一個時刻 t-1 的輸出作為後一個時刻 t 的輸入,循環解碼,直到輸出停止符為止。
  • 經典Seq2Seq與注意力Seq2Seq模型結構詳解
    注意力機制什麼是Seq2Seq模型?在Seq2seq模型中,神經機器翻譯以單詞序列的形式接收輸入,並生成一個單詞序列作為輸出。例如,義大利語的「Cosa vorresti ordinare?」#5:解碼器產生第二個輸出「careful」時間步驟#6:解碼器產生第三個輸出「Thomas」編碼器或解碼器的每一步都是RNN處理其輸入並生成該時間步長的輸出。
  • 為文本摘要模型添加注意力機制:採用LSTM的編解碼器模型實現
    在本文中,我們將重點研究抽象摘要技術,並將利用編解碼器架構來解決這一問題。什麼是編碼器-解碼器架構?常用的序列-序列模型(編碼器-解碼器)的整體結構如下圖所示該模型由編碼器、中間矢量和解碼器三部分組成。
  • NLP攜手Transformer跨界計算機視覺,DETR:目標檢測新範式
    自從 Transformer 被提出以來,得益於其強大的注意力機制,便開始在 NLP 領域一統江湖。但令人意外的是,Transformer 在 CV 界卻反響平平,一度認為不適合 CV 領域,直到最近計算機視覺領域出來幾篇 Transformer 文章,性能直逼 CNN 的 SOTA,給予了計算機視覺領域新的想像空間,Transformer 在計算機視覺領域的範式已經初具雛形。
  • 【乾貨】首次使用分層強化學習框架進行視頻描述生成,王威廉組最新工作
    文章中指出,未來將計劃注意力機制(Attention),以提升提出的層次強化學習(HRL)框架。作者相信,提出的方法的結果可以通過使用不同類型的特徵,如C3D特徵,光流等進一步改善。同時,作者將在其他相似的序列生成任務(如視頻/文檔摘要)中探索提出的HRL框架。
  • 在圖像生成領域裡,GAN這一大家族是如何生根發芽的
    而 GAN 看起來正好相反,它根據隨機的中間表徵,學習一個能生成真實樣本的編碼器。選自 arXiv: 1906.04493。如上所示,PM 模型使用基於梯度的極小極大策略學習數據的編碼器,從而使中間表徵與數據的分布保持一致。而 GAN 卻使用基於梯度的極小極大策略直接學習給定中間表徵的解碼器。
  • Attention 掃盲:注意力機制及其 PyTorch 應用實現
    /lucas_zhang深度學習attention 機制是對人類視覺注意力機制的仿生,本質上是一種資源分配機制。生理原理就是人類視覺注意力能夠以高解析度接收於圖片上的某個區域,並且以低解析度感知其周邊區域,並且視點能夠隨著時間而改變。換而言之,就是人眼通過快速掃描全局圖像,找到需要關注的目標區域,然後對這個區域分配更多注意,目的在於獲取更多細節信息和抑制其他無用信息。提高 representation 的高效性。
  • 【CV+NLP】更有智慧的眼睛:圖像描述(Image Caption)&視覺問答(VQA)綜述(上)
    在那以後的幾年,計算機視覺的三大基本任務:分類,檢測,分割被以 ResNet 為骨幹網絡的各種 Net 迅速蠶食。計算機視覺的研究者們,也更加地由感知智能偏向到認知智能,他們終於要嚴肅面對在自然語言處理中的面對的種種問題,去探索人工智慧更神秘的邊界。
  • 綜述|計算機視覺中的注意力機制
    視覺注意力分為幾種,核心思想是基於原有的數據找到其之間的關聯性,然後突出其某些重要特徵,有通道注意力,像素注意力,多階注意力等,也有把NLP中的自注意力引入。所有的編碼器在結構上都是相同的,但它們沒有共享參數。每個編碼器都可以分解成兩個子層: