圖中的結(jié)構(gòu)主要分為兩部分:編碼器和解碼器。編碼器將輸入序列轉(zhuǎn)換為一組表示,該表示將傳遞給解碼器生成輸出序列。位置編碼(Positional Encoding)是為了在序列中加入位置信息,因?yàn)門(mén)ransformer不具備處理序列位置信息的能力。

PyTorch中對(duì)Transformer的調(diào)用

PyTorch提供了便捷的API來(lái)實(shí)現(xiàn)Transformer模型。其核心是將左側(cè)的神經(jīng)網(wǎng)絡(luò)封裝為一個(gè)TransformerEncoder類(lèi)。該類(lèi)需要兩個(gè)關(guān)鍵參數(shù):TransformerEncoderLayer和層數(shù)(num_layers)。

class Transformer(nn.Module):
    def __init__(self, vocab_size, embedding_dim, hidden_dim, num_class,
                 dim_feedforward=512, num_head=2, num_layers=2, dropout=0.1, max_len=512, activation='relu'):
        super(Transformer, self).__init__()
        self.embedding_dim = embedding_dim
        self.embeddings = nn.Embedding(vocab_size, embedding_dim)
        self.position_embedding = PositionalEncoding(embedding_dim, dropout, max_len)
        encoder_layer = nn.TransformerEncoderLayer(hidden_dim, num_head, dim_feedforward, dropout, activation)
        self.transformer = nn.TransformerEncoder(encoder_layer, num_layers)
        self.output = nn.Linear(hidden_dim, num_class)

    def forward(self, inputs, lengths):
        inputs = torch.transpose(inputs, 0, 1)
        hidden_states = self.embeddings(inputs)
        hidden_states = self.position_embedding(hidden_states)
        attention_mask = length_to_mask(lengths) == False
        hidden_states = self.transformer(hidden_states, src_key_padding_mask=attention_mask).transpose(0, 1)
        logits = self.output(hidden_states)
        log_probs = F.log_softmax(logits, dim=-1)
        return log_probs

TransformerEncoder類(lèi)詳解

TransformerEncoder是一個(gè)由多個(gè)編碼器層組成的堆棧。每個(gè)編碼器層都由TransformerEncoderLayer類(lèi)實(shí)例化,這個(gè)類(lèi)具體實(shí)現(xiàn)了自注意力機(jī)制和前饋神經(jīng)網(wǎng)絡(luò)。

class TransformerEncoder(Module):
    def __init__(self, encoder_layer, num_layers, norm=None):
        super(TransformerEncoder, self).__init__()
        self.layers = _get_clones(encoder_layer, num_layers)
        self.num_layers = num_layers
        self.norm = norm

    def forward(self, src: Tensor, mask: Optional[Tensor] = None, src_key_padding_mask: Optional[Tensor] = None) -> Tensor:
        output = src
        for mod in self.layers:
            output = mod(output, src_mask=mask, src_key_padding_mask=src_key_padding_mask)
        if self.norm is not None:
            output = self.norm(output)
        return output

該類(lèi)主要通過(guò)克隆傳入的編碼器層并對(duì)其進(jìn)行堆疊,實(shí)現(xiàn)了多層編碼器的構(gòu)建。每層的輸入輸出維度保持一致,這在后續(xù)的TransformerEncoderLayer中可以進(jìn)一步驗(yàn)證。

TransformerEncoderLayer類(lèi)深入

TransformerEncoderLayer由自注意力機(jī)制和前饋網(wǎng)絡(luò)組成。其實(shí)現(xiàn)基于論文《Attention Is All You Need》,該論文首次提出了Transformer的概念。

class TransformerEncoderLayer(Module):
    def __init__(self, d_model, nhead, dim_feedforward=2048, dropout=0.1, activation=F.relu,
                 layer_norm_eps=1e-5, batch_first=False, norm_first=False,
                 device=None, dtype=None) -> None:
        factory_kwargs = {'device': device, 'dtype': dtype}
        super(TransformerEncoderLayer, self).__init__()
        self.self_attn = MultiheadAttention(d_model, nhead, dropout=dropout, batch_first=batch_first,
                                            **factory_kwargs)
        self.linear1 = Linear(d_model, dim_feedforward, **factory_kwargs)
        self.dropout = Dropout(dropout)
        self.linear2 = Linear(dim_feedforward, d_model, **factory_kwargs)
        self.norm1 = LayerNorm(d_model, eps=layer_norm_eps, **factory_kwargs)
        self.norm2 = LayerNorm(d_model, eps=layer_norm_eps, **factory_kwargs)
        self.dropout1 = Dropout(dropout)
        self.dropout2 = Dropout(dropout)

    def forward(self, src: Tensor, src_mask: Optional[Tensor] = None, src_key_padding_mask: Optional[Tensor] = None) -> Tensor:
        x = src
        x = self.norm1(x + self._sa_block(x, src_mask, src_key_padding_mask))
        x = self.norm2(x + self._ff_block(x))
        return x

    def _sa_block(self, x: Tensor, attn_mask: Optional[Tensor], key_padding_mask: Optional[Tensor]) -> Tensor:
        x = self.self_attn(x, x, x, attn_mask=attn_mask, key_padding_mask=key_padding_mask, need_weights=False)[0]
        return self.dropout1(x)

    def _ff_block(self, x: Tensor) -> Tensor:
        x = self.linear2(self.dropout(self.activation(self.linear1(x))))
        return self.dropout2(x)

在forward函數(shù)中,通過(guò)自注意力機(jī)制和前饋網(wǎng)絡(luò)模塊的運(yùn)算,輸入的張量經(jīng)過(guò)兩次加法運(yùn)算后依舊保持了原始的維度,這也證明了TransformerEncoder中的層堆疊是維度一致的。

PyTorch中的激活函數(shù)

activations.py文件中,我們可以看到PyTorch對(duì)幾種常用激活函數(shù)的實(shí)現(xiàn)。這些激活函數(shù)在深度學(xué)習(xí)模型中用于引入非線性特性。

class PytorchGELUTanh(nn.Module):
    def __init__(self):
        super().__init__()
        if version.parse(torch.__version__) =1.12.0 is required to use '
                'PytorchGELUTanh. Please upgrade torch.'
            )

    def forward(self, input: Tensor) -> Tensor:
        return nn.functional.gelu(input, approximate='tanh')

class NewGELUActivation(nn.Module):
    def forward(self, input: Tensor) -> Tensor:
        return 0.5 * input * (1.0 + torch.tanh(math.sqrt(2.0 / math.pi) * (input + 0.044715 * torch.pow(input, 3.0))))

這些實(shí)現(xiàn)展示了激活函數(shù)的多樣性和PyTorch在實(shí)現(xiàn)這些函數(shù)時(shí)對(duì)性能和準(zhǔn)確度的權(quán)衡。

FAQ

什么是Transformer模型?

Transformer是一種用于處理序列數(shù)據(jù)的深度學(xué)習(xí)模型,具有很強(qiáng)的并行處理能力。其通過(guò)自注意力機(jī)制實(shí)現(xiàn)了對(duì)序列中每個(gè)元素的全局依賴(lài)建模。

PyTorch如何實(shí)現(xiàn)Transformer模型?

PyTorch通過(guò)nn.TransformerEncodernn.TransformerEncoderLayer等類(lèi)提供了對(duì)Transformer模型的實(shí)現(xiàn)。這些類(lèi)封裝了自注意力機(jī)制和前饋網(wǎng)絡(luò)的細(xì)節(jié),使得用戶可以專(zhuān)注于模型的高層搭建。

如何在PyTorch中使用自定義激活函數(shù)?

用戶可以通過(guò)繼承nn.Module類(lèi)并實(shí)現(xiàn)forward方法來(lái)自定義激活函數(shù)。PyTorch提供了多種激活函數(shù)的實(shí)現(xiàn)作為參考。

為什么Transformer模型需要位置編碼?

由于Transformer模型不具備處理輸入序列中位置信息的能力,因此需要通過(guò)位置編碼將位置信息顯式地加入到輸入中,以幫助模型學(xué)習(xí)序列中的順序關(guān)系。

如何優(yōu)化Transformer模型的性能?

可以通過(guò)調(diào)整模型的超參數(shù)(如層數(shù)、隱藏層維度、注意力頭數(shù)等),優(yōu)化數(shù)據(jù)預(yù)處理流程,以及利用GPU加速計(jì)算等方法來(lái)提高Transformer模型的性能。

上一篇:

Rust Rayon并行計(jì)算API的使用

下一篇:

CMake CTest測(cè)試框架API詳解
#你可能也喜歡這些API文章!

我們有何不同?

API服務(wù)商零注冊(cè)

多API并行試用

數(shù)據(jù)驅(qū)動(dòng)選型,提升決策效率

查看全部API→
??

熱門(mén)場(chǎng)景實(shí)測(cè),選對(duì)API

#AI文本生成大模型API

對(duì)比大模型API的內(nèi)容創(chuàng)意新穎性、情感共鳴力、商業(yè)轉(zhuǎn)化潛力

25個(gè)渠道
一鍵對(duì)比試用API 限時(shí)免費(fèi)

#AI深度推理大模型API

對(duì)比大模型API的邏輯推理準(zhǔn)確性、分析深度、可視化建議合理性

10個(gè)渠道
一鍵對(duì)比試用API 限時(shí)免費(fèi)