前提・実現したいこと
閲覧ありがとうございます。初めての質問、深層学習の初学者です。
参考書を元にpytorchでseq2seqモデルを構築しました。
このモデルの性能を上げるために、学習済みのBERTモデルを組み込んで学習を行いました。
BERTを組み込んだ学習済みモデルで日英翻訳を行ったがうまく学習できていません
発生している問題・エラーメッセージ
モデルの学習を行うプログラムは正常に動いているようで、損失が順調に減っていきますが、
このモデルで翻訳を行うと意味不明な文字列が出力されてしまいます
該当のソースコード
python
1class MyAttNMT(nn.Module): 2 def __init__(self, jv, ev, k, jmodel, emodel): 3 super(MyAttNMT, self).__init__() 4 self.jmodel = jmodel 5 self.emodel = emodel 6 self.lstm1 = nn.LSTM(k, k, num_layers=2, batch_first=True) 7 self.lstm2 = nn.LSTM(k, k, num_layers=2, batch_first=True) 8 self.Wc = nn.Linear(2*k, k) 9 self.W = nn.Linear(k, ev) 10 def forward(self, jline, eline): 11 x = self.jmodel(jline) 12 ox, (hnx, cnx) = self.lstm1(x[0]) 13 y = self.emodel(eline) 14 oy, (hny, cny) = self.lstm2(y[0],(hnx, cnx)) 15 ox1 = ox.permute(0,2,1) 16 sim = torch.bmm(oy,ox1) 17 bs, yws, xws = sim.shape 18 sim2 = sim.reshape(bs*yws,xws) 19 alpha = F.softmax(sim2,dim=1).reshape(bs, yws, xws) 20 ct = torch.bmm(alpha,ox) 21 oy1 = torch.cat([ct,oy],dim=2) 22 oy2 = self.Wc(oy1) 23 return self.W(oy2)
引数はjv=日本語BERTモデルの語彙数、ev=英語BERTモデルの語彙数、k=設定次元数、
jmodelは日本語BERTモデル、emodelは英語BERTモデル、
jlineはテンソル型の和文の単語ID配列、elineはテンソル型の英文の単語ID配列
jv,evはどちらも30000語ほどで設定次元数はBERTモデルの単語ベクトルの次元数に合わせて768にしてあります
学習用の対訳ペアは50000文で100エポックほど学習を行いました
試したこと
最初、BERTモデルのところはpytorchのnn.Embedding()を使用しており、埋め込み語彙数は日本語9000語、英語14000語、設定次元数は200で50000文を100エポック分の学習を行いました。そのときはそれなりに翻訳できていて、比較的短め文はちゃんと翻訳できていました。
自分の中で考えでは最後のnn.Linearが入力次元数が768次元で出力次元数が30000次元とかなり差が大きくなっていてうまく学習できていないのかなと考えています。この考えは正しいのでしょうか?このような場合は根気強くうまくいく次元数を探していかなければならないのでしょうか?
一応、ネットで同じような構成を探してみたり、次元数の設定のコツなどについて調べてみたりしたのですが、見つかりませんでした
ご助言をいただけるとありがたいです
補足情報(FW/ツールのバージョンなど)
現在、実行環境、ソースコードが手元になく、上記ソースコードのBERTモデルの定義部分に間違いがあるかもしれません。
プログラムの動作は確認できているので、ソースコードはネットワークの構成の参考にしてください
あなたの回答
tips
プレビュー