このシリーズは、7月のアルゴリズムnlp雇用クラスの研究ノートです。
3つの分類方法:単語平均化モデル、RNN、CNN。
1データの準備
最初のステップは、データを準備することです。コードで使用されているクラスライブラリは、spacyとtorchtextです。
torchtextには、各テキストフィールドを処理するためのdata.Fieldがあります。dataLabelFiledはラベルフィールドを処理します。
1.1データセットの分割
データセットは、トレーニングセット、検証セット、テストセットに分けられます。各データセットのデータ量を理解し、各データがどのように見えるかを確認します。
各文はサンプルです。
1.2語彙を作成する
TEXT.build_vocab(train_data, max_size=25000, vectors="glove.6B.100d", unk_init=torch.Tensor.normal_)
LABEL.build_vocab(train_data)
語彙のサイズを設定し、単語ベクトルで語彙を初期化します。
1.3バッチデータ、イテレータを作成
トレーニングがバッチの場合、バッチトレーニング。Torchtextは、短い文を最長の文と同じ長さにパディングします。
train_iterator, valid_iterator, test_iterator = data.BucketIterator.splits(
(train_data, valid_data, test_data),
batch_size=BATCH_SIZE,
device=device)
データの準備ができたら、モデルを使用してトレーニングを開始します。
2単語平均化モデル
まず、簡単な単語平均化モデルを紹介します。このモデルは非常に単純です。各単語を埋め込みレイヤーを介して単語埋め込みベクトルに投影し、文全体のベクトル表現である文内のすべての単語ベクトルを平均します。
次に、この文ベクトルを分類のために線形レイヤーに渡します。
平均化する方法は?avg_pool2dを使用して平均プーリングを実行します。私たちの目標は、文の長さの次元を平均して1にし、埋め込みの次元を保持することです。
avg_pool2dのカーネルサイズは(embedded.shape [1]、1)であるため、文の長さの次元は押しつぶされます。
import torch.nn as nn
import torch.nn.functional as F
class WordAVGModel(nn.Module):
def __init__(self, vocab_size, embedding_dim, output_dim, pad_idx):
super().__init__()
self.embedding = nn.Embedding(vocab_size, embedding_dim, padding_idx=pad_idx)
self.fc = nn.Linear(embedding_dim, output_dim)
def forward(self, text):
embedded = self.embedding(text) # [sent len, batch size, emb dim]
embedded = embedded.permute(1, 0, 2) # [batch size, sent len, emb dim]
pooled = F.avg_pool2d(embedded, (embedded.shape[1], 1)).squeeze(1) # [batch size, embedding_dim]
return self.fc(pooled)
次のステップは、モデルのトレーニングと評価です。
3RNNモデル
最後の非表示状態hTh_Tを使用しますhT文全体を表すため。
次に、h T h_ThT線形変換fを介して、文の感情を予測するために使用されます。
class RNN(nn.Module):
def __init__(self, vocab_size, embedding_dim, hidden_dim, output_dim,
n_layers, bidirectional, dropout, pad_idx):
super().__init__()
self.embedding = nn.Embedding(vocab_size, embedding_dim, padding_idx=pad_idx)
self.rnn = nn.LSTM(embedding_dim, hidden_dim, num_layers=n_layers,
bidirectional=bidirectional, dropout=dropout)
self.fc = nn.Linear(hidden_dim*2, output_dim)
self.dropout = nn.Dropout(dropout)
def forward(self, text):
embedded = self.dropout(self.embedding(text)) #[sent len, batch size, emb dim]
output, (hidden, cell) = self.rnn(embedded)
#output = [sent len, batch size, hid dim * num directions]
#hidden = [num layers * num directions, batch size, hid dim]
#cell = [num layers * num directions, batch size, hid dim]
#concat the final forward (hidden[-2,:,:]) and backward (hidden[-1,:,:]) hidden layers
#and apply dropout
hidden = self.dropout(torch.cat((hidden[-2,:,:], hidden[-1,:,:]), dim=1)) # [batch size, hid dim * num directions]
return self.fc(hidden.squeeze(0))
4 CNN
CNNは各ローカルエリアの機能を提案することができます。文の感情分類に使用される場合、実際にはngramの特徴抽出です。
まず、埋め込みを実行して、各単語の単語ベクトルを取得します。これは、k次元のベクトルです。各単語の単語ベクトルを組み合わせて、nxk行列を取得します。nは単語数です。
次に、畳み込み層フィルター。これは、hgramと同等になりました。最後に、それはh語に変換されます。
wはhxkです。
hワードの各ウィンドウは、このフィルターによって変換されます。c = [c 1、c 2、... cn − h − 1] c = [c_1、c_2、... c_ {nh-1}]c=[ c1、c2、。。。cN - H - 1]
3番目のステップは、max-over-timeプーリングを実行することです。C ^ = max {c} \ widehat {C} = max \ {c \}C =m a x { c }
m個のフィルターがある場合、z = [C 1 ^、C 2 ^、... C m ^] z = [\ widehat {C_1}、\ widehat {C_2}、... \ widehat {C_m} ]から=[C1 、C2 、。。。Cメートル ]
4番目のステップは、分類を取得するためにzで線形変換を実行することです。