示例#1
0
def run_main():
    args = parse_arg()
    if args.IMDb:
        ds = ds_imdb
    else:
        ds = ds_jptxt

    print("1. preparing datasets ... ", end="", flush=True)
    dataset_generator = ds.DataSetGenerator(args.vocab_file[0],
                                            args.text_length,
                                            mecab_dict=args.mecab_dict)
    test_ds = dataset_generator.loadTSV(args.tsv_file[0])
    test_dl = ds.get_data_loader(test_ds, args.batch_size, for_train=False)
    dataset_generator.build_vocab(test_ds)
    print("done.", flush=True)

    print("2. loading network ... ", end="", flush=True)
    conf = get_config(file_path=args.conf[0])
    bert_base = BertModel(conf)
    net = BertClassifier(bert_base, out_features=2)
    net.load_state_dict(torch.load(args.load_path[0]))
    net.eval()

    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    net.to(device)
    print("done.", flush=True)

    criterion = torch.nn.CrossEntropyLoss()  # クラス分けの場合
    # criterion = torch.nn.MSELoss()  # 数値予測の場合

    print("3. run tests. ", flush=True)
    epoch_acc = test_model(net, test_dl, criterion, device)
    print("# of test data: {} || Acc. {:.4f}".format(len(test_dl.dataset),
                                                     epoch_acc))
示例#2
0
def bert_model():
    config = get_config(file_path=BERT_CONFIG)
    net_bert = BertModel(config)
    net_trained = BertForEmoji(net_bert)
    net_trained.load_state_dict(
        torch.load(MODEL_FILE, map_location=torch.device('cpu')))
    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    net_trained.eval()
    net_trained.to(device)
    return net_trained
示例#3
0
def build_bert_model():
    
    config = get_config(file_path=BERT_CONFIG)
    net_bert = BertModel(config) # BERTモデルを作成します
    net_trained = BertForchABSA(net_bert)
    net_trained.load_state_dict(torch.load(MODEL_FILE, map_location='cpu'))
    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    net_trained.eval()   # モデルを検証モードに
    net_trained.to(device)

    return net_trained
    def __init__(self,
                 data_dir=r'./',
                 bert_dir=r'./pytorch_advanced/nlp_sentiment_bert/'):
        self.data_dir = data_dir
        self.bert_dir = bert_dir
        self.tokenizer_bert = BertTokenizer(
            vocab_file=self.bert_dir + "vocab/bert-base-uncased-vocab.txt",
            do_lower_case=True)
        self.vocab_bert, self.ids_to_tokens_bert = load_vocab(
            vocab_file=self.bert_dir + "vocab/bert-base-uncased-vocab.txt")

        config = get_config(file_path=self.bert_dir +
                            "weights/bert_config.json")
        self.net_bert = BertModel(config)
        self.net_bert = set_learned_params(self.net_bert,
                                           weights_path=self.bert_dir +
                                           "weights/pytorch_model.bin")
示例#5
0
def run_main():
    args = parse_arg()
    if args.random_seed is not None:
        init_random_seed(args.random_seed)

    if args.IMDb:
        ds = ds_imdb
    else:
        ds = ds_jptxt

    print("1. preparing datasets ... ", end="", flush=True)
    dataset_generator = ds.DataSetGenerator(
        args.vocab_file[0],
        args.text_length,
        do_normalize_text=args.normalize_text,
        mecab_dict=args.mecab_dict)

    data_set = dataset_generator.loadTSV(args.train_tsv[0])
    train_ds, validation_ds = data_set.split(split_ratio=0.8,
                                             random_state=random.seed(1234))
    dataset_generator.build_vocab(train_ds)

    train_dl = ds.get_data_loader(train_ds, args.batch_size, for_train=True)
    validation_dl = ds.get_data_loader(validation_ds,
                                       args.batch_size,
                                       for_train=False)
    print("done.", flush=True)

    print("2. preparing network ... ", end="", flush=True)
    conf = get_config(file_path=args.conf[0])
    bert_base = BertModel(conf)
    bert_base = set_learned_params(bert_base, weights_path=args.bert_model[0])
    net = BertClassifier(bert_base, out_features=2)  # out_features = クラス数
    net.train()

    optimizer = get_optimizer(net)
    criterion = torch.nn.CrossEntropyLoss()  # クラス分けの場合
    # criterion = torch.nn.MSELoss()  # 数値予測の場合
    print("done.", flush=True)

    print("3. start to train.", flush=True)
    data_loader_set = {"train": train_dl, "validation": validation_dl}
    net_trained = train_model(net, data_loader_set, criterion, optimizer,
                              args.epoch)
    if args.save_path is not None:
        torch.save(net_trained.to("cpu").state_dict(), args.save_path)
示例#6
0
def run_main():
    args = parse_arg()

    if args.IMDb:
        ds = ds_imdb
    else:
        ds = ds_jptxt

    print("1. preparing datasets ... ", end="", flush=True)
    dataset_generator = ds.DataSetGenerator(args.vocab_file[0],
                                            args.text_length, args.mecab_dict)
    dataset = dataset_generator.loadTSV_at_index(args.tsv_file[0], args.index)
    dataset_generator.build_vocab(dataset)
    dataloader = ds.get_data_loader(dataset, args.batch_size, for_train=False)
    print("done.", flush=True)

    print("2. loading network ... ", end="", flush=True)
    conf = get_config(file_path=args.conf[0])
    bert_base = BertModel(conf)
    net = BertClassifier(bert_base, out_features=2)
    net.load_state_dict(torch.load(args.load_path[0]))
    net.eval()

    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    net.to(device)
    print("done.", flush=True)

    example = next(iter(dataloader))
    inputs = example.Text[0].to(device)  # 文章
    preds, attention_probs = predict(net, inputs)
    if args.save_html is not None:
        print("3. generating HTML file.", flush=True)
        html = mk_html(example.Text[0][0], example.Label[0], preds[0],
                       attention_probs, dataset_generator.tokenizer)
        with open(args.save_html, "w") as f:
            f.write(html)

    elif args.save_raw_attn is not None:
        print("3. generating raw attention tsv file.", flush=True)
        mk_high_attention_words_list(example.Text[0][0], example.Label[0],
                                     preds[0], attention_probs,
                                     dataset_generator.tokenizer,
                                     args.save_raw_attn)
    else:
        print("no flag for saving file")
示例#7
0
# IDを単語に戻す
text = tokenizer_bert.convert_ids_to_tokens(text_minibatch_1)

print(text)


# # 2.BERTによるネガポジ分類モデル実装

# In[16]:


from utils.bert import get_config, BertModel,BertForchABSA, set_learned_params

# モデル設定のJOSNファイルをオブジェクト変数として読み込みます
config = get_config(file_path="./weights/bert_config.json")

# BERTモデルを作成します
net_bert = BertModel(config)

# BERTモデルに学習済みパラメータセットします
net_bert = set_learned_params(
    net_bert, weights_path="./weights/pytorch_model.bin")


# In[17]:


# モデル構築
net = BertForchABSA(net_bert)
示例#8
0
            encoded_layers, _ = self.bert(
                input_ids, token_type_ids, attention_mask, output_all_encoded_layers, attention_show_flg)
        # 入力文章の1単語目[CLS]の特徴量を使用して、ポジ・ネガを分類します
        vec_0 = encoded_layers[:, 0, :]
        vec_0 = vec_0.view(-1, self.cls.in_features)  # sizeを[batch_size, hidden_sizeに変換
        out = self.cls(vec_0)

        # attention_showのときは、attention_probs(1番最後の)もリターンする
        if attention_show_flg == True:
            return out, attention_probs
        elif attention_show_flg == False:
            return out


if __name__ == "__main__":
    import argparse
    from utils.bert import BertModel, get_config, set_learned_params

    def parse_arg():
        parser = argparse.ArgumentParser(description="Test for BERT for Japanese Texts.")
        parser.add_argument("conf", type=str, nargs=1, help="a configuration file.")
        parser.add_argument("model", type=str, nargs=1, help="a trained model file.")
        return parser.parse_args()

    args = parse_arg()
    conf = get_config(file_path=args.conf[0])
    bert_base = BertModel(conf)
    bert_base = set_learned_params(bert_base, weights_path=args.model[0])
    net = BertClassifier(bert_base, out_features=2)
    print(net)
def main():
    # define output dataframe
    sample = pd.read_csv("./data/sample_submission.csv")
    # データを読み込んだときに、読み込んだ内容に対して行う処理を定義します
    max_length = 256

    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]')

    LABEL1 = torchtext.data.Field(sequential=False, use_vocab=False)
    LABEL2 = torchtext.data.Field(sequential=False, use_vocab=False)
    LABEL3 = torchtext.data.Field(sequential=False, use_vocab=False)
    LABEL4 = torchtext.data.Field(sequential=False, use_vocab=False)
    LABEL5 = torchtext.data.Field(sequential=False, use_vocab=False)
    LABEL6 = torchtext.data.Field(sequential=False, use_vocab=False)

    # (注釈):各引数を再確認
    # sequential: データの長さが可変か?文章は長さがいろいろなのでTrue.ラベルはFalse
    # tokenize: 文章を読み込んだときに、前処理や単語分割をするための関数を定義
    # use_vocab:単語をボキャブラリーに追加するかどうか
    # lower:アルファベットがあったときに小文字に変換するかどうか
    # include_length: 文章の単語数のデータを保持するか
    # batch_first:ミニバッチの次元を先頭に用意するかどうか
    # fix_length:全部の文章を指定した長さと同じになるように、paddingします
    # init_token, eos_token, pad_token, unk_token:文頭、文末、padding、未知語に対して、どんな単語を与えるかを指定

    # フォルダ「data」から各tsvファイルを読み込みます
    # BERT用で処理するので、10分弱時間がかかります
    temp_path = preprocessing.reformat_csv_header(path="./data",
                                                  train_file="train.csv",
                                                  test_file="test.csv")

    print("temp path {}".format(temp_path))
    print("text {}".format(vars(TEXT)))

    train_val_ds, test_ds = torchtext.data.TabularDataset.splits(
        path=temp_path,
        train='train.csv',
        test='test.csv',
        format='csv',
        fields=[('Text', TEXT), ('toxic', LABEL1), ('severe_toxic', LABEL2),
                ('obscene', LABEL3), ('threat', LABEL4), ('insult', LABEL5),
                ('identity_hate', LABEL6)])

    # torchtext.data.Datasetのsplit関数で訓練データとvalidationデータを分ける
    train_ds, val_ds = train_val_ds.split(split_ratio=0.8,
                                          random_state=random.seed(2395))

    # BERTはBERTが持つ全単語でBertEmbeddingモジュールを作成しているので、ボキャブラリーとしては全単語を使用します
    # そのため訓練データからボキャブラリーは作成しません

    vocab_bert, ids_to_tokens_bert = load_vocab(
        vocab_file="./weights/bert-base-uncased-vocab.txt")

    # このまま、TEXT.vocab.stoi= vocab_bert (stoiはstring_to_IDで、単語からIDへの辞書)としたいですが、
    # 一度bulild_vocabを実行しないとTEXTオブジェクトがvocabのメンバ変数をもってくれないです。
    # ('Field' object has no attribute 'vocab' というエラーをはきます)

    # 1度適当にbuild_vocabでボキャブラリーを作成してから、BERTのボキャブラリーを上書きします
    TEXT.build_vocab(train_ds, min_freq=1)
    TEXT.vocab.stoi = vocab_bert

    # DataLoaderを作成します(torchtextの文脈では単純にiteraterと呼ばれています)
    batch_size = 16  # BERTでは16、32あたりを使用する

    train_dl = torchtext.data.Iterator(train_ds,
                                       batch_size=batch_size,
                                       train=True)

    val_dl = torchtext.data.Iterator(val_ds,
                                     batch_size=batch_size,
                                     train=False,
                                     sort=False)

    test_dl = torchtext.data.Iterator(test_ds,
                                      batch_size=batch_size,
                                      train=False,
                                      sort=False)

    # 辞書オブジェクトにまとめる
    dataloaders_dict = {"train": train_dl, "val": val_dl}

    print(vars(train_ds[0]))
    print(vars(test_ds[0]))

    # モデル設定のJOSNファイルをオブジェクト変数として読み込みます
    config = get_config(file_path="./weights/bert_config.json")

    # BERTモデルを作成します
    net_bert = BertModel(config)

    # BERTモデルに学習済みパラメータセットします
    net_bert = set_learned_params(net_bert,
                                  weights_path="./weights/pytorch_model.bin")

    for label in [
            'toxic', 'severe_toxic', 'obscene', 'threat', 'insult',
            'identity_hate'
    ]:
        # モデル構築
        net = BertTraining(net_bert)

        # 訓練モードに設定
        net.train()

        print('done setup network')

        # 勾配計算を最後のBertLayerモジュールと追加した分類アダプターのみ実行

        # 1. まず全部を、勾配計算Falseにしてしまう
        for name, param in net.named_parameters():
            param.requires_grad = False

        # 2. 最後のBertLayerモジュールを勾配計算ありに変更
        for name, param in net.bert.encoder.layer[-1].named_parameters():
            param.requires_grad = True

        # 3. 識別器を勾配計算ありに変更
        for name, param in net.cls.named_parameters():
            param.requires_grad = True

        # 最適化手法の設定

        # BERTの元の部分はファインチューニング
        optimizer = optim.Adam(
            [{
                'params': net.bert.encoder.layer[-1].parameters(),
                'lr': 5e-5
            }, {
                'params': net.cls.parameters(),
                'lr': 5e-5
            }],
            betas=(0.9, 0.999))

        # 損失関数の設定
        criterion = nn.CrossEntropyLoss()
        # nn.LogSoftmax()を計算してからnn.NLLLoss(negative log likelihood loss)を計算

        device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

        # 学習・検証を実行する。1epochに20分ほどかかります
        num_epochs = 2
        net_trained = train_model(net,
                                  dataloaders_dict,
                                  criterion,
                                  optimizer,
                                  num_epochs=num_epochs,
                                  label=label,
                                  device=device)

        # 学習したネットワークパラメータを保存します
        save_path = './weights/bert_fine_tuning_weights.pth'
        torch.save(net_trained.state_dict(), save_path)

        # テストデータ
        net_trained.eval()  # モデルを検証モードに
        net_trained.to(device)  # GPUが使えるならGPUへ送る

        predicts = []

        for batch in tqdm(test_dl):  # testデータのDataLoader
            # batchはTextとLableの辞書オブジェクト
            # GPUが使えるならGPUにデータを送る
            inputs = batch.Text[0].to(device)  # 文章

            # 順伝搬(forward)計算
            with torch.set_grad_enabled(False):
                # BertForIMDbに入力
                outputs = net_trained(inputs,
                                      token_type_ids=None,
                                      attention_mask=None,
                                      output_all_encoded_layers=False,
                                      attention_show_flg=False)

                _, preds = torch.max(outputs, 1)  # ラベルを予測

                preds = preds.cpu()
                preds = preds.numpy().tolist()

                predicts += preds

        sample[label] = predicts

    # save predictions
    if not os.path.exists("./submission"):
        os.mkdir("./submission")
    sample.to_csv("./submission/submission_Bert_{}_{}ep.csv".format(
        datetime.datetime.now().date(), num_epochs),
                  index=False)