一、BertModel的輸入和輸出
from transformers import BertModel
bert=BertModel.from_pretrained('bert-base-chinese')
out=bert(context, attention_mask=mask)
1. 輸入
Bert模型的輸入context
張量需要滿足以下要求:
-
張量形狀:
context
應為二維張量,形狀為[batch_size, sequence_length]
,其中-
batch_size
是輸入樣本的批量大小, -
sequence_length
是輸入序列的長度。
-
-
數(shù)據(jù)類型:
context
的數(shù)據(jù)類型應為整數(shù)類型,如torch.LongTensor
。 -
值范圍:
context
中的值應該是詞匯表中的詞索引。通常情況下,詞匯表中的特殊符號會被分配預先定義好的索引,例如[PAD]
、[UNK]
、[CLS]
和[SEP]
。其余的詞將被映射到詞匯表中的相應索引。
另外,為了有效控制模型的注意力,提高計算效率,可以使用 attention_mask
張量。attention_mask
是一個與輸入張量形狀相同的二進制張量(0和1組成),用于指示哪些位置是有效的(1表示有效)和哪些位置是填充的(0表示填充)。填充位置的注意力權(quán)重將被設(shè)為零,因此模型不會關(guān)注填充位置。
注意,輸入張量的長度限制取決于Bert模型的最大序列長度限制。超過最大長度的部分需要進行截斷或者其他處理。
總結(jié)起來,Bert模型的輸入context
張量應為二維整數(shù)張量,形狀為[batch_size, sequence_length]
,并且可以結(jié)合使用attention_mask
張量來標識填充位置。
2. 輸出
如上邊調(diào)用Bert模型時,輸出結(jié)果out中包含last_hidden_state、pooler_output、hidden_states、past_key_values、attentions、cross_attentions幾個屬性。
以下是在BERT模型的輸出中的各個屬性的含義:
-
last_hidden_state
: 這是BERT模型最后一個隱藏層的輸出。它是一個形狀為[batch_size, sequence_length, hidden_size]
的張量,表示每個輸入令牌的上下文相關(guān)表示。這個張量包含了輸入序列中每個位置的隱藏狀態(tài)信息。
last_hidden_state[:,0]
表示BERT模型輸出的最后一個隱藏層的所有令牌的第一個位置(即[CLS]
令牌)的表示。
在BERT模型中,通常在輸入序列的開頭添加一個特殊的[CLS]
令牌,用于表示整個序列的匯總信息。last_hidden_state[:,0]
提取了這個[CLS]
令牌的表示,它是一個形狀為[batch_size, hidden_size]
的張量。
這個[CLS]
令牌的表示可以用作整個序列的匯總或句子級別的表示,通常用于下游任務(wù)的分類或句子級別的特征提取。在一些任務(wù)中,可以將last_hidden_state[:,0]
作為整個序列的表示,用于進行情感分類、文本匹配等任務(wù)。
需要注意的是,last_hidden_state[:,0]
是一個針對每個樣本的表示,如果批量處理了多個樣本,則batch_size
的維度將對應于樣本的數(shù)量。
-
pooler_output
: 這是BERT模型經(jīng)過池化操作得到的輸出。它是一個形狀為[batch_size, hidden_size]
的張量,表示整個輸入序列的池化表示。它通常被用作句子級別的表示,用于下游任務(wù)的分類或句子級別的特征提取。 -
hidden_states
: 這是BERT模型中所有隱藏層的輸出。它是一個包含每個隱藏層輸出的列表,其中每個元素的形狀為[batch_size, sequence_length, hidden_size]
。hidden_states[0]
表示第一個隱藏層的輸出,hidden_states[1]
表示第二個隱藏層的輸出,以此類推,hidden_states[-1]
表示最后一個隱藏層的輸出(即last_hidden_state
)。這些隱藏層輸出可以用于更詳細的分析或進行一些特殊任務(wù)。 -
past_key_values
: 這是用于生成下一個預測令牌的先前鍵值對。它是一個元組,其中包含了前幾次調(diào)用BERT模型時生成的先前鍵值對。它通常在生成任務(wù)(如文本生成)中使用,以便在多步預測中保留先前的狀態(tài)信息。 -
attentions
: 這是自注意力機制產(chǎn)生的注意力權(quán)重。它是一個列表,包含每個注意力頭的注意力權(quán)重矩陣。注意力權(quán)重矩陣的形狀為[batch_size, num_heads, sequence_length, sequence_length]
,表示模型在每個位置上關(guān)注其他位置的程度。 -
cross_attentions
: 這是BERT模型中的交叉注意力機制產(chǎn)生的注意力權(quán)重。它是一個列表,包含每個交叉注意力頭的注意力權(quán)重矩陣。注意力權(quán)重矩陣的形狀為[batch_size, num_heads, sequence_length, sequence_length]
,表示模型在每個位置上關(guān)注另一個輸入序列(如句子級別的任務(wù)中的兩個句子)的程度。
這些屬性提供了BERT模型在不同層級和注意力機制上的輸出信息,可以根據(jù)任務(wù)的需求選擇合適的屬性來使用。
二、CNN的輸入和輸出
from transformers import BertModel
import torch.nn.functional as F
def conv_and_pool(self, x, conv):
x = F.relu(conv(x)).squeeze(3) #[batch_size, out_channels, output_length]
x = F.max_pool1d(x, x.size(2)).squeeze(2) #[batch_size, channels]
return x
num_filters = 256
filter_sizes = (2, 3, 4)
convs = nn.ModuleList(
[nn.Conv2d(1, config.num_filters, (k, config.hidden_size))
for k in config.filter_sizes])
bert=BertModel.from_pretrained('bert-base-chinese')
encoder_out = self.bert(context, attention_mask=mask).last_hidden_state #[batch_size, sequence_length, hidden_size]
out = encoder_out.unsqueeze(1) # [batch_size, 1(in_channels), sequence_length, hidden_size]
out = torch.cat([self.conv_and_pool(out, conv) for conv in self.convs], 1) #[batch_size, channels*len(self.convs)]
1. nn.Conv2d
convs = nn.ModuleList([nn.Conv2d(1, num_filters, (k, hidden_size)) for k in config.filter_sizes])
這行代碼定義了一個卷積層的列表 convs
,其中每個卷積層都是通過 nn.Conv2d
創(chuàng)建的。
nn.Conv2d
是PyTorch中用于定義二維卷積層的類。在這里,通過使用 nn.Conv2d(1, config.num_filters, (k, config.hidden_size))
,創(chuàng)建了一個卷積層對象。
每一個卷積層的輸入是一個四維張量,形狀為 [batch_size, in_channels, sequence_length, embedding_size],參數(shù)解釋如下:
-
batch_size
是輸入樣本的批量大小。 -
in_channels
是輸入通道數(shù),對于文本數(shù)據(jù)通常為1,表示單通道輸入。 -
sequence_length
是輸入序列的長度,即令牌的數(shù)量。 -
embedding_size
是輸入序列中每個令牌的嵌入維度。
通過使用列表推導式和 nn.ModuleList
,將多個卷積層對象組成一個列表 self.convs
。這樣就創(chuàng)建了一個由多個卷積層組成的模塊列表。
在該代碼段中,config.filter_sizes 是一個元組,包含了多個卷積核的寬度。具體地,代碼使用列表推導式和 nn.ModuleList 創(chuàng)建了三個卷積層對象,對應于寬度為2、3和4的卷積核。
這樣設(shè)計的目的可能是為了在文本分類等任務(wù)中使用多尺度卷積操作,從不同的窗口尺寸中提取特征。每個卷積核會產(chǎn)生一個輸出特征圖,這些特征圖將被用于后續(xù)的處理或分類任務(wù)。通過使用不同寬度的卷積核,模型能夠同時捕捉不同范圍的語義信息,從而提高模型對輸入文本的理解能力。
2. conv(out)
conv=nn.Conv2d(1, num_filters, (k, config.hidden_size))
-
out
是經(jīng)過卷積層之前的輸入張量,形狀為[batch_size, in_channels, sequence_length, hidden_size]
。-
batch_size
是輸入樣本的批量大小。 -
in_channels
是輸入通道數(shù),通常為 1,因為在這個例子中,輸入是一維序列。 -
sequence_length
是輸入序列的長度。 -
hidden_size
是隱藏維度,即每個位置的特征向量的維度。
-
-
conv(out)
是經(jīng)過卷積操作后的輸出張量,形狀為[batch_size, out_channels, output_length, feature_size]
。-
batch_size
與輸入張量相同。 -
out_channels
是卷積層的輸出通道數(shù),由config.num_filters
決定。 -
output_length
是經(jīng)過卷積操作后的輸出序列長度,取決于輸入序列的長度、卷積核大小和填充方式。 -
feature_size
是每個位置的特征向量的維度,由卷積核大小和隱藏維度決定。
-
feature_size的計算方法
要計算 feature_size
,需要知道卷積核的大小和隱藏層的維度。
假設(shè)卷積核的大小為 (k, hidden_size)
,其中 k
是卷積核的寬度,hidden_size
是隱藏層的維度。在二維卷積操作中,卷積核在兩個維度上滑動,分別為序列長度和隱藏層維度。
定義序列長度output_length
和隱藏層維度feature_size
分別為H'
和W'
對于二維卷積操作,輸出張量的維度計算公式為:
[batch_size, out_channels, H', W']
其中,
-
batch_size
是批量大小, -
out_channels
是輸出通道數(shù)(卷積核個數(shù)), -
H'
是輸出特征圖的高度,計算公式為:H' = H - kernel_size[0] + 1
(默認stride為1), -
W'
是輸出特征圖的寬度,計算公式為:W' = W - kernel_size[1] + 1
(默認stride為1),
。
綜上所述,當卷積核大小為 (k, hidden_size)
時,執(zhí)行卷積操作后,輸出張量的形狀為 [batch_size, out_channels, output_length, 1]
,其中 out_channels
是卷積層的輸出通道數(shù),output_length
是根據(jù)輸入序列長度和卷積核大小計算得到的輸出序列長度,1
是隱藏層維度(hidden_size-hidden_size+1),也是每個位置的特征向量的維度(feature_size
)。
3. F.max_pool1d
F.max_pool1d
是 PyTorch 中用于一維最大池化操作的函數(shù),它的輸入和輸出張量維度要求如下:
-
輸入張量的維度要求:輸入張量的形狀應為
[batch_size, channels, sequence_length]
,其中-
batch_size
是輸入樣本的批量大小, -
channels
是輸入通道數(shù),通常對應卷積層的輸出通道數(shù), -
sequence_length
是輸入序列的長度。
-
-
輸出張量的維度:輸出張量的形狀與輸入張量的形狀相同,即
[batch_size, channels, output_length]
,其中-
batch_size
與輸入張量相同, -
channels
與輸入張量相同, -
output_length
是經(jīng)過最大池化操作后的輸出序列長度,它取決于池化窗口大小、步幅和填充方式。
-
-
x = torch.nn.functional.max_pool1d(x, x.size(2))
-
x
是輸入張量,假設(shè)形狀為[batch_size, channels, sequence_length]
。 -
x.size(2)
返回輸入張量x
在第三個維度上的大小,即輸入序列的長度sequence_length
。
-
需要注意的是,F.max_pool1d
只能在輸入張量的最后一個維度上進行池化操作,即在序列維度上進行池化。池化窗口的大小、步幅以及填充方式可以通過參數(shù)進行指定。在進行一維最大池化操作時,每個窗口中的最大值將被提取出來形成輸出張量。
如果輸入張量的形狀不符合要求,可以使用相應的函數(shù)進行形狀調(diào)整,如 torch.unsqueeze
來增加維度或 torch.transpose
進行維度交換,以滿足 F.max_pool1d
函數(shù)的要求。
4. Bert預訓練模型上疊加CNN模型
要在BERT預訓練模型的基礎(chǔ)上疊加CNN模型用于分類,可以考慮使用模型的輸出 last_hidden_state
和 pooler_output
作為卷積層的輸入具有不同的特點和適用性:
-
last_hidden_state
:last_hidden_state
是BERT模型最后一個隱藏層的輸出,它是一個形狀為[batch_size, sequence_length, hidden_size]
的張量。在使用last_hidden_state
作為卷積層的輸入時,可以考慮以下情況:- 適用性:
last_hidden_state
包含了每個輸入令牌的上下文相關(guān)表示,可以捕捉到輸入序列的詳細信息。因此,它適用于需要使用局部特征進行分類或處理的任務(wù),例如文本分類、命名實體識別等。通過卷積操作,可以提取不同尺寸的局部特征,以便對輸入進行更細粒度的分析和建模。 - 注意事項:由于
last_hidden_state
的形狀是[batch_size, sequence_length, hidden_size]
,在應用卷積操作之前,需要將其轉(zhuǎn)換為[batch_size, 1, sequence_length, hidden_size]
的四維張量,以匹配卷積層的輸入要求。
- 適用性:
-
pooler_output
:pooler_output
是BERT模型經(jīng)過池化操作得到的輸出,它是一個形狀為[batch_size, hidden_size]
的張量。在使用pooler_output
作為卷積層的輸入時,可以考慮以下情況:- 適用性:
pooler_output
可以看作是整個輸入序列的池化表示,具有更高級別的語義信息。因此,它適用于對整個序列進行分類或處理的任務(wù),例如句子級情感分類、文本相似度等。通過卷積操作,可以進一步提取pooler_output
中的特征,以便對輸入序列進行更深入的分析和建模。 - 注意事項:由于
pooler_output
的形狀是[batch_size, hidden_size]
,在應用卷積操作之前,需要將其轉(zhuǎn)換為[batch_size, 1, 1, hidden_size]
的四維張量,以匹配卷積層的輸入要求。
- 適用性:
在實際應用中,選擇使用哪個輸出作為卷積層的輸入取決于任務(wù)需求和數(shù)據(jù)特點。如果任務(wù)需要更詳細的局部特征,可以使用 last_hidden_state
;如果任務(wù)更關(guān)注整體語義信息或句子級別的表示,可以使用 pooler_output
。同時,還可以嘗試不同的組合和變體,以找到最適合任務(wù)的輸入表示。
三、lstm的輸入和輸出
from transformers import BertModel
from torch import nn
bert=BertModel.from_pretrained('bert-base-chinese')
lstm=nn.LSTM(input_size, rnn_hidden_size, num_layers, bidirectional=True, batch_first=True, dropout=config.dropout)
# nn.LSTM(輸入特征大小, 隱藏狀態(tài)大小, lstm層數(shù), 是否為雙向, 輸入張量第一維是否為批量維度, 丟棄率, bias=True是否使用偏置項)
encoder_out= bert(context, attention_mask=mask).last_hidden_state # [batch_size, sequence_length, hidden_size]
out, _ = self.lstm(encoder_out)
1.默認batch_first=False
nn.LSTM()
函數(shù)的輸入?yún)?shù)如下:
-
input_size
:輸入特征的大小。 -
hidden_size
:隱藏狀態(tài)的大小。 -
num_layers
:LSTM的層數(shù)。 -
bias
:是否使用偏置項,默認為True。 -
batch_first
:輸入張量是否具有批量維度在第一維,默認為False。 -
dropout
:應用于LSTM層輸出的丟棄率,默認為0。 -
bidirectional
:是否使用雙向LSTM,默認為False。
該模型的輸入?yún)?shù)和輸出結(jié)果的類型和維度如下:
-
輸入?yún)?shù):
-
input
:形狀為[sequence_length, batch_size, input_size]
的輸入張量,其中-
sequence_length
是輸入序列的長度, -
batch_size
是輸入樣本的批量大小, -
input_size
是輸入特征的大小。
-
-
h_0
:形狀為[num_layers * num_directions, batch_size, hidden_size]
的初始隱藏狀態(tài)張量,其中-
num_layers
是LSTM的層數(shù), -
num_directions
是LSTM的方向數(shù)(雙向為2,單向為1), -
batch_size
是輸入樣本的批量大小, -
hidden_size
是隱藏狀態(tài)的大小。
-
-
c_0
:形狀為[num_layers * num_directions, batch_size, hidden_size]
的初始細胞狀態(tài)張量,具有與h_0
相同的維度。
-
-
輸出結(jié)果:
-
output
:形狀為[sequence_length, batch_size, num_directions * hidden_size]
的輸出序列張量,其中-
sequence_length
是輸入序列的長度, -
batch_size
是輸入樣本的批量大小, -
num_directions
是LSTM的方向數(shù)(雙向為2,單向為1), -
hidden_size
是隱藏狀態(tài)的大小。
-
-
h_n
:形狀為[num_layers * num_directions, batch_size, hidden_size]
的最后一個時間步的隱藏狀態(tài)張量,具有與h_0
相同的維度。 -
c_n
:形狀為[num_layers * num_directions, batch_size, hidden_size]
的最后一個時間步的細胞狀態(tài)張量,具有與h_0
相同的維度。
-
請注意,輸入?yún)?shù)和輸出結(jié)果的維度和類型是基于輸入張量和參數(shù)的實際形狀和設(shè)置。上述描述是一般情況下的示例,具體的維度和類型可能會因具體的輸入數(shù)據(jù)形狀和模型參數(shù)而有所不同。
示例:
import torch
import torch.nn as nn
input_size = 10
hidden_size = 20
num_layers = 2
batch_size = 4
sequence_length = 6
num_directions = 1
lstm = nn.LSTM(input_size, hidden_size, num_layers, bidirectional=False, batch_first=False)
input = torch.randn(sequence_length, batch_size, input_size)
h_0 = torch.randn(num_layers * num_directions, batch_size, hidden_size)
c_0 = torch.randn(num_layers * num_directions, batch_size, hidden_size)
output, (h_n, c_n) = lstm(input, (h_0, c_0))
print("Output shape:", output.shape)
print("Hidden state shape:", h_n.shape)
print("Cell state shape:", c_n.shape)
2. 設(shè)置batch_first=True
如果在使用nn.LSTM()
時設(shè)置了batch_first=True
,那么輸入張量的形狀為 [batch_size, sequence_length, hidden_size]
,其中:
-
batch_size
表示批量大小,即輸入數(shù)據(jù)中的樣本數(shù)量。 -
sequence_length
表示序列的長度,即每個樣本的時間步數(shù)或序列長度。 -
hidden_size
表示 LSTM 模型的隱藏狀態(tài)的維度。
在這種設(shè)置下,nn.LSTM()
的輸出張量的形狀為 [batch_size, sequence_length, num_directions * hidden_size]
,其中:
-
num_directions
表示 LSTM 模型的方向數(shù),通常為 1(單向 LSTM)或 2(雙向 LSTM)。 -
hidden_size
表示 LSTM 模型的隱藏狀態(tài)的維度。
輸出張量中的 num_directions
是由 LSTM 模型的 bidirectional
參數(shù)決定的。如果 bidirectional=True
,則輸出張量中的 num_directions
為 2,即包括正向和反向的隱藏狀態(tài);如果 bidirectional=False
,則輸出張量中的 num_directions
為 1,即只包括正向的隱藏狀態(tài)。
因此,當 batch_first=True
時,nn.LSTM()
模型的輸出張量形狀為 [batch_size, sequence_length, num_directions * hidden_size]
。文章來源:http://www.zghlxwxcb.cn/news/detail-507111.html
注意
如果想在Bert預訓練模型輸出的基礎(chǔ)上增加LSTM層,由于Bert模型的輸出out.last_hidden_state張量的形狀一致,可以直接作為輸入傳入LSTM層,無需像CNN一樣進行形狀轉(zhuǎn)換。此時,應該將batch_first
設(shè)置為True
。文章來源地址http://www.zghlxwxcb.cn/news/detail-507111.html
到了這里,關(guān)于【自然語言處理NLP】Bert預訓練模型、Bert上搭建CNN、LSTM模型的輸入、輸出詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!