YutaroOgawa / pytorch_advanced

書籍「つくりながら学ぶ! PyTorchによる発展ディープラーニング」の実装コードを配置したリポジトリです
MIT License
844 stars 335 forks source link

【第8章:】Fieldインスタンスを作成する際のエラー #64

Open ghost opened 4 years ago

ghost commented 4 years ago

現在、BERTでモデルを作成しております。 TEXT = torchtext.data.Field(sequential=True, tokenize=tokenizer_with_preprocessing, use_vocab=True, lower=True, include_lengths=True, batch_first=True, fix_length=max_length, init_token="[CLS]", eos_token="[SEP]", pad_token='[PAD]', unk_token="[UNK]") 上記のコードを実行し、DataLoaderを作成するところまで行いました。 しかし、下記のコードで動作確認を行うと、Key Errorを起こしてしまいます。

動作確認 検証データのデータセットで確認

batch = next(iter(val_dl)) print(batch.Text) print(batch.Label)

KeyError: [unk]

デバッグで確認してみると、どうやらtorchtext.data.Fieldのオプションでlower=Trueにしてるせいで[UNK]が[unk]になってしまい、取得ができないようでした。 どういう理由でこうなってしまうのかは分からない上に、torch側のバグなのか私の実装のミスなのか分からずにいます。 一度確認いただけますでしょうか。

宜しくお願い致します。

YutaroOgawa commented 4 years ago

@tnomura-git さま

ご連絡ありがとうございます。

さきほど試したところ、 私が1週間前に構築した環境(Ubuntu、AWS)では、 8-4_bert_IMDb.ipynbの、該当部分は問題なく実行できました。BERTの学習まで実行できています。

unk_token="[UNK]"などで、直接指定しているので、[UNK]や[SEP]などには、lowerは効いていない状態です。 以下出力結果。

8-4_bert

また、Pythonのバージョンは、 Python 3.6.5 :: Anaconda, Inc.

PyTorch周りのバージョンは、 torch '1.4.0' torchtext '0.5.0'

となっています。

OSがWindowsだと自然言語処理、文字系はいろいろエラーが発生しやすいです。 問題が解決しておらず、大変申し訳ございませんが、いかがでしょうか?

ghost commented 4 years ago

ご返信ありがとうございます。 その後確認してみるとwindowsの挙動がおかしいようでした。 しかし、UbuntuとWindowsで予想外のところで挙動が違うのは驚きでした。 アドバイス頂きありがとうございました。

もう一つ質問させてください。 サンプルのdata_datasetはtrainデータからvalとtestをsplitで書き出しているのでtestにもラベルがついていると思います。 しかし現実問題、予測をするときはtestはラベルがついていないという認識でいます。 test_dlを回す際、ラベルがついていないとintに変換できずエラーになります。 ValueError: invalid literal for int() with base 10: '' ラベルが空でも予測をするにはどうしたらよいでしょうか。 明示的にラベルを0埋めでも良いのかなと思いましたが、どうも納得が出来ないです。

宜しくお願い致します。

YutaroOgawa commented 4 years ago

@tnomura-git さま

早速のご確認ありがとうございます。 Windowsでの挙動だったとのことで、他の読者の皆様にも参考になる情報をありがとうございます。 非常に助かります。

testを回す際に、Labelをいれないといけないのは、

8-4_bert_IMDb.ipynbの、

train_val_ds, test_ds = torchtext.data.TabularDataset.splits( path='./data/', train='IMDb_train.tsv', test='IMDb_test.tsv', format='tsv', fields=[('Text', TEXT), ('Label', LABEL)])

で、 fields=[('Text', TEXT), ('Label', LABEL)]) でラベルを含むように指定しているからです。

このfields部分を fields=[('Text', TEXT)])

とすれば、ラベルを含まないDatasetを作ることができます。

訓練データおよび検証データのDatasetと テストデータのDatasetを別々に作ればラベルを含むDatasetと テスト用の含まないDatasetを作ることができます。

https://torchtext.readthedocs.io/en/latest/data.html#tabulardataset

実際に動かして確かめていないのですが、おそらく、

train_val_ds = torchtext.data.TabularDataset.splits( path='./data/', train='IMDb_train.tsv', test=None, format='tsv', fields=[('Text', TEXT), ('Label', LABEL)])

test_ds = torchtext.data.TabularDataset.splits( path='./data/', train=None', test='IMDb_test.tsv', format='tsv', fields=[('Text', TEXT)])

なイメージ、です。

どうぞよろしくお願い致します。