Transformers(16) - 要約④要約実行

学習したモデルを使って要約を行います。

要約

要約を行うコードは以下の通りです。

5行目で、日本語T5事前学習済みモデルのトークナイザーを読み込んでいます。

6行目では、前回ファインチューニングした要約モデルをoutputフォルダから読み込んでいます。

9行目に、要約対象の文章を設定しています。

[Google Colaboratory]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import torch
from transformers import pipeline, AutoTokenizer, AutoModelForSeq2SeqLM

# トークナイザーとモデルの準備
tokenizer = AutoTokenizer.from_pretrained('sonoisa/t5-base-japanese')
model = AutoModelForSeq2SeqLM.from_pretrained('output/')

# テキスト
text = "ぴちぴちのおねえさんが川でせんたくをしていると、ドンブラコ、ドンブラコと、大きな桃が流れてきました。おねえさんは大きな桃をひろいあげて、家に持ち帰りました。そして、ギャル男とおねえさんが桃を食べようと桃を切ってみると、なんと中から元気 の良いドランゴンの赤ちゃんが飛び出してきました。"

# テキストをテンソルに変換
input = tokenizer.encode(text, return_tensors='pt', max_length=512, truncation=True)

# 推論
model.eval()
with torch.no_grad():
summary_ids = model.generate(input)
print(tokenizer.decode(summary_ids[0]))

要約結果は以下の通りです。

[実行結果]

1
2
3
4
/usr/local/lib/python3.7/dist-packages/torch/_tensor.py:575: UserWarning: floor_divide is deprecated, and will be removed in a future version of pytorch. It currently rounds toward 0 (like the 'trunc' function NOT 'floor'). This results in incorrect rounding for negative values.
To keep the current behavior, use torch.div(a, b, rounding_mode='trunc'), or for actual floor division, use torch.div(a, b, rounding_mode='floor'). (Triggered internally at /pytorch/aten/src/ATen/native/BinaryOps.cpp:467.)
return torch.floor_divide(self, other)
<pad><extra_id_0>川でせんたくをしていると、ドンブラコ、ドンブラコと大きな桃が流れてきました。</s>

・・・要約と言えば要約されていますが、主語が全部とんでますし、中盤以降を全部省略とずいぶん大胆な要約となっています。

なんらかの改善が必要なのかもしれません。

Transformers(15) - 要約③ファインチューニング

学習データと検証データを使ってファインチューニングを行います。

ファインチューニング

次のコマンドを実行し、要約のファインチューニングを行います。

[Google Colaboratory]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
%%time

# ファインチューニングの実行
!python ./transformers/examples/seq2seq/run_summarization.py \
--model_name_or_path=sonoisa/t5-base-japanese \
--do_train \
--do_eval \
--train_file=train.csv \
--validation_file=dev.csv \
--num_train_epochs=10 \
--per_device_train_batch_size=2 \
--per_device_eval_batch_size=2 \
--save_steps=5000 \
--save_total_limit=3 \
--output_dir=output/ \
--predict_with_generate \
--use_fast_tokenizer=False \
--logging_steps=100

実行結果は以下の通りです。

[実行結果]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
10/06/2021 11:45:03 - WARNING - __main__ -   Process rank: -1, device: cuda:0, n_gpu: 1distributed training: False, 16-bits training: False
10/06/2021 11:45:03 - INFO - __main__ - Training/evaluation parameters Seq2SeqTrainingArguments(output_dir='output/', overwrite_output_dir=False, do_train=True, do_eval=True, do_predict=False, evaluation_strategy=<IntervalStrategy.NO: 'no'>, prediction_loss_only=False, per_device_train_batch_size=2, per_device_eval_batch_size=2, per_gpu_train_batch_size=None, per_gpu_eval_batch_size=None, gradient_accumulation_steps=1, eval_accumulation_steps=None, learning_rate=5e-05, weight_decay=0.0, adam_beta1=0.9, adam_beta2=0.999, adam_epsilon=1e-08, max_grad_norm=1.0, num_train_epochs=10.0, max_steps=-1, lr_scheduler_type=<SchedulerType.LINEAR: 'linear'>, warmup_ratio=0.0, warmup_steps=0, logging_dir='runs/Oct06_11-45-03_2d9fb230d52a', logging_strategy=<IntervalStrategy.STEPS: 'steps'>, logging_first_step=False, logging_steps=100, save_strategy=<IntervalStrategy.STEPS: 'steps'>, save_steps=5000, save_total_limit=3, no_cuda=False, seed=42, fp16=False, fp16_opt_level='O1', fp16_backend='auto', fp16_full_eval=False, local_rank=-1, tpu_num_cores=None, tpu_metrics_debug=False, debug=False, dataloader_drop_last=False, eval_steps=100, dataloader_num_workers=0, past_index=-1, run_name='output/', disable_tqdm=False, remove_unused_columns=True, label_names=None, load_best_model_at_end=False, metric_for_best_model=None, greater_is_better=None, ignore_data_skip=False, sharded_ddp=[], deepspeed=None, label_smoothing_factor=0.0, adafactor=False, group_by_length=False, report_to=['tensorboard'], ddp_find_unused_parameters=None, dataloader_pin_memory=True, skip_memory_metrics=False, sortish_sampler=False, predict_with_generate=True)
Using custom data configuration default
Reusing dataset csv (/root/.cache/huggingface/datasets/csv/default-2359a64c962f9aac/0.0.0/2960f95a26e85d40ca41a230ac88787f715ee3003edaacb8b1f0891e9f04dda2)
loading configuration file https://huggingface.co/sonoisa/t5-base-japanese/resolve/main/config.json from cache at /root/.cache/huggingface/transformers/fb3cd498b86ea48d9c5290222d7a1b96e0acb4daa6d35a7fcb00168d59c356ee.82b38ae98529e44bc2af82ee82527f78e94856e2fb65b0ec6faecbb49d8ab639
Model config T5Config {
"_name_or_path": "/content/drive/MyDrive/T5_models/oscar_cc100_wikipedia_ja",
"architectures": [
"T5Model"
],
"bos_token_id": 0,
"d_ff": 3072,
"d_kv": 64,
"d_model": 768,
"decoder_start_token_id": 0,
"dropout_rate": 0.1,
"eos_token_id": 1,
"eos_token_ids": [
1
],
"feed_forward_proj": "relu",
"initializer_factor": 1.0,
"is_encoder_decoder": true,
"layer_norm_epsilon": 1e-06,
"max_length": 512,
"model_type": "t5",
"n_positions": 512,
"num_beams": 4,
"num_decoder_layers": 12,
"num_heads": 12,
"num_layers": 12,
"pad_token_id": 0,
"relative_attention_num_buckets": 32,
"transformers_version": "4.4.2",
"use_cache": true,
"vocab_size": 32128
}

loading configuration file https://huggingface.co/sonoisa/t5-base-japanese/resolve/main/config.json from cache at /root/.cache/huggingface/transformers/fb3cd498b86ea48d9c5290222d7a1b96e0acb4daa6d35a7fcb00168d59c356ee.82b38ae98529e44bc2af82ee82527f78e94856e2fb65b0ec6faecbb49d8ab639
Model config T5Config {
"_name_or_path": "/content/drive/MyDrive/T5_models/oscar_cc100_wikipedia_ja",
"architectures": [
"T5Model"
],
"bos_token_id": 0,
"d_ff": 3072,
"d_kv": 64,
"d_model": 768,
"decoder_start_token_id": 0,
"dropout_rate": 0.1,
"eos_token_id": 1,
"eos_token_ids": [
1
],
"feed_forward_proj": "relu",
"initializer_factor": 1.0,
"is_encoder_decoder": true,
"layer_norm_epsilon": 1e-06,
"max_length": 512,
"model_type": "t5",
"n_positions": 512,
"num_beams": 4,
"num_decoder_layers": 12,
"num_heads": 12,
"num_layers": 12,
"pad_token_id": 0,
"relative_attention_num_buckets": 32,
"transformers_version": "4.4.2",
"use_cache": true,
"vocab_size": 32128
}

loading file https://huggingface.co/sonoisa/t5-base-japanese/resolve/main/spiece.model from cache at /root/.cache/huggingface/transformers/a455eff173d5e851553673177dcb6876d5fcd0d39a4bdd7e9a75c50dfb2ab158.82c0f9a9b4ec152c1ca13afe226abd56b618ec9f9d395dc56fd3ad6ca14b4dcc
loading file https://huggingface.co/sonoisa/t5-base-japanese/resolve/main/added_tokens.json from cache at None
loading file https://huggingface.co/sonoisa/t5-base-japanese/resolve/main/special_tokens_map.json from cache at /root/.cache/huggingface/transformers/559eb952d008bbb60787ea4b89849e5a377f35e163651805b072f2fb1f4b28b9.c94798918c92ded6aeef2d2f0e666d2cc4145eca1aa6e1336fde07f2e13e2f46
loading file https://huggingface.co/sonoisa/t5-base-japanese/resolve/main/tokenizer_config.json from cache at /root/.cache/huggingface/transformers/175dd55a5be280f74e003b3b5efa1de2080efdc795da6dc013dd001d661fcb50.6de37cb3d7dbffde3a51667c5706471d3c6b2a3ff968f108c1429163c5860a5d
loading file https://huggingface.co/sonoisa/t5-base-japanese/resolve/main/tokenizer.json from cache at None
loading weights file https://huggingface.co/sonoisa/t5-base-japanese/resolve/main/pytorch_model.bin from cache at /root/.cache/huggingface/transformers/e6cfe18cc2661a1900624126a7fd3af005a942d9079fd828c4333b0f46617f58.f3773e9948a37df8ff8b19de7bdc64bbcc9fd2225fcdc41ed5a4a2be8a86f383
All model checkpoint weights were used when initializing T5ForConditionalGeneration.

All the weights of T5ForConditionalGeneration were initialized from the model checkpoint at sonoisa/t5-base-japanese.
If your task is similar to the task the model of the checkpoint was trained on, you can already use T5ForConditionalGeneration for predictions without further training.
Loading cached processed dataset at /root/.cache/huggingface/datasets/csv/default-2359a64c962f9aac/0.0.0/2960f95a26e85d40ca41a230ac88787f715ee3003edaacb8b1f0891e9f04dda2/cache-1b9264874e882057.arrow
Loading cached processed dataset at /root/.cache/huggingface/datasets/csv/default-2359a64c962f9aac/0.0.0/2960f95a26e85d40ca41a230ac88787f715ee3003edaacb8b1f0891e9f04dda2/cache-31c3668d81aead05.arrow
***** Running training *****
Num examples = 477
Num Epochs = 10
Instantaneous batch size per device = 2
Total train batch size (w. parallel, distributed & accumulation) = 2
Gradient Accumulation steps = 1
Total optimization steps = 2390
{'loss': 3.7109, 'learning_rate': 4.7907949790794984e-05, 'epoch': 0.42}
{'loss': 3.3028, 'learning_rate': 4.581589958158996e-05, 'epoch': 0.84}
{'loss': 2.9266, 'learning_rate': 4.372384937238494e-05, 'epoch': 1.26}
{'loss': 2.6457, 'learning_rate': 4.1631799163179915e-05, 'epoch': 1.67}
{'loss': 2.4916, 'learning_rate': 3.95397489539749e-05, 'epoch': 2.09}
{'loss': 2.2776, 'learning_rate': 3.744769874476988e-05, 'epoch': 2.51}
{'loss': 2.3356, 'learning_rate': 3.5355648535564854e-05, 'epoch': 2.93}
{'loss': 2.1054, 'learning_rate': 3.3263598326359835e-05, 'epoch': 3.35}
{'loss': 2.0186, 'learning_rate': 3.117154811715482e-05, 'epoch': 3.77}
{'loss': 1.9114, 'learning_rate': 2.9079497907949792e-05, 'epoch': 4.18}
{'loss': 1.8481, 'learning_rate': 2.6987447698744773e-05, 'epoch': 4.6}
{'loss': 1.7216, 'learning_rate': 2.489539748953975e-05, 'epoch': 5.02}
{'loss': 1.6217, 'learning_rate': 2.280334728033473e-05, 'epoch': 5.44}
{'loss': 1.6558, 'learning_rate': 2.0711297071129708e-05, 'epoch': 5.86}
{'loss': 1.5691, 'learning_rate': 1.8619246861924686e-05, 'epoch': 6.28}
{'loss': 1.5122, 'learning_rate': 1.6527196652719665e-05, 'epoch': 6.69}
{'loss': 1.3568, 'learning_rate': 1.4435146443514645e-05, 'epoch': 7.11}
{'loss': 1.4267, 'learning_rate': 1.2343096234309625e-05, 'epoch': 7.53}
{'loss': 1.3995, 'learning_rate': 1.0251046025104603e-05, 'epoch': 7.95}
{'loss': 1.3224, 'learning_rate': 8.158995815899583e-06, 'epoch': 8.37}
{'loss': 1.3677, 'learning_rate': 6.066945606694561e-06, 'epoch': 8.79}
{'loss': 1.3022, 'learning_rate': 3.97489539748954e-06, 'epoch': 9.21}
{'loss': 1.2621, 'learning_rate': 1.882845188284519e-06, 'epoch': 9.62}
100% 2390/2390 [33:01<00:00, 1.25it/s]

Training completed. Do not forget to share your model on huggingface.co/models =)


{'train_runtime': 1981.4145, 'train_samples_per_second': 1.206, 'epoch': 10.0}
100% 2390/2390 [33:01<00:00, 1.21it/s]
Saving model checkpoint to output/
Configuration saved in output/config.json
Model weights saved in output/pytorch_model.bin
tokenizer config file saved in output/tokenizer_config.json
Special tokens file saved in output/special_tokens_map.json
Copy vocab file to output/spiece.model
***** train metrics *****
epoch = 10.0
init_mem_cpu_alloc_delta = 1MB
init_mem_cpu_peaked_delta = 0MB
init_mem_gpu_alloc_delta = 850MB
init_mem_gpu_peaked_delta = 0MB
train_mem_cpu_alloc_delta = 0MB
train_mem_cpu_peaked_delta = 0MB
train_mem_gpu_alloc_delta = 2575MB
train_mem_gpu_peaked_delta = 5616MB
train_runtime = 1981.4145
train_samples = 477
train_samples_per_second = 1.206
10/06/2021 12:18:20 - INFO - __main__ - *** Evaluate ***
***** Running Evaluation *****
Num examples = 120
Batch size = 2
/usr/local/lib/python3.7/dist-packages/torch/_tensor.py:575: UserWarning: floor_divide is deprecated, and will be removed in a future version of pytorch. It currently rounds toward 0 (like the 'trunc' function NOT 'floor'). This results in incorrect rounding for negative values.
To keep the current behavior, use torch.div(a, b, rounding_mode='trunc'), or for actual floor division, use torch.div(a, b, rounding_mode='floor'). (Triggered internally at /pytorch/aten/src/ATen/native/BinaryOps.cpp:467.)
return torch.floor_divide(self, other)
100% 60/60 [01:37<00:00, 1.62s/it]
***** eval metrics *****
epoch = 10.0
eval_gen_len = 16.7333
eval_loss = 2.6638
eval_mem_cpu_alloc_delta = 2MB
eval_mem_cpu_peaked_delta = 0MB
eval_mem_gpu_alloc_delta = 0MB
eval_mem_gpu_peaked_delta = 1227MB
eval_rouge1 = 10.1667
eval_rouge2 = 6.3889
eval_rougeL = 10.2778
eval_rougeLsum = 10.5278
eval_runtime = 98.9901
eval_samples = 120
eval_samples_per_second = 1.212
CPU times: user 18 s, sys: 2.62 s, total: 20.7 s
Wall time: 35min 1s

35分ほどかかりました。

outputフォルダに学習結果となるモデルを表す複数ファイルが出力されています。

学習結果の確認

TensorBoardで学習結果を確認します。

[Google Colaboratory]

1
2
3
# 学習状況の確認
%load_ext tensorboard
%tensorboard --logdir runs

[実行結果]

損失(Loss)が0に収束・・・してはいないのですが、少しずづ減少し1.4以下になってはいるので、それなりに学習していることが分かります。

次回は、学習したモデルを使って要約を行います。

Transformers(14) - 要約②学習データと検証データの作成

前回ダウンロードしたニュース記事から学習データ検証データを作成します。

学習データ・検証データの作成

前回取得したニュース記事は、output.tsvに出力されています。

このファイルから、学習データ(8割)と検証データ(2割)を作成します。

[Google Colaboratory]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import os
import pandas as pd

# データフレームの作成
df = pd.DataFrame(columns=['text', 'summary'])
with open('output.tsv') as f:
for line in f.readlines():
strs = line.split('\t')
df = df.append({'text':strs[3] , 'summary':strs[0]}, ignore_index=True)

# シャッフル
df = df.sample(frac=1)

# CSVファイルの保存
num = len(df)
df[:int(num*0.8)].to_csv('train.csv', sep=',', index=False)
df[int(num*0.8):].to_csv('dev.csv', sep=',', index=False)

処理が成功すると、以下のファイルが出力されます。

  • train.csv
    学習データ
  • dev.csv
    検証データ

必要ライブラリのインストール

次回ファインチューニングを行う前準備として、必要なライブラリをインストールしておきます。

[Google Colaboratory]

1
2
3
4
5
# ソースからのHuggingface Transformersのインストール
!git clone https://github.com/huggingface/transformers -b v4.4.2
!pip install -e transformers
!pip install fugashi[unidic-lite]
!pip install ipadic

メニューから「ランタイム → ランタイムを再起動」を選択し、Google Colaboratoryを再起動しておきます。

さらに以下のライブラリをインストールします。

[Google Colaboratory]

1
2
3
4
5
6
# Huggingface Datasetsのインストール
!pip install datasets==1.2.1

# 依存パッケージのインストール
!pip install rouge_score==0.0.4
!pip install sentencepiece==0.1.91

以上で、ライブラリのインストールが完了しました。

次回は、準備した学習データと検証データを使ってファインチューニングを行います。

Transformers(13) - 要約①データセットの準備

要約を全4回に分けて説明していきます。

要約は、本文(長い文章)要約(短い文章)に変換する処理です。

「livedoorニュースの3行要約データセット」を使って、要約の処理を確認していきます。

ニュース記事の一覧を取得

まずはニュース記事の公開年月、カテゴリ、記事IDがまとまっているCSVファイルをダウンロードします。

ダウンロード後にファイル名を変更します。

[Google Colaboratory]

1
2
!wget https://raw.githubusercontent.com/KodairaTomonori/ThreeLineSummaryDataset/master/data/train.csv
!mv train.csv downloaded_train.csv

[実行結果]

1
2
3
4
5
6
7
8
9
10
--2021-10-06 08:20:12--  https://raw.githubusercontent.com/KodairaTomonori/ThreeLineSummaryDataset/master/data/train.csv
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.111.133, ...
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3836862 (3.7M) [text/plain]
Saving to: ‘train.csv’

train.csv 100%[===================>] 3.66M --.-KB/s in 0.07s

2021-10-06 08:20:12 (52.4 MB/s) - ‘train.csv’ saved [3836862/3836862]

ニュース記事を取得

ニュース記事の一覧(CSVファイル)を元に、ニュース記事をダウンロードします。

beautiful soupというスクレイピング用のライブラリを使って、ニュース記事の取得を行います。

(サーバに負荷がかからないように10秒間に1記事を取得するようにしています)

[Google Colaboratory]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
from urllib.request import urlopen
from bs4 import BeautifulSoup
from bs4.element import NavigableString
from pprint import pprint
import time

# 収集するニュース記事のインデックス
start_index = 0 # 開始インデックス
end_index = 1000 # 終了インデックス

# コンテンツの取得
def get_content(id):
# サーバに負荷をかけないように10秒スリープ
time.sleep(10)

# URL
URL = 'https://news.livedoor.com/article/detail/'+id+'/'
print(URL)
try:
with urlopen(URL) as res:
# 本文の抽出
output1 = ''
html = res.read().decode('euc_jp', 'ignore')
soup = BeautifulSoup(html, 'html.parser')
lineList = soup.select('.articleBody p')
for line in lineList:
if len(line.contents) > 0 and type(line.contents[0]) == NavigableString:
output1 += line.contents[0].strip()
if output1 == '': # 記事がない
return
output1 += '\n'

# 要約の抽出
output0 = ''
summaryList = soup.select('.summaryList li')
for summary in summaryList:
output0 += summary.contents[0].strip()+'\t'
if output0 == '': # 記事がない
return

# 出力
print(output0+output1)
with open('output.tsv', mode='a') as f:
f.writelines(output0+output1)
except Exception:
print('Exception')

# IDリストの生成の取得
idList = []
# with open('ThreeLineSummaryDataset/data/train.csv', mode='r') as f:
with open('downloaded_train.csv', mode='r') as f:
lines = f.readlines()
for line in lines:
id = line.strip().split(',')[3].split('.')[0]
idList.append(id)

# コンテンツの取得
for i in range(start_index, end_index):
print('index:', i)
get_content(idList[i])

[実行結果]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
index: 0
https://news.livedoor.com/article/detail/11097202/
岡むら屋から、期間限定の新メニュー「じゃが肉めし」が登場する 男爵いもなどは味噌ベースで煮こまれ、しっかり味が染み込んでいるとのこと 「岡むら屋特製肉じゃが」と言うべき一品に、仕上がっているという 新橋と秋葉原に店を構える「岡むら屋」。味噌ベースの独自の味つけで牛バラ肉を煮込んだ具材がたっぷり乗ったオリジナル丼『肉めし』で知られる店です。自分も新橋店で『肉めし』を食べたことがありますが、濃いめの味付けでトロットロに煮こまれた牛肉とホカホカご飯は最高の相性! 味の染み込んだ豆腐も絶品で、腹ぺこボーイズ&ガールズたちの胃袋を満たし続けている丼なのです。昨年開催された『第2回全国丼グランプリ』では、肉丼部門で金賞受賞を獲得しています。そんな「岡むら屋」に期間限定新メニューが登場。その名も『じゃが肉めし』!肉と芋――このまま名作文学のタイトルにもなりそうな、重厚かつ甘美な響き。これって食いしんぼうたちにとっては定番かつ夢の組み合わせではないでしょうか。この組み合わせではすでに「肉じゃが」という殿堂入りメニューがありますが、今回の『じゃが肉めし』は、“岡むら屋特製肉じゃが”と言うべき一品に仕上がっているそうです。北海道産の男爵いもとしらたきを合わせ、味噌ベースの大鍋で他の具材と一気に煮込むことで、しっかり味が染み込んでいるとのこと。商品写真が公開されていますが、ビジュアルを見ただけで、その染みこみ具合いは一目瞭然!丼というステージで繰り広げられる、肉×芋×白米というスーパースターの競演。肉好き必食の1杯と言えそうです。あ、定食も同時販売されるので、気分で選べるのもうれしいですね。詳しい販売期間などは、店舗にお問い合わせください。肉めし「岡むら屋」

index: 1
https://news.livedoor.com/article/detail/11104959/
東京駅周辺の安くて美味しい「蕎麦ランチ」の名店を紹介している 「越後そば 東京店」では、ミニかき揚げ丼セットがおすすめと筆者 その他には、「手打ちそば 石月」「酢重正之 楽」「鎌倉 一茶庵 丸山」など 名店がひしめく「丸の内・日本橋」エリアで<うまい蕎麦ランチ>が食べられるお店を厳選してご紹介。ぴあMOOK『うまい蕎麦の店 首都圏版』が選んだ、とっておきの7店がこちら!ミニかき揚げ丼セット(温冷) 660円関東風の濃いめのつゆと、ふのりを練り込んだ喉ごしの良い自家製のそばが相性抜群。新鮮な油を使ったかき揚げは、サクサク。千代田区丸の内1-9-1 東京駅一番街B1F蕎麦も天ぷらも正統派の味お蕎麦と天丼(二八) 1600円喉ごしや歯応えを楽しむ二八蕎麦のほか、蕎麦の風味を存分に味わえる十割蕎麦と天丼のセットも。天ぷらは鮮度抜群で美味。千代田区丸の内1-6-4 丸の内オアゾ5F信州の郷土料理をアレンジ“信州フランス鴨”セリかも南蛮(温) 1680円和食とフレンチが融合したスタイルの人気店。このメニューは、本格信州そば、信州のフランス鴨、契約農家が育てた野菜など、素材にこだわっている。千代田区丸の内2-7-2 JPタワーKITTE5F納豆と卵白でふんわり食感なっとうそば 1100円取り寄せた蕎麦の実を、職人が毎日石臼で挽き、丹念に手打ちする。たっぷりの納豆と卵白がのって、なめらかな口当たり。千代田区丸の内1-5-1 新丸の内ビルディング5Fやわらかな厚切り鴨肉を堪能鴨せいろ 1945円、さつま揚げ 650円合鴨・ネギ・しめじなどを合わせた濃厚なつけ汁に、程良いコシの蕎麦がよく合う。自家製さつま揚げもぜひ味わいたい一品。千代田区丸の内2-4-1 丸の内ビルディング6Fコシの強い独特な田舎蕎麦が美味とり辛そば(温) 980円信州軽井沢の味噌・醤油屋「酢重正之商店」が手掛ける蕎麦屋の人気メニュー。辛口のつけ汁と太い田舎蕎麦がよく合うと評判。千代田区丸の内1-5-1 新丸の内ビルディングB1F風味豊かな生わさびが決め手ざるそば(生わさび) 710円信州の民家を思わせる店内で打つ自家製麺は歯応え抜群。生わさびを自分でおろして味わう。甘めのつゆがわさびにぴったり。千代田区丸の内1-6-1 丸の内センタービル B1Fうまい蕎麦の店 首都圏版日本人ならいつでも蕎麦が食べたい!

(・・・・・途中略・・・・・)

index: 998
https://news.livedoor.com/article/detail/11024867/
厚生労働省は1日、2015年の人口動態統計の年間推計を公表した 2015年の推計出生数は100万8000人で前年と比べ4000人増加した 死亡数は戦後最多の130万2000人となっている ○主な死因1位はガンなどの悪性新生物2015年の出生数は100万8,000人で、前年と比べて4,000人増加した。死産数は2万3,000胎(前年比1,000胎減)となった。死亡数は130万2,000人で戦後最多。主な死因の推計死亡数は、ガンなどの悪性新生物が37万人、心筋梗塞などの心疾患が19万9,000人、肺炎が12万3,000人、脳卒中などの脳血管疾患が11万3,000人だった。婚姻件数は63万5,000組(前年比9,000組減)、離婚件数は22万5,000組(前年比3,000組増)だった。人口動態総覧を日本・韓国・シンガポール・アメリカ・フランス・ドイツ・イタリア・スウェーデン・イギリスの9カ国で比較したところ、1人の女性が一生に産む子供の平均数(合計特殊出生率)が最も多いのはフランス(1.99人/2013年)、次いでスウェーデン(1.89人/2013年)、アメリカ(1.86人/2014年推定値)だった。一方シンガポール(1.19人/2013年)、韓国(1.21人/2014年)、イタリア(1.39人/2013年)の3カ国はいずれも1.4人を下回った。なお日本は1.42人(2014年)だった。

index: 999
https://news.livedoor.com/article/detail/11060391/
16年、年始から下落した中国株式市場を香港メディアが検証している 中国株式市場は個人投資家が主体の市場であり、価格変動が大きいと指摘 変動制限のため導入したサーキットブレーカー制度も一因だと論じている 2016年の株式市場は世界的に波乱の幕開けだった。中国株式市場では4日と7日にそれぞれ上海総合指数が7%も下落し、株価の急変を防ぐために導入されたサーキットブレーカーが発動。中国政府は導入されたばかりのサーキットブレーカー制度の一時停止に追い込まれた。中国株の急落は世界の株式市場に波及し、中国発の世界同時株安が起きたが、そもそも上海総合指数はなぜ年初から急落したのだろうか。香港メディアの鳳凰網は10日、中国の株式市場は閉鎖的であり、外国人投資家の関与が制限されていることを指摘したうえで、投資家に株式を投げ売りさせた要因について考察した。記事はまず、さらに、中国株式市場は個人投資家が主体の市場であることを指摘したうえで、だからこそ価格変動が大きいと指摘。さらに2015年夏にも上海総合指数が急落したことを指摘し、「現在、市場で取引をしているのは前回の急落を脳裏に焼き付けつつ、今なお怯える個人投資家たちだ」と伝え、だからこそ中国証券監督管理委員会は値幅変動を制限するためにサーキットブレーカーを導入したのだと論じた。一方で記事は、上海総合指数はサーキットブレーカーの導入によって7%下落すると取引が停止されることになっていたため、株価が下落すると個人投資家たちが取引停止を恐れて我先にと売り始めたと指摘。サーキットブレーカーの存在がむしろ価格変動を大きくしてしまったと論じた。

以上で、ニュース記事のダウンロードが完了しました。

output.tsvというファイルにニュース記事が出力されています。


次回は、ダウンロードしたニュース記事を学習データ検証データに分けます。

Transformers(12) - 質疑応答③学習したモデルを使って質疑応答

前回は、わかち書きとファインチューニングを行いました。

今回は、学習したモデルを使って質疑応答を行います。

学習済みモデルを使って質疑応答

学習したモデルを使って質疑応答を行ってみます。

8行目のfrom_pretrained関数で、学習済みモデルをロードしています。

11行目でコンテキストを設定し、12行目で質問を指定しています。

[Google Colaboratory]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import torch
from transformers import BertJapaneseTokenizer, AutoModelForQuestionAnswering
import MeCab
wakati = MeCab.Tagger("-Owakati")

# トークナイザーとモデルの準備
tokenizer = BertJapaneseTokenizer.from_pretrained('cl-tohoku/bert-base-japanese-whole-word-masking')
model = AutoModelForQuestionAnswering.from_pretrained('output/')

# コンテキストと質問
context = wakati.parse('土曜日に友達と表参道に遊びに行きました。').strip()
question = wakati.parse('どこに遊びに行ったの?').strip()
print(wakati.parse('土曜日に友達と表参道に遊びに行きました。'), wakati.parse('どこに遊びに行ったの?'))

# テキストをテンソルに変換
inputs = tokenizer.encode_plus(question, context, return_tensors='pt')

# 入力のトークンIDの配列の取得
input_ids = inputs['input_ids'].tolist()[0]

# 推論
model.eval()
with torch.no_grad():
output = model(**inputs)
answer_start = torch.argmax(output.start_logits)
answer_end = torch.argmax(output.end_logits) + 1
answer = tokenizer.convert_tokens_to_string(tokenizer.convert_ids_to_tokens(input_ids[answer_start:answer_end]))
print(answer)

回答結果は以下の通りです。

[実行結果]

1
2
3
4
土曜 日 に 友達 と 表 参道 に 遊び に 行き まし た 。 
どこ に 遊び に 行っ た の ?

表 参道

応答は「表 参道」と的確な回答になっています。


次に、コンテキストはそのままで質問の内容を変えてみます。

[Google Colaboratory]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import torch
from transformers import BertJapaneseTokenizer, AutoModelForQuestionAnswering
import MeCab
wakati = MeCab.Tagger("-Owakati")

# トークナイザーとモデルの準備
tokenizer = BertJapaneseTokenizer.from_pretrained('cl-tohoku/bert-base-japanese-whole-word-masking')
model = AutoModelForQuestionAnswering.from_pretrained('output/')

# コンテキストと質問
context = wakati.parse('土曜日に友達と表参道に遊びに行きました。').strip()
question = wakati.parse('いつ遊びに行ったの?').strip()
print(wakati.parse('土曜日に友達と表参道に遊びに行きました。'), wakati.parse('いつ遊びに行ったの?'))

# テキストをテンソルに変換
inputs = tokenizer.encode_plus(question, context, return_tensors='pt')

# 入力のトークンIDの配列の取得
input_ids = inputs['input_ids'].tolist()[0]

# 推論
model.eval()
with torch.no_grad():
output = model(**inputs)
answer_start = torch.argmax(output.start_logits)
answer_end = torch.argmax(output.end_logits) + 1
answer = tokenizer.convert_tokens_to_string(tokenizer.convert_ids_to_tokens(input_ids[answer_start:answer_end]))
print(answer)

回答結果は以下の通りです。

[実行結果]

1
2
3
4
土曜 日 に 友達 と 表 参道 に 遊び に 行き まし た 。 
いつ 遊び に 行っ た の ?

土曜 日

応答は「土曜 日」と、こちらも的確な回答になっています。

前回のファインチューニングは2時間以上とかなり時間がかかりましたが、一度学習を完了してしまえば質問に対して的確な応答を得られるようになるのでかなり実用的だと感じました。

Transformers(11) - 質疑応答②わかち書き/ファインチューニング

前回は、質疑応答のためのデータセットの準備と必要なライブラリのインストールを行いました。

今回は、わかち書きファインチューニングを行います。

わかち書き

日本語はわかち書きに変換すると精度が上がります。

下記のコードでわかち書きを行います。

[Google Colaboratory]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import json
import MeCab
wakati = MeCab.Tagger("-Owakati")

# paragraphのわかち書き
def wakatiParagraph(dic):
context = None
for k, v in dic.items():
if k == 'context':
dic[k] = wakati.parse(v).strip()
context = dic[k]

for k, v in dic.items():
if k == 'qas':
for qa in v:
if not wakatiQa(qa, context):
print('Warning Remove QA:', context)
v.remove(qa)

# qaのわかち書き
def wakatiQa(dic, context):
for k, v in dic.items():
if k == 'question':
dic[k] = wakati.parse(v).strip()
elif k == 'answers':
for answer in v:
answer['text'] = wakati.parse(answer['text']).strip()
answer['answer_start'] = context.find(answer['text'])
if answer['answer_start'] < 0:
print('Warning Remove Text: ', answer['text'])
v.remove(answer)
if len(v) == 0:
return False
return True

# ファイルのわかち書き
def wakatiFile(in_file, out_file):
data = None
with open(in_file, 'r') as f:
data = json.load(f)
paragraphs = data['data'][0]['paragraphs']
for paragraph in paragraphs:
wakatiParagraph(paragraph)

with open(out_file, 'w') as f:
json.dump(data, f, indent=2, ensure_ascii=False)

# ファイルのわかち書きの実行
wakatiFile('./DDQA-1.0/RC-QA/DDQA-1.0_RC-QA_train.json', 'wakati_DDQA-1.0_RC-QA_train.json')
wakatiFile('./DDQA-1.0/RC-QA/DDQA-1.0_RC-QA_dev.json', 'wakati_DDQA-1.0_RC-QA_dev.json')

実行結果は以下の通りです。

[実行結果]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
Warning Remove Text:  冬 期間
Warning Remove QA: と ばかり に 、 DJEBEL を 走ら せ 、 国道 361 号 の 旧道 で 地蔵 峠 を 登っ て いく 。 地蔵 峠 は 御岳 山 を 眺める の に は 、 絶好 の 展望 台 に なっ て いる 。 だ が 峠道 は 冬期 間 は 閉鎖 。 バイク なら ば 走れる の で は ない か と 峠道 を のぼっ て いく と 、 ツルツル 滑る アイスバーン に なり 、 深い 雪道 に なり 、 たてつづけ に 転倒 。
Warning Remove Text: ローディ ー
Warning Remove Text: 米 島口
Warning Remove Text: 米 島口
Warning Remove QA: 本丸 会館 前 間 の 途中 の ところ で 行き違い が 出来る よう に なっ て いる 。 広小路 から 、 複線 と なる 。 道路 の 真ん中 を 、 軽快 に 走る 。 しばらく 走っ て 、 米 島 口 に 到着 する 。
Warning Remove Text: スー パーカ
Warning Remove Text: 三島
Warning Remove QA: 県道 18 号 線 を 下り だし て 修善寺 に 近付く に つれ 、 路面 は 段々 と ウェット 状態 に 。 暑く て も レイン ウェア を 脱が なく て 正解 だっ た 。 修善寺 IC から 修善寺 道路 を 三 島 へ 向かっ て 北上 。 料金 を 払う の が どう も 面倒 くさい 。
Warning Remove Text: 暖機 音
Warning Remove QA: いずれ この 音 に 満足 いか なく なっ たり する の か な 。 朝 早く 暖 機音 が 気 に なる の で 、 アクセル を 開け ず そろそろ と 発進 。 岐れ 路 で 剣道 と ぶつかっ て から ちゃんと 開け て 走る 。 八幡 宮前 を 左折 し て 一路 海 へ 。
Warning Remove Text: 40 分位
Warning Remove QA: 前 に も 後ろ に も 、 対向 車 も い ない 。 それ で も 、 何 と か 家 に 帰ら ない と 、 と 一生 懸命 走っ た らしい 。 その 内 に 気 が つく と 、 いつ も の 道 に 出 て い た 、 と 言う 。 だいたい 、 40 分 位 迷っ て い た らしい ん だ けれど 。 。 。
Warning Remove Text: おまわり さん
Warning Remove QA: こんな の が ごろごろ いる よ 。 自分 の 事 だけ じゃ なく 、 対向 車 や 後続 車 、 歩行 者 や 自転 車 まで 、 自分 の 周り の 全て の 状況 に 心配 れ ない 人 は 、 免許 取り消し 処分 に なっ て も 仕方ない ん じゃ ない の ? ? そんな 奴 に 限っ て お まわり さん に 縁 が 無かっ たり する ん だ よ ね ! ! エコ と か セコ と か 勝手 に すれ ば よい けど 、 状況 を わきまえ て ください 。
Warning Remove Text: デレ ー ラー
Warning Remove QA: 宿 に 着い て 指示 さ れ た 場所 に 自転 車 を 置い て ? ? その まま に し て おけ ば 良い の に 、 変速 用 の ワイヤー が ピーン と 張っ て いる の が 眼 に 入っ て ( 張っ て いる の が 普通 の 状態 で 、 何 も わるく ない ん です よ ) 貧乏 性 な もの です から カチカチ と ワイヤー を 緩め て しまい まし た 。 つまり 1 と 同じ 状況 です 、 チェーン が 廻っ て い ない 状態 で 変速 する と 不 完全 な 変速 状態 ( ロック 状態 ) に なっ て しまい ます 。 で 、 翌朝 そこ に 気 が つか ず に 、 その まま 乗っ て こぎ出し 大きな 負荷 が かかり 、 今度 は デレーラー が 曲がっ て しまっ た ? ? と 言う わけ です 。 ひどく 曲がっ て い まし た 、 軽い 曲がり なら 腕力 で も 直せ ます が ? ? ? 、 考え まし た 。
Warning Remove Text: アクセル と ブレーキ ー
Warning Remove QA: の で フト 見 て み たら 、 お 店 の 駐車 場 の フェンス を 倒し 、 その ちょうど 正面 に ある ビル の 1 階 に 、 1 台 の 。 ワン ボックス カー が 突っ込ん で い た … フェンス を なぎ倒し 、 壁 を 壊し 、 すっぽり と はまっ て い た 。 よく ある アクセル と ブレ ー キー を 踏み 間違え た って 事故 の 。
Warning Remove Text: ア イザイア
Warning Remove QA: 後 を 追う パトカー に 乗っ て いる の は 先ほど ジェニー が 急 発進 し た 時 に 止め た 警官 の アイザイア だっ た 。 「 今 じゃ 私 を 信じ て くれる わ ね 。 」 と 言う ジェニー に ようやく 納得 の アイザイア 。 その 時 、 後部 座席 で 駄洒落 を ふりまい て い た デクスター に 突如 名案 が 浮かん だ よう だ 。 身軽 に 前 に 乗り移る と 車 の 下 に もぐりこみ 配線 接続 を あれこれ 試し て み た 。
Warning Remove Text: 警官 の ア イザイア
Warning Remove Text: ア イザイア
Warning Remove QA: 後 を 追う パトカー に 乗っ て いる の は 先ほど ジェニー が 急 発進 し た 時 に 止め た 警官 の アイザイア だっ た 。 「 今 じゃ 私 を 信じ て くれる わ ね 。 」 と 言う ジェニー に ようやく 納得 の アイザイア 。 その 時 、 後部 座席 で 駄洒落 を ふりまい て い た デクスター に 突如 名案 が 浮かん だ よう だ 。 身軽 に 前 に 乗り移る と 車 の 下 に もぐりこみ 配線 接続 を あれこれ 試し て み た 。
Warning Remove Text: 15 分位
Warning Remove Text: 八幡平
Warning Remove QA: も 出 てる だろう し 時間 が かかる に 違い ない … 。 ここ で 時間 を ロス し て しまう と この 後 の 予定 が 詰まっ て しまう と 考え て 、 残念 ながら 。 八幡 平 を あきらめ て その まま 高速 を 走っ て 次 の 目的 地 を 目指す こと に し まし た 。 安代 Jct を 過ぎ て 八戸 道 へ 入り 走っ て いく と 、 青森 へ 入り まし た 。
Warning Remove Text: 八幡平
Warning Remove QA: と 思い ながら 、 とりあえず 八幡 平 を 目指し て 走り まし た 。 国道 103 号 から 国道 282 へ 入り まし た が 、 雨 は 止む 様子 も なく … 。 そして 東北 の 国道 は あまり 交通 量 も 多く ない し 、 ひたすら 走る ? って ところ が 多い ん です よ ね 。 4 日 走っ て い ます が 、 距離 も 長い し 雨 の 音 しか し ない し 、 疲れ も ある ため か スピード も 出せ ない の で ボーっと 走っ て いる と つい ウトウト し ちゃう こと が 何 度 か あり まし た (^_^;)
Warning Remove Text: 川 沿い
Warning Remove QA: 思っ た 通り 、 一 往復 する 間 に 、 すいすい 乗れる よう に 。 と いっ て も 、 「 滑らか な 道 なら OK 」 と いう 条件 つき です し 、 乗る こと で 精 一杯 です から 、 自転 車 で どこ か へ 出かける の は まだまだ 危ない です が 。 これ まで の 感じ だ と 、 こう いっ た 、 「 成長 と とも に 、 あまり 苦労 なく できる よう に なる こと 」 に つい て は 、 早め に 練習 する より は 、 ある 程度 大きく なっ て から やっ て み た 方 が 、 スンナリ できる よう に なる こと が 多かっ た の です が 、 自転 車 も やっぱり その パターン だっ た よう です 。 川沿い を 往復 し て 、 少々 疲れ て 、 自転 車 を 押し て 家 まで 帰る 途中 。
Warning Remove Text: 40 00 回転
Warning Remove Text: うー ー ん 、 、 奴 ら 、 死に たい の か と ?
Warning Remove Text: と よ じ さ ん ち
Warning Remove QA: 進め られ て い まし た 。 する と 向う から 、 またまた やっ て 来 まし た ? また 横 を サーッ と 通り抜け て 、 スタコラ サッサと 坂 を 下り て ゆき まし た 。 この 道 は いつ も の 散歩 道 に 通じ て おり 、 と よ じ さん ち に 行く 近道 ・ ・ ・
Warning Remove Text: ア ミ ティ
Warning Remove QA: そして おの や ん 家 一同 は アミ ティ に 乗っ て 我が家 に 向かう 。 走り 出し た 瞬間 、 オートマ に すれ ば よかっ た か な ? と 少し 後悔 を 感じる 。 その 後悔 を 振り払い ながら 車 を 進める 。 前 を 見 て 運転 し て いる だけ で は 、 ロング ハイ ルーフ の ハイ エース と 雰囲気 は 変わら ない 。
Warning Remove Text: ティピ ー
Warning Remove QA: 「 ティ ピー の 前 で 写真 を 撮る から 集まれ ? ! 」 皆 が 外 に 出 た とき は 、 結構 な 降り に なっ て い た が 、 家族 全員 が 、 ランドティピー の 前 で 写真 を 撮る こと が 最後 だ と 感じ て いる の で 、 誰 も 文句 を 言わ ず に 外 へ 出 た 。 三脚 を ランドティピー の 前 に 立て て 、 セルフ タイマー を セット する 。 「 みんな ? 、 あの カメラ の 真ん中 を 見 て ね と ? 」 言い ながら 自分 も 車 に 駆け寄る 。
Warning Remove Text: お 祖母 ちゃん が どう し て この 坂 の 上 に お 墓 を 建て た か
Warning Remove Text: ネズミ 捕
Warning Remove Text: 右前
Warning Remove QA: 雪 が 降っ て い て 視界 が 悪かっ た の も 影響 し た 。 両車 とも 手前 で スピード を 緩め て いる の で それ 程 衝撃 も なく 、 ぶつかっ た ところ も 右 前 で 自分 の 近く で 良かっ た 。 誰 も 怪我 も なく 人身 事故 で は なく 物損 事故 と なっ た 。 向こう の 人 は 特に 怒っ た そぶり も なく 淡々 と 事故 後 の 手続き を 踏ん で い た 。
Warning Remove Text: 左折 に あたる から 左 合図
Warning Remove Text: 走っ たり と まっ た
Warning Remove Text: 50 00 回転
Warning Remove Text: 白い L クサ ス
Warning Remove QA: 昨日 は いつ も より 早く 家 を 出 まし た から 道 は まだ 空い て い て 。 で も 信号 の 間隔 は 同じ です から できる だけ 止まら ない よう に 。 かつ 安全 スピ ? ド で 走っ て ます と 後ろ から 白い L クサス が 迫っ て き て 。 ピタっ と 真後ろ に つい た 片側 2 車線 です から 抜い て いけ ば いい ん だ けど 。
Warning Remove Text: うっちゃん
Warning Remove QA: 何 時 に 行こう か と 悩ん でる うち に 夜中 に なっ て しまい まし た 。 Chiffon は いつ も 私 の 膝 の 上 に 来 ます 。 私 が 運転 席 で 、 助手 席 に うっ ちゃん が い て も 来る の で 。 安全 を 考え て いつ も 寝 て いる Chiffon の ベッド を 持っ て いく 事 に し まし た 。
Warning Remove Text: 思いのほか よい 燃費
Warning Remove Text: え れ み
Warning Remove Text: マ アーン
Warning Remove Text: ガー ミン
Warning Remove QA: 後 は 、 何 と か 登り はじめ 前 に 自販 機 か なん か で 給水 できれ ば なん と か なる な 。 確認 し て おい た とおり に 右折 。 後 は 道 なり に 進ん で 、 ガーミン 頼っ て いけ ば 間違わ ない はず 。 住宅 地 を 抜ける と だんだん 上り坂 に 。
Warning Remove Text: ちゃんと 大型 車 の 運転
Warning Remove Text: アンキ モ
Warning Remove QA: 大洗 港 近く の 「 潮騒 の 湯 」 ( 入浴 料 1000 円 10 時 ? 21 時 ) に 入り 、 湯 から 上がる と 「 あんこう 鍋 うどん 」 ( 900 円 ) を 食べ た 。 アン キモ が 上 に のっ て いる 。 アンコウ を 先 に 食べ 、 その あと で 味 の しみ込ん だ うどん を 食べ た 。 それ を 最後 に R 51 から 水戸 大洗 IC で 東 水戸 道路 に 入り 、 常磐 道 で 東京 に 戻っ た 。
Warning Remove Text: わんこ の 好き な おもちゃ
Warning Remove Text: ユ ロン 峠
Warning Remove Text: ラチ ェ
Warning Remove Text: あ ん こう 鍋 うどん
Warning Remove QA: 大洗 港 近く の 「 潮騒 の 湯 」 ( 入浴 料 1000 円 10 時 ? 21 時 ) に 入り 、 湯 から 上がる と 「 あんこう 鍋 うどん 」 ( 900 円 ) を 食べ た 。 アン キモ が 上 に のっ て いる 。 アンコウ を 先 に 食べ 、 その あと で 味 の しみ込ん だ うどん を 食べ た 。 それ を 最後 に R 51 から 水戸 大洗 IC で 東 水戸 道路 に 入り 、 常磐 道 で 東京 に 戻っ た 。
Warning Remove Text: 川上 牧 丘
Warning Remove Text: 上 浦幌 の パーキング エリア
Warning Remove Text: 上 浦幌 の パーキング エリア
Warning Remove Text: 市 内
Warning Remove QA: これ は 今 まで と は ちょっと 違う と 思い つつ も 、 少し 遠出 を し た が その 時 は 大丈夫 だっ た 。 一旦 帰宅 し て 、 用事 を 済ま せる ため に 市内 を 走っ て いる とき だっ た 。 右折 中 に 突然 ボキッ と いう よう な 音 と 、 ガラガラ ガタガタ と いう 大きな 音 と 衝撃 が 走っ た 。 ブレーキ を 踏ん で も 、 ス ? っと 手応え が ない 感じ で 効い て い ない よう だ 。
Warning Remove Text: 男子 予備 校生
Warning Remove Text: 男子 予備 校生
Warning Remove Text: アニキ ィ
Warning Remove QA: そんな アニ キィ は わんこ 先生 仕込み の ヤクザ 運転 で 、 ブイ ブイ 言わし ながら 走る けど 、 高速 は 怖く て 乗ら ない らしい 。 あん だけ 運転 出来 たら 怖い モノ は 無い と 思う の だ けど 不思議 。 しかも 運転 が 好き じゃ ない と か 。 助手 席 に 乗っ てる 方 が 良い と 、 センス の 無い 私 の 運転 で も 助手 席 に 座る 。
Warning Remove Text: 伏 石町
Warning Remove QA: かなり 雪道 を 走っ た 割 に は 良い 数字 が 出 まし た 。 給油 後 、 伏 石 町 に ある コイン 洗車 に 行っ て 洗車 、 ワックス がけ を し て から 、 住居 に は 午前 11 時 45 分 に 到着 し まし た 。 前 の バンパー に は 、 凍っ た 雪 が ぶつかっ て つい た 傷 が 多数 あり まし た 。 車体 側面 に も 一部 に 傷 が 見つかっ た の で 、 先ほど 、 ドンキホーテ に 行っ て 。
Warning Remove Text: みっ き ぃ ママ
Warning Remove QA: 既に 日 は 落ち て しまい 、 明るい 時間 帯 に 走り たかっ た な ? と 思っ たり し た 。 車 を 停め て 散歩 し たかっ た な ? と か 。 で 、 その 頃 助手 席 のみ っ き ぃ ママ は と いう と ・ ・ ・ 、 「 おえ ? 」 の 連発 で うるさかっ たり し たり し て ・ ・ ・
Warning Remove Text: キン ヘッド の お 兄 さん
Warning Remove Text: ザザ ザザ ザザッ
Warning Remove Text: タウン ビー
Warning Remove Text: 三 輪 車
Warning Remove QA: あの 頃 、 私 たち は 交通 事故 ごっこ を よく し て い た 。 私 が 地面 に 横たわり 、 * * ちゃん が 、 三輪 車 に 乗っ て 私 を 轢い た 。 それ は 子供 だけ の 秘密 めい た 遊び で 、 私 と * * ちゃん は 共犯 者 の よう な 関係 だっ た 。 大人 に 見つから ない よう な 場所 で 遊ん で い た もの の 、 ある とき 、 近所 の 口うるさい おば さん に 見つかっ た 。
Warning Remove Text: バ カナディアン の 運転 マナー
Warning Remove Text: オオ ホリ
Warning Remove QA: 途中 、 右 カーブ を 曲がり 切れ ず 、 ミニ 四駆 みたい に 壁 づたい に 走る 車 。 左 の ドア と 壁 と の 摩擦 で 、 なぜ か 左腕 を 大やけど する 助手 席 オオホリ 。 さらに 加速 を 続ける こと 10 分 あまり か 。 ついに あきらめ 、 車 を 止めよう と する ゴト ー 。
Warning Remove Text: マ ルラ
Warning Remove QA: だ が 、 洪水 と 泥土 に すっかり 慣れ た メンバー 全員 は 、 「 目指せ ! エアーズ ロック 」 を 合言葉 に 「 ウーダナダッタトラック 」 も 走り きり 、 スチュワート ハイウエイ の マルラ に 着い た 。 ここ まで 来れ ば 、 あと は もう 舗装 路 のみ 。 マルラ で は キャラバン パーク で キャンプ し た が 、 その 夜 は 大きな 難関 を 突破 し た 喜び を 爆発 さ せ 、 焚き火 を 囲ん で の 大 宴会 に なる 。
Warning Remove Text: オト ン
Warning Remove QA: その 前 に 良い 相手 を 見つけ ね ば なら ん が 、 現実 的 に 厳しい だろう な … 。 食事 が 終わる なり オトン は 去っ た 。 結局 奴 と 一言 も 話す こと は なけれ ば 、 一 度 も 目 を 合わす こと は なかっ た 。 全く 知ら なかっ た の だ が 、 奴 は 広島 で 単身 赴任 し て い たり 、 弟 に 車 を 貸し て い たり 、 今朝 広島 から やっ て き て その まま 広島 に 帰っ た と か 。
Warning Remove Text: 真っ暗 な 中立
Warning Remove Text: イ ク ミ
Warning Remove QA: 「 おめぇ ら 、 仲 良い ん だ な 。 ダチ って の は 大切 に し なきゃ な 」 この 運転 手 さん が 言っ た 言葉 も イク ミ の 予想 通り だ 。 前 に この 運転 手 さん の 事 を 話し たら 、 もし その 人 が 不良 だっ たら 友達 と か 仲間 を 凄い 大事 に する 人 か も ね 、 って 言っ て た 。 ラジオ で 非行 問題 の 事 を 放送 し て い て 、 そう いう 人 達 は 敵対 関係 に ある 人間 に は 凄い 怖い けど 、 結束 力 は 凄い って 言っ て た の を 覚え て い た らしい 。
Warning Remove Text: スタットレス ト
Warning Remove QA: うち に 近ずく に つれ 激しく なっ て き た 。 いくら スタットレスト は いえ スピード を 出す の は やばい ! な の で 40 キロ 走行 21 時 過ぎ だっ たろう か ・ ・ ・ そして 、 うち の 方 へ 曲がっ て 少し 走っ て い たら 、 「 ドカーン ! ! 」 と 音 が し た 。
Warning Remove Text: 一 礼
Warning Remove QA: 向こう も 分かっ て 嬉しかっ た らしい 。 お 互い 笑顔 で 確認 も ほどほど に 、 一礼 を し て 自分 は 去っ た 。 ちょうど 自分 の 買い物 に 行く スーパー の 方向 と 途中 まで 一緒 だっ た の で 、 歩き 始め た 後 も 、 後ろ から 来る で あろう ワゴン 車 が 気 に なっ て は い た 。 案の定 少し 遅れ て 来 た ニトリ の ワゴン 車 が 自分 の 脇 を 抜け て 前 へ 行く 。
Warning Remove Text: 一 礼
Warning Remove Text: かな っぺ
Warning Remove QA: もえ も え の トキ も 同じ よう な 授業 を 参観 し た コト が ある の で 、 アレ 、 また コレ かぁ ? ( 笑 ) って カンジ (* ̄m ̄) ププッ 。 ひとりひとり 、 先生 に 当て られ た 順 に 前 に 出 て 、 自分 の 名前 と 誕生 日 ・ 2 年 生 に なっ て がんばる こと を 発表 し た 後 、 黒板 に 貼っ て ある 表 の 誕生 月 の 欄 に 自分 の カード を 貼り付け て いき ます 。 20 分間 しか 参観 できる 時間 が ない モノ で ( もえ も え の クラス に まわら なきゃ いけ ない 関係 上 ) 、 な っぽ の いる 間 に かなっ ぺ の 番 が まわっ て くる か 気 に なっ た ン だ けど 、 運 よく 早い うち に かなっ ぺ は 当て られ 、 前 に 出 て 発表 を し て い まし た 。
Warning Remove Text: 何 か 変 な もの ふん だ
Warning Remove Text: ト ダ
Warning Remove QA: わかる わかる 。 こっ から だ と 5 分 くらい で 行ける って 。 じゃ 、 すぐ 行く わ 。 トダ は テキパキ 答え 、 すぐ に 通話 を 切る 。 ナカ ヤン は 仕事 の 内容 など を 伝え て おき たかっ た の だ が 、 それ は 合流 し て から で も いい だろう 、 と 思い直す 。 ふと 見る と 、 少年 達 は いつ の ま に か サッカー を やめ て 、 キャッチ ボール に 移行 し て い た 。
Warning Remove Text: くろと わ さん
Warning Remove QA: なるほど 、 道沿い に 二 軒 おき 位 に 寺 が 延々 と 続い て いる 。 これ って 下 世話 な 話 、 商売 に なる の か な ? ? 1 時間 ほど 散策 し 、 ホテル に 戻っ た 。 前日 の 約束 通り 、 9 時 半 に 駐車 場 で くろ とわ さん と 落ち合う 。
Warning Remove Text: トン ネ
Warning Remove Text: とみ や ま 村
Warning Remove Text: とみ や ま 村
Warning Remove Text: 名栗 川 沿い
Warning Remove Text: ま たがる
Warning Remove QA: さっそく またがる 。 やっぱ デケ え し 重い 300 kg を 余裕 で 超し て いる の を 今 に なっ て 思い 。 出す 。 店 の 人 に 通行 を 確認 し て もらい ながら 車 の 切れ目 を ぬっ て いざ 路上 へ 。
Warning Remove Text: ブリス コーティング
Warning Remove Text: 香川 県 内
Warning Remove QA: 利用 し た 大坂 峠 ( 実 は 有名 な 心霊 スポット 出 そう な ) の 入り口 付近 まで 走っ て き まし た 。 教習 所 を 卒業 し て 以来 の 運転 です が … 。 うん 、 やはり 慣れ て い ない 乗り物 を 運転 する の は 怖い です ね ( ´ = ω = ) と いう か 正確 に は 香川 県内 を 走る 事 が 怖い … 。
Warning Remove Text: サイコ ン
Warning Remove QA: 進ん で いる と なん だ か 南 に 進ん で いる 様 な 感じ に なっ て き まし た 。 サイコン の 表示 で 確認 し まし た が ” S ” と 表示 さ れ て い まし た 。 行き先 の 看板 も 大阪 に 行く 途中 に 名阪 国道 で 見 た 地名 が 出 て き まし た 。 「 この まま だ と 名阪 国道 に 合流 し て しまう なぁ と ・ ・ ・ 」 少し 考え まし た が 、 まず は 進む こと が 重要 と 判断 し て その まま 道 なり に 進み ます 。
Warning Remove Text: 町内
Warning Remove QA: 道路 の 左側 も 住宅 で 、 生垣 や フェンス 、 ブロック 塀 に 囲ま れ て いる 。 こちら も ひっそり と 静まり返り 、 真っ暗 だ 。 どう なっ て ん だ ・ ・ ・ 町 内 で 旅行 に で も 出かけ てる の か ?
Warning Remove Text: ポ ミ オ
Warning Remove Text: ポ ミ オ
Warning Remove Text: ポ ミ オ
Warning Remove Text: 湖畔 の 公園 内 の 食堂
Warning Remove Text: カ マ ウ
Warning Remove QA: もし か し て と 思い 、 「 Burst ? 」 と 聞く と 、 「 Yes 」 と の 答え で 、 車 を 脇 に 停める 。 カマウ が 車 を 降りる と 、 その 辺 から どこ から と も なく 人 が 集まっ て くる 。 中 に 、 明らか に 車 の 修理 慣れ し た 男性 が い て 、 彼 が タイヤ 交換 を ほぼ やっ て くれ た 。 その 間 、 車 の メーター を 盗み見る と 、 何 と 24 万 km 超え !
Warning Remove Text: ゲロ リン
Warning Remove Text: ゲロ リン
Warning Remove Text: ロントバンパー が 割れ た 程度
Warning Remove Text: BE NZ
Warning Remove QA: 今週 、 近所 の 方 に 頼ま れ て 、 BENZ を ちょっと 診 て い ます 。 W 210 の E 320 です が 、 丸目 4 灯 の E クラス も さすが に 10 年 以上 経ち ます から 古 臭 さ は 否め ませ ん 。 で も 腐っ て も やっぱり BENZ 、 走り は 良い です ね 。 走行 時 の 静穏 性 や クイック で しなやか な 足回り 等 、 高速 テスト を し て も 申し分 あり ませ ん 。
Warning Remove Text: BE NZ
Warning Remove QA: 今週 、 近所 の 方 に 頼ま れ て 、 BENZ を ちょっと 診 て い ます 。 W 210 の E 320 です が 、 丸目 4 灯 の E クラス も さすが に 10 年 以上 経ち ます から 古 臭 さ は 否め ませ ん 。 で も 腐っ て も やっぱり BENZ 、 走り は 良い です ね 。 走行 時 の 静穏 性 や クイック で しなやか な 足回り 等 、 高速 テスト を し て も 申し分 あり ませ ん 。
Warning Remove Text: ジャック ラッセル テリア
Warning Remove QA: 「 道 に ジャック ラッセル が 、 一人 で いる から ピックアップ し て あげ て ! 」 この ジャック ラッセル 、 近所 の 家の子 だ と 知っ て いる ん です ね 。 と いう の は 、 この 家 の 庭 を 囲ん で いる 柵 、 かなり 背 が 低い もの で 、 私 は 、 いつ も この 家 の 前 を 通る たび に 、 この 低い 柵 じゃ 、 ジャック ラッセル なら 簡単 に 飛び越え ちゃう よ な 、 飼い主 さん 、 ジャック ラッセル は 、 すっごい ジャンプ できる って 知ら ない の か な ? って 思っ て い た ん です 。 と いう こと で 、 外 に 出 て みる と 、 ちょうど 家 の 周り の 道 を うろうろ し て い た の で 、 捕まえよう と し た の です が 、 ジャックラッセルテリア 、 すっごく やん ちゃ !
Warning Remove Text: ジャック ラッセル テリア
Warning Remove Text: くろと わ さん
Warning Remove QA: なるほど 、 道沿い に 二 軒 おき 位 に 寺 が 延々 と 続い て いる 。 これ って 下 世話 な 話 、 商売 に なる の か な ? ? 1 時間 ほど 散策 し 、 ホテル に 戻っ た 。 前日 の 約束 通り 、 9 時 半 に 駐車 場 で くろ とわ さん と 落ち合う 。
Warning Remove Text: デバ ガメ
Warning Remove Text: デ コッパ チ
Warning Remove QA: そして ら デコ ッ パチ は 、 僕 の 後ろ に 入っ た 。 そして 車間 を つめ た まま 走っ て くる 。 この デコッパチ 、 前 に 3 人 座れる の で 、 女の子 を 真ん中 に おやじ が 運転 し て おく さん が 助手 席 。 家族 で 乗っ てる なら 、 もう ちょっと 安全 を 考え た 運転 を する べき 。
Warning Remove Text: で き の 悪い 子供 ほど かわいい と 言う が 、 こと 車 に 関し て は 腹 しか 立た ない な 。
Warning Remove Text: 祥雲 寺 前
Warning Remove QA: 「 どっ から 来 た の ? 」 「 東京 です 」 「 日本 一 周 ? 」 いきなり 来 た … 。 そう いう 人 しか 来 ない 場所 な ん だろう か 。 バス 停 「 祥雲 寺前 」 で 折れ て 、 猿岩 方面 へ 。 こっち の 道 も 、 細い 道 で 登り下り し て 行く 。
Warning Remove Text: アップ ダウン コース
Warning Remove QA: 作業 中 の 。 自転 車 屋 さん は TL ? FC 33 じゃ ない 奴 を 首振り の ソケット レンチ で 使っ て まし た 。 あれ は 何 を 使っ て た の か な ? ? ? 増し 締め 後 に 15 km アップダウンコース を 走っ て み たら 異音 が し ませ ん でし た 。
Warning Remove Text: カ ラオ カン
Warning Remove QA: しかし 何処 の 国 に 行っ て も バイク 屋 や 用品 屋 が 立ち並ぶ エリア を 見 て 歩く の は 楽しい 。 思っ た より も 長 時間 カラオカン に 滞在 し た 。 夕方 の 渋滞 が 始まる 前 に 高速 に 乗る 為 に 移動 を 開始 。 少し 混み 始め て い た が 、 そこ は バイク 集団 で 分離 帯 の 無い 所 は 堂々 と はみ出し 走行 で バリンタワック から 高速 に 入る 。
Warning Remove Text: プ セット
Warning Remove QA: ガラス 張り な の で 彼女 の 行動 は 見え て い まし た 。 最初 は 待っ て い た の に プセット に 荷物 を 急い で 詰め てる 時 、 彼女 は 歩き 始め まし た 。 急い で プセット を 押し て また 彼女 を 捕まえ まし た 。 みんな が 振り返る 程 、 大声 で 叫び 口調 で 「 ママ が 待っ て と 言っ たら 待ち なさい 」 「 一人 で 歩い ちゃ いけ ませ ん 」 「 車 が たくさん いる ん だ から 危ない 」 と 彼女 に きつく いい まし た 。
Warning Remove Text: イミクジロー さん
Warning Remove Text: ハザード チカチカ
Warning Remove QA: ハザードチカチカ の ご 挨拶 は 、 あれ って 誰 が いつ の 間 に やる よう に なっ た ん だろう 。 今 じゃ 当たり前 の よう に みんな やっ てる よ ね 。 そして 割り込ん で 来 て は チカーチカー っと 鳴らす 。 。 強引 に 入っ て 来 て は チカーチカー って やる 。
Warning Remove Text: 某 エネオス
Warning Remove QA: まず 最初 に 並ん だ 某 エネ オス 。 この スタンド の 営業 再開 の 見込み が 立た ない と 分かっ た の は 、 並び 始め て 2 時間 以上 も 経っ て から ・ ・ ・ 。 車 を 降り て 走っ て スタンド の 様子 を 見 に 行っ た 所 、 どう 考え て も オープン する 見込み が 無い と 判断 。 完全 に 無人 の スタンド で 、 「 再開 の 見込み 無し 」 と 貼り出さ れ た スタンド に 2 時間 も 並ん で しまっ た 。
Warning Remove Text: ママ リャリ
Warning Remove QA: アニメ ・ コミック を 中心 と し た 備忘 録 。 信号 待ち を し て い たら 、 前 に 止まっ て い た 自動 車 が かなり の 速度 で 後退 し て き た の で 、 降り て 押し て い た ママリャリ を もっ て 後ろ に さがり まし た が 、 それ で も 間 に 合わす 自転 車 の 前輪 に ぶつけ られ まし た 。 警察 を 呼ぶ ところ まで は 行き ませ ん で でし た が 、 ホイール が 振れ て い たら 弁償 する と いう 確認 を とり 連絡 先 を 聞い て と いう 形 に 。 なん と も 無さ そう に 思える ん です けど 、 しばらく のっ て み ない と わから ない です ね 。
Warning Remove Text: この 子
Warning Remove QA: 前回 、 予定 時間 より 少し 早く 終了 し て ゲージ に 入れ られ て 待たさ れ て い た 際 、 パニック に なり 金 の 柵 を ガリガリ し 続け て 爪 が 折れ た ? の か 私 が 迎え に 行く と 大 出血 し て 手当て を し て もらっ た あんた ん 。 ( こー たん は もちろん の こと 、 ぜ ? っ たいこ の 子 は 預かり と か ペット ホテル と か 飛行 機 と か 入院 と か 無理 だ わぁ ・ ・ って 改めて 思っ た ) 心配 だ から 待つ 時間 が ない 状態 に し て あげ なく ちゃ ! と 思い 、 1人 で 自由 の 身 だっ た から 1 時間 前 から お 店 の 中 の あんた ん から 見え ない 場所 で 待機 し て 引き取っ て き まし た 。
Warning Remove Text: ゆうた
Warning Remove QA: 7 月 は 車 を ぶつけ たり 、 その 他 に も 落ち込む こと が 立て続け に 。 ちょうど 実家 に ゆう た と 帰っ て た 時 に 事件 が 発生 ! ! 両親 を のせ て 4 人 で 垂水 の アウトレット に 行っ て 、 お 寿司 を ご 馳走 し て もらっ て 、 気分 よく 帰っ て たら 、 隣 を 走っ て た 初心 者 マーク の 車 が 急 に 車線 変更 を し て … 。 あぶない ! と 思っ て とっさ に 左 に 切っ た の で 、 ぶつから なかっ た けど 、 すんごい 音 が し て タイヤ が パンク し て しまい まし た 。
Warning Remove Text: 両親 指
Warning Remove QA: 車内 で 二人 掛け の シート に 座り 、 暫し 近況 話 に 花 が 咲き まし た 。 高2 の お 母 さん で も あり 、 未亡人 に なっ て から 一人 で 頑張っ て い ます 。 最初 の 頃 は 何 と 声 を 掛け て 良い やら 困り まし た が 、 前向き な 姿勢 で 疲れ た 様子 は 見受け られ ませ ん でし た 。 両 親指 が バネ指 に なっ た よう です が 、 今 は 痛む こと は ない そう です 。
Warning Remove Text: 少し 窓 を 開け て 話し合い を しよう と し たら
Warning Remove Text: ダイド ー
Warning Remove QA: そして 、 この 道 で そもそも 夜 に 他 の バイク や 車 と すれ違っ た こと は ない 。 と いう か 、 まあ 車 で 走る に は 狭い 。 ぎょえ ー ! と 思っ て 、 パンドラ の うち に つく と 、 前 の 二人 は もう 着い て い た 。 「 ダイ ドー ( 最後 に 走っ て い た ヤツ ) の 隣 に もう 一 台 い た ん だ よ ! 」
Warning Remove Text: 手 く 入れ ない 車
Warning Remove Text: 午前 4 時 から 9 時の間
Warning Remove Text: 場内 の 方向 転換 の 課題 へ
Warning Remove Text: 場内 の 方向 転換 の 課題
Warning Remove Text: 意力 が 散漫 に なっ て いる 時
Warning Remove Text: つも の お 姉 さん
Warning Remove Text: 忘れ物
Warning Remove Text: GAM BA LI
Warning Remove Text: GAM BA LI
Warning Remove Text: ばちゃ ん スクーター
Warning Remove Text: 新学 期始
Warning Remove Text: ラ ・ トゥール
Warning Remove QA: ラ・トゥール で ミカ 達 が 作戦 を 練っ て いる 頃 、 オーストラリア の ナナ と 美和子 の 車 は ハイウェイ を 疾走 し て い た 。 「 なん だ かん だ 言っ て も 、 気分 ええ なぁ ? ? ! 」 日本 の 物 と は 違う 景色 を 眺め ながら ナナ は 美和子 に 話し掛ける 。 美和子 も ハンドル を 握り ながら 、 普段 走り回っ て いる 都内 の 景色 と 違う 中 、 目 を 丸く し ながら 頷い て いる 。
Warning Remove Text: 街中
Warning Remove QA: 室内 の 静粛 性 、 直進 安定 性 、 そして ボディ 剛性 の 高 さ など どれ も 変わら ぬ 感想 で 素晴らしい ! ただ 、 試乗 の 時 と 違い 街 中 を 走っ て い て 気づい た こと が 1 つ 。 それ は アイドリング ストップ システム に 関し て ・ ・ ・ 。 この アイドリング ストップ システム です が 、 信号 待ち など 停車 中 に 自動 的 に エンジン を 停止 し 、 再 発進 する 際 に 自動 的 に エンジン が 再 始動 する システム な 訳 です が 、 実 は この デイズ を 運転 し て 唯一 気 に なる 点 が 、 この エンジン の ストップ と 再 始動 の タイミング 。
Warning Remove Text: 警官 の ア イザイア
Warning Remove Text: 八幡平
Warning Remove QA: も 出 てる だろう し 時間 が かかる に 違い ない … 。 ここ で 時間 を ロス し て しまう と この 後 の 予定 が 詰まっ て しまう と 考え て 、 残念 ながら 。 八幡 平 を あきらめ て その まま 高速 を 走っ て 次 の 目的 地 を 目指す こと に し まし た 。 安代 Jct を 過ぎ て 八戸 道 へ 入り 走っ て いく と 、 青森 へ 入り まし た 。
Warning Remove Text: ジェベ ル
Warning Remove QA: しかし 、 ここ 最近 の 猛暑 の 中 、 高速 道路 の 連続 走行 に ジェベル が 耐え られる の か が 少々 心配 。 この 前 の ツーリング と 違っ て 道東 方面 は 全線 1 車線 の ため 、 速い 車 は お 先 に どうぞ と は いか なく 、 厳しい 走行 が 続く こと に なる だろう 。 広高 オイル に し て から 現在 1000 km 走行 し た が 、 とりあえず この まま で いく 。 前後 の タイヤ は 先日 交換 し た ばかり な の で 問題 ない 。
Warning Remove Text: 外人
Warning Remove QA: まだ 朝 早い の で 人影 が 少なく 、 車 も 通ら ない 。 5 分 ほど し て ようやく 1 台 を 見つけ た が 、 先 の ほう で 別 の 人 に 拾わ れ て しまっ た 。 しばらく し て また 空車 を 見つけ た の で 手 を 上げる が 今度 は 乗車 拒否 。 格好 を 見れ ば 長 距離 乗り そう な 雰囲気 の はず だ けど 、 ホテル の 前 に つける タクシー と 違っ て 、 この 辺り を 流す タクシー は 外 人慣れ し て なく て 面倒 に 思う の か も しれ なかっ た 。
Warning Remove Text: と よ じ さ ん ち
Warning Remove QA: 進め られ て い まし た 。 する と 向う から 、 またまた やっ て 来 まし た ? また 横 を サーッ と 通り抜け て 、 スタコラ サッサと 坂 を 下り て ゆき まし た 。 この 道 は いつ も の 散歩 道 に 通じ て おり 、 と よ じ さん ち に 行く 近道 ・ ・ ・
Warning Remove Text: なに い っ ! !

実行結果として次の2ファイルが出力されます。

  • wakati_DDQA-1.0_RC-QA_train.json
    分かち書きした学習データ
  • wakati_DDQA-1.0_RC-QA_dev.json
    分かち書きした検証データ

ファインチューニングの実行

質疑応答のファインチューニングを行います。

各パラメータの意味は次の通りです。

  • model_type
    モデル識別
  • model_name_or_path
    モデル名
  • do_train
    学習するかどうか
  • do_eval
    検証するかどうか
  • max_seq_length
    最大シーケンス長
  • per_gpu_train_batch_size
    バッチサイズ
  • learning_rate
    学習率
  • num_train_epochs
    学習のエポック数
  • train_file
    学習データ(csvファイルまたはjsonファイル)
  • predict_file
    検証データ(csvファイルまたはjsonファイル)
  • output_dir
    出力先フォルダのパス
  • overwrite_output_dir
    出力先フォルダの上書き

[Google Colaboratory]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
%%time

# ファインチューニングの実行
!python ./transformers/examples/legacy/question-answering/run_squad.py \
--model_type=bert \
--model_name_or_path=cl-tohoku/bert-base-japanese-whole-word-masking \
--do_train \
--do_eval \
--max_seq_length=384 \
--per_gpu_train_batch_size=12 \
--learning_rate=3e-5 \
--num_train_epochs=3 \
--train_file=wakati_DDQA-1.0_RC-QA_train.json \
--predict_file=wakati_DDQA-1.0_RC-QA_dev.json \
--output_dir=output/ \
--overwrite_output_dir

[実行結果]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
10/03/2021 00:15:58 - WARNING - __main__ -   Process rank: -1, device: cuda, n_gpu: 1, distributed training: False, 16-bits training: False
10/03/2021 00:15:58 - INFO - filelock - Lock 139742275205968 acquired on /root/.cache/huggingface/transformers/573af37b6c39d672f2df687c06ad7d556476cbe43e5bf7771097187c45a3e7bf.abeb707b5d79387dd462e8bfb724637d856e98434b6931c769b8716c6f287258.lock
[INFO|file_utils.py:1386] 2021-10-03 00:15:58,904 >> https://huggingface.co/cl-tohoku/bert-base-japanese-whole-word-masking/resolve/main/config.json not found in cache or force_download set to True, downloading to /root/.cache/huggingface/transformers/tmpzc_e3b8q
Downloading: 100% 479/479 [00:00<00:00, 482kB/s]
[INFO|file_utils.py:1390] 2021-10-03 00:15:59,083 >> storing https://huggingface.co/cl-tohoku/bert-base-japanese-whole-word-masking/resolve/main/config.json in cache at /root/.cache/huggingface/transformers/573af37b6c39d672f2df687c06ad7d556476cbe43e5bf7771097187c45a3e7bf.abeb707b5d79387dd462e8bfb724637d856e98434b6931c769b8716c6f287258
[INFO|file_utils.py:1393] 2021-10-03 00:15:59,083 >> creating metadata file for /root/.cache/huggingface/transformers/573af37b6c39d672f2df687c06ad7d556476cbe43e5bf7771097187c45a3e7bf.abeb707b5d79387dd462e8bfb724637d856e98434b6931c769b8716c6f287258
10/03/2021 00:15:59 - INFO - filelock - Lock 139742275205968 released on /root/.cache/huggingface/transformers/573af37b6c39d672f2df687c06ad7d556476cbe43e5bf7771097187c45a3e7bf.abeb707b5d79387dd462e8bfb724637d856e98434b6931c769b8716c6f287258.lock
[INFO|configuration_utils.py:463] 2021-10-03 00:15:59,084 >> loading configuration file https://huggingface.co/cl-tohoku/bert-base-japanese-whole-word-masking/resolve/main/config.json from cache at /root/.cache/huggingface/transformers/573af37b6c39d672f2df687c06ad7d556476cbe43e5bf7771097187c45a3e7bf.abeb707b5d79387dd462e8bfb724637d856e98434b6931c769b8716c6f287258

(・・・・・途中略・・・・・)

100% 1/1 [00:00<00:00, 7.62it/s]
convert squad examples to features: 100% 1052/1052 [00:08<00:00, 130.44it/s]
add example index and unique id: 100% 1052/1052 [00:00<00:00, 656901.56it/s]
10/03/2021 02:22:37 - INFO - __main__ - Saving features into cached file ./cached_dev_bert-base-japanese-whole-word-masking_384
10/03/2021 02:22:39 - INFO - __main__ - ***** Running evaluation *****
10/03/2021 02:22:39 - INFO - __main__ - Num examples = 1052
10/03/2021 02:22:39 - INFO - __main__ - Batch size = 8
Evaluating: 100% 132/132 [00:52<00:00, 2.53it/s]
10/03/2021 02:23:31 - INFO - __main__ - Evaluation done in total 52.158478 secs (0.049580 sec per example)
[INFO|squad_metrics.py:401] 2021-10-03 02:23:31,244 >> Writing predictions to: output/predictions_.json
[INFO|squad_metrics.py:403] 2021-10-03 02:23:31,244 >> Writing nbest to: output/nbest_predictions_.json
10/03/2021 02:23:34 - INFO - __main__ - Results: {'exact': 87.79069767441861, 'f1': 92.2942438197623, 'total': 1032, 'HasAns_exact': 87.79069767441861, 'HasAns_f1': 92.2942438197623, 'HasAns_total': 1032, 'best_exact': 87.79069767441861, 'best_exact_thresh': 0.0, 'best_f1': 92.2942438197623, 'best_f1_thresh': 0.0}
CPU times: user 51.7 s, sys: 7.79 s, total: 59.5 s
Wall time: 2h 7min 44s

2時間7分ほどかかりました。(;^_^A

学習結果の確認

TensorBoardで学習結果を確認します。

[Google Colaboratory]

1
2
3
# 学習状況の確認
%load_ext tensorboard
%tensorboard --logdir runs

[実行結果]

損失(Loss)が0に収束しているため、きちんと学習できていることが分かります。

次回は、学習したモデルを使って質疑応答を行います。

Transformers(10) - 質疑応答①データセットの準備とライブラリ・インストール

質疑応答を3回に分けて説明していきます。

質疑応答は、コンテキスト(ひとまとまりの文章)質問からコンテキスト内に含まれる応答を抽出する処理です。

今回は、データセットの準備と必要ライブラリのインストールまで行います。

データセットの準備

データセットとしては運転ドメインQAデータセットを使います。

下記のURLから、ダウンロードリンクよりDDQA-1.0.tar.gzファイルをダウンロードしてください。

運転ドメインQAデータセット - https://nlp.ist.i.kyoto-u.ac.jp/?Driving+domain+QA+datasets


次にダウンロードしたファイルを、Google Colaboratoryにアップロードし、下記コマンドを使って解凍します。

[Google Colaboratory]

1
!tar xzvf DDQA-1.0.tar.gz

[実行結果]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
DDQA-1.0/
DDQA-1.0/RC-QA/
DDQA-1.0/PAS-QA-NOM/
DDQA-1.0/PAS-QA-ACC/
DDQA-1.0/PAS-QA-DAT/
DDQA-1.0/README_en.txt
DDQA-1.0/README_ja.txt
DDQA-1.0/PAS-QA-DAT/DDQA-1.0_PAS-QA-DAT_train.json
DDQA-1.0/PAS-QA-DAT/DDQA-1.0_PAS-QA-DAT_dev.json
DDQA-1.0/PAS-QA-DAT/DDQA-1.0_PAS-QA-DAT_test.json
DDQA-1.0/PAS-QA-ACC/DDQA-1.0_PAS-QA-ACC_train.json
DDQA-1.0/PAS-QA-ACC/DDQA-1.0_PAS-QA-ACC_dev.json
DDQA-1.0/PAS-QA-ACC/DDQA-1.0_PAS-QA-ACC_test.json
DDQA-1.0/PAS-QA-NOM/DDQA-1.0_PAS-QA-NOM_dev.json
DDQA-1.0/PAS-QA-NOM/DDQA-1.0_PAS-QA-NOM_test.json
DDQA-1.0/PAS-QA-NOM/DDQA-1.0_PAS-QA-NOM_train.json
DDQA-1.0/RC-QA/DDQA-1.0_RC-QA_dev.json
DDQA-1.0/RC-QA/DDQA-1.0_RC-QA_test.json
DDQA-1.0/RC-QA/DDQA-1.0_RC-QA_train.json

これでデータセットの準備は完了です。

Huggingface Transformersのインストール

ソースからHuggingface Transformersのインストールを行います。

[Google Colaboratory]

1
2
3
4
5
# ソースからのHuggingface Transformersのインストール
!git clone https://github.com/huggingface/transformers -b v4.4.2
!pip install -e transformers
!pip install fugashi[unidic-lite]
!pip install ipadic

下記のような実行結果になれば、Huggingface Transformersのインストールは成功しています。

[実行結果]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
Cloning into 'transformers'...
remote: Enumerating objects: 85569, done.
remote: Counting objects: 100% (28/28), done.
remote: Compressing objects: 100% (22/22), done.
remote: Total 85569 (delta 8), reused 17 (delta 3), pack-reused 85541
Receiving objects: 100% (85569/85569), 68.44 MiB | 24.02 MiB/s, done.
Resolving deltas: 100% (61496/61496), done.
Note: checking out '9f43a425fe89cfc0e9b9aa7abd7dd44bcaccd79a'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

git checkout -b <new-branch-name>

Obtaining file:///content/transformers
Installing build dependencies ... done
Getting requirements to build wheel ... done
Preparing wheel metadata ... done
Collecting tokenizers<0.11,>=0.10.1
Downloading tokenizers-0.10.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (3.3 MB)
|████████████████████████████████| 3.3 MB 5.1 MB/s
Requirement already satisfied: filelock in /usr/local/lib/python3.7/dist-packages (from transformers==4.4.2) (3.0.12)
Requirement already satisfied: requests in /usr/local/lib/python3.7/dist-packages (from transformers==4.4.2) (2.23.0)
Collecting sacremoses
Downloading sacremoses-0.0.46-py3-none-any.whl (895 kB)
|████████████████████████████████| 895 kB 50.1 MB/s
Requirement already satisfied: numpy>=1.17 in /usr/local/lib/python3.7/dist-packages (from transformers==4.4.2) (1.19.5)
Requirement already satisfied: packaging in /usr/local/lib/python3.7/dist-packages (from transformers==4.4.2) (21.0)
Requirement already satisfied: regex!=2019.12.17 in /usr/local/lib/python3.7/dist-packages (from transformers==4.4.2) (2019.12.20)
Requirement already satisfied: tqdm>=4.27 in /usr/local/lib/python3.7/dist-packages (from transformers==4.4.2) (4.62.3)
Requirement already satisfied: importlib-metadata in /usr/local/lib/python3.7/dist-packages (from transformers==4.4.2) (4.8.1)
Requirement already satisfied: typing-extensions>=3.6.4 in /usr/local/lib/python3.7/dist-packages (from importlib-metadata->transformers==4.4.2) (3.7.4.3)
Requirement already satisfied: zipp>=0.5 in /usr/local/lib/python3.7/dist-packages (from importlib-metadata->transformers==4.4.2) (3.5.0)
Requirement already satisfied: pyparsing>=2.0.2 in /usr/local/lib/python3.7/dist-packages (from packaging->transformers==4.4.2) (2.4.7)
Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.7/dist-packages (from requests->transformers==4.4.2) (2.10)
Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.7/dist-packages (from requests->transformers==4.4.2) (3.0.4)
Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.7/dist-packages (from requests->transformers==4.4.2) (2021.5.30)
Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python3.7/dist-packages (from requests->transformers==4.4.2) (1.24.3)
Requirement already satisfied: click in /usr/local/lib/python3.7/dist-packages (from sacremoses->transformers==4.4.2) (7.1.2)
Requirement already satisfied: six in /usr/local/lib/python3.7/dist-packages (from sacremoses->transformers==4.4.2) (1.15.0)
Requirement already satisfied: joblib in /usr/local/lib/python3.7/dist-packages (from sacremoses->transformers==4.4.2) (1.0.1)
Installing collected packages: tokenizers, sacremoses, transformers
Running setup.py develop for transformers
Successfully installed sacremoses-0.0.46 tokenizers-0.10.3 transformers-4.4.2
Collecting fugashi[unidic-lite]
Downloading fugashi-1.1.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl (490 kB)
|████████████████████████████████| 490 kB 5.2 MB/s
Collecting unidic-lite
Downloading unidic-lite-1.0.8.tar.gz (47.4 MB)
|████████████████████████████████| 47.4 MB 92 kB/s
Building wheels for collected packages: unidic-lite
Building wheel for unidic-lite (setup.py) ... done
Created wheel for unidic-lite: filename=unidic_lite-1.0.8-py3-none-any.whl size=47658836 sha256=b5301b21eb0c5ec36e22cf4f0e7f6dfb63d8c968cf59353e0ba252853e96d055
Stored in directory: /root/.cache/pip/wheels/de/69/b1/112140b599f2b13f609d485a99e357ba68df194d2079c5b1a2
Successfully built unidic-lite
Installing collected packages: unidic-lite, fugashi
Successfully installed fugashi-1.1.1 unidic-lite-1.0.8
Collecting ipadic
Downloading ipadic-1.0.0.tar.gz (13.4 MB)
|████████████████████████████████| 13.4 MB 210 kB/s
Building wheels for collected packages: ipadic
Building wheel for ipadic (setup.py) ... done
Created wheel for ipadic: filename=ipadic-1.0.0-py3-none-any.whl size=13556723 sha256=07367203dbaaef7bd0d3d9a3c355d8927072637e6e2398a3e2ab710c877d6e7a
Stored in directory: /root/.cache/pip/wheels/33/8b/99/cf0d27191876637cd3639a560f93aa982d7855ce826c94348b
Successfully built ipadic
Installing collected packages: ipadic
Successfully installed ipadic-1.0.0

ここで、一旦ランタイムの再起動を行います。

メニューからランタイム → ランタイムを再起動を選択してください。

Huggingface Datasetsのインストール

Huggingface Datasetsのインストールを行います。

[Google Colaboratory]

1
2
# Huggingface Datasetsのインストール
!pip install datasets==1.2.1

[実行結果]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Collecting datasets==1.2.1
Downloading datasets-1.2.1-py3-none-any.whl (159 kB)
|████████████████████████████████| 159 kB 5.4 MB/s
Requirement already satisfied: numpy>=1.17 in /usr/local/lib/python3.7/dist-packages (from datasets==1.2.1) (1.19.5)
Requirement already satisfied: pyarrow>=0.17.1 in /usr/local/lib/python3.7/dist-packages (from datasets==1.2.1) (3.0.0)
Collecting tqdm<4.50.0,>=4.27
Downloading tqdm-4.49.0-py2.py3-none-any.whl (69 kB)
|████████████████████████████████| 69 kB 6.6 MB/s
Requirement already satisfied: multiprocess in /usr/local/lib/python3.7/dist-packages (from datasets==1.2.1) (0.70.12.2)
Requirement already satisfied: importlib-metadata in /usr/local/lib/python3.7/dist-packages (from datasets==1.2.1) (4.8.1)
Requirement already satisfied: pandas in /usr/local/lib/python3.7/dist-packages (from datasets==1.2.1) (1.1.5)
Requirement already satisfied: requests>=2.19.0 in /usr/local/lib/python3.7/dist-packages (from datasets==1.2.1) (2.23.0)
Collecting xxhash
Downloading xxhash-2.0.2-cp37-cp37m-manylinux2010_x86_64.whl (243 kB)
|████████████████████████████████| 243 kB 19.6 MB/s
Requirement already satisfied: dill in /usr/local/lib/python3.7/dist-packages (from datasets==1.2.1) (0.3.4)
Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python3.7/dist-packages (from requests>=2.19.0->datasets==1.2.1) (1.24.3)
Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.7/dist-packages (from requests>=2.19.0->datasets==1.2.1) (3.0.4)
Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.7/dist-packages (from requests>=2.19.0->datasets==1.2.1) (2021.5.30)
Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.7/dist-packages (from requests>=2.19.0->datasets==1.2.1) (2.10)
Requirement already satisfied: typing-extensions>=3.6.4 in /usr/local/lib/python3.7/dist-packages (from importlib-metadata->datasets==1.2.1) (3.7.4.3)
Requirement already satisfied: zipp>=0.5 in /usr/local/lib/python3.7/dist-packages (from importlib-metadata->datasets==1.2.1) (3.5.0)
Requirement already satisfied: python-dateutil>=2.7.3 in /usr/local/lib/python3.7/dist-packages (from pandas->datasets==1.2.1) (2.8.2)
Requirement already satisfied: pytz>=2017.2 in /usr/local/lib/python3.7/dist-packages (from pandas->datasets==1.2.1) (2018.9)
Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.7/dist-packages (from python-dateutil>=2.7.3->pandas->datasets==1.2.1) (1.15.0)
Installing collected packages: xxhash, tqdm, datasets
Attempting uninstall: tqdm
Found existing installation: tqdm 4.62.3
Uninstalling tqdm-4.62.3:
Successfully uninstalled tqdm-4.62.3
Successfully installed datasets-1.2.1 tqdm-4.49.0 xxhash-2.0.2

MeCabのインストール

MeCabのインストールを行います。

MeCabは、簡単なテキスト解析や、分かち書きができるライブラリです。

[Google Colaboratory]

1
2
# MeCabのインストール
!pip install mecab-python3

[実行結果]

1
2
3
4
5
Collecting mecab-python3
Downloading mecab_python3-1.0.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl (488 kB)
|████████████████████████████████| 488 kB 5.3 MB/s
Installing collected packages: mecab-python3
Successfully installed mecab-python3-1.0.4

以上で、必要なライブラリのインストールが完了しました。

次回は、わかち書きファインチューニングを行います。

Transformers(9) - テキスト分類②学習と推論

前回は、テキスト分類のための学習データと検証データを用意しました。

今回は、この学習データと検証データを使って学習と推論を行います。

Huggingface Transformersのインストール

ソースからHuggingface Transformersのインストールを行います。

[Google Colaboratory]

1
2
3
4
5
# ソースからのHuggingface Transformersのインストール
!git clone https://github.com/huggingface/transformers -b v4.4.2
!pip install -e transformers
!pip install fugashi[unidic-lite]
!pip install ipadic

下記のような実行結果になれば、Huggingface Transformersのインストールは成功しています。

[実行結果]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
Cloning into 'transformers'...
remote: Enumerating objects: 85569, done.
remote: Counting objects: 100% (28/28), done.
remote: Compressing objects: 100% (22/22), done.
remote: Total 85569 (delta 8), reused 17 (delta 3), pack-reused 85541
Receiving objects: 100% (85569/85569), 68.48 MiB | 23.50 MiB/s, done.
Resolving deltas: 100% (61495/61495), done.
Note: checking out '9f43a425fe89cfc0e9b9aa7abd7dd44bcaccd79a'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

git checkout -b <new-branch-name>

Obtaining file:///content/transformers
Installing build dependencies ... done
Getting requirements to build wheel ... done
Preparing wheel metadata ... done
Requirement already satisfied: filelock in /usr/local/lib/python3.7/dist-packages (from transformers==4.4.2) (3.0.12)
Requirement already satisfied: numpy>=1.17 in /usr/local/lib/python3.7/dist-packages (from transformers==4.4.2) (1.19.5)
Requirement already satisfied: requests in /usr/local/lib/python3.7/dist-packages (from transformers==4.4.2) (2.23.0)
Requirement already satisfied: packaging in /usr/local/lib/python3.7/dist-packages (from transformers==4.4.2) (21.0)
Requirement already satisfied: importlib-metadata in /usr/local/lib/python3.7/dist-packages (from transformers==4.4.2) (4.8.1)
Collecting sacremoses
Downloading sacremoses-0.0.46-py3-none-any.whl (895 kB)
|████████████████████████████████| 895 kB 5.2 MB/s
Requirement already satisfied: regex!=2019.12.17 in /usr/local/lib/python3.7/dist-packages (from transformers==4.4.2) (2019.12.20)
Collecting tokenizers<0.11,>=0.10.1
Downloading tokenizers-0.10.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (3.3 MB)
|████████████████████████████████| 3.3 MB 32.2 MB/s
Requirement already satisfied: tqdm>=4.27 in /usr/local/lib/python3.7/dist-packages (from transformers==4.4.2) (4.62.3)
Requirement already satisfied: zipp>=0.5 in /usr/local/lib/python3.7/dist-packages (from importlib-metadata->transformers==4.4.2) (3.5.0)
Requirement already satisfied: typing-extensions>=3.6.4 in /usr/local/lib/python3.7/dist-packages (from importlib-metadata->transformers==4.4.2) (3.7.4.3)
Requirement already satisfied: pyparsing>=2.0.2 in /usr/local/lib/python3.7/dist-packages (from packaging->transformers==4.4.2) (2.4.7)
Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.7/dist-packages (from requests->transformers==4.4.2) (3.0.4)
Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python3.7/dist-packages (from requests->transformers==4.4.2) (1.24.3)
Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.7/dist-packages (from requests->transformers==4.4.2) (2021.5.30)
Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.7/dist-packages (from requests->transformers==4.4.2) (2.10)
Requirement already satisfied: joblib in /usr/local/lib/python3.7/dist-packages (from sacremoses->transformers==4.4.2) (1.0.1)
Requirement already satisfied: click in /usr/local/lib/python3.7/dist-packages (from sacremoses->transformers==4.4.2) (7.1.2)
Requirement already satisfied: six in /usr/local/lib/python3.7/dist-packages (from sacremoses->transformers==4.4.2) (1.15.0)
Installing collected packages: tokenizers, sacremoses, transformers
Running setup.py develop for transformers
Successfully installed sacremoses-0.0.46 tokenizers-0.10.3 transformers-4.4.2
Collecting fugashi[unidic-lite]
Downloading fugashi-1.1.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl (490 kB)
|████████████████████████████████| 490 kB 5.3 MB/s
Collecting unidic-lite
Downloading unidic-lite-1.0.8.tar.gz (47.4 MB)
|████████████████████████████████| 47.4 MB 46 kB/s
Building wheels for collected packages: unidic-lite
Building wheel for unidic-lite (setup.py) ... done
Created wheel for unidic-lite: filename=unidic_lite-1.0.8-py3-none-any.whl size=47658836 sha256=a900f8c583a206e3a5dbf25e2c9bc3bb7c8bd17e5968974b5c3a798570bc2364
Stored in directory: /root/.cache/pip/wheels/de/69/b1/112140b599f2b13f609d485a99e357ba68df194d2079c5b1a2
Successfully built unidic-lite
Installing collected packages: unidic-lite, fugashi
Successfully installed fugashi-1.1.1 unidic-lite-1.0.8
Collecting ipadic
Downloading ipadic-1.0.0.tar.gz (13.4 MB)
|████████████████████████████████| 13.4 MB 182 kB/s
Building wheels for collected packages: ipadic
Building wheel for ipadic (setup.py) ... done
Created wheel for ipadic: filename=ipadic-1.0.0-py3-none-any.whl size=13556723 sha256=0903009667e96df8abd478ee8f094186148de203896aeeebb6f068a4811d2c0d
Stored in directory: /root/.cache/pip/wheels/33/8b/99/cf0d27191876637cd3639a560f93aa982d7855ce826c94348b
Successfully built ipadic
Installing collected packages: ipadic
Successfully installed ipadic-1.0.0

ここで、一旦ランタイムの再起動を行います。

メニューからランタイム → ランタイムを再起動を選択してください。

Huggingface Datasetsのインストール

Huggingface Datasetsのインストールを行います。

[Google Colaboratory]

1
2
# Huggingface Datasetsのインストール
!pip install datasets==1.2.1

下記のような実行結果になれば、Huggingface Datasetsのインストールは成功しています。

[実行結果]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Collecting datasets==1.2.1
Downloading datasets-1.2.1-py3-none-any.whl (159 kB)
|████████████████████████████████| 159 kB 5.4 MB/s
Collecting xxhash
Downloading xxhash-2.0.2-cp37-cp37m-manylinux2010_x86_64.whl (243 kB)
|████████████████████████████████| 243 kB 32.3 MB/s
Requirement already satisfied: importlib-metadata in /usr/local/lib/python3.7/dist-packages (from datasets==1.2.1) (4.8.1)
Requirement already satisfied: requests>=2.19.0 in /usr/local/lib/python3.7/dist-packages (from datasets==1.2.1) (2.23.0)
Requirement already satisfied: numpy>=1.17 in /usr/local/lib/python3.7/dist-packages (from datasets==1.2.1) (1.19.5)
Requirement already satisfied: pyarrow>=0.17.1 in /usr/local/lib/python3.7/dist-packages (from datasets==1.2.1) (3.0.0)
Requirement already satisfied: pandas in /usr/local/lib/python3.7/dist-packages (from datasets==1.2.1) (1.1.5)
Requirement already satisfied: multiprocess in /usr/local/lib/python3.7/dist-packages (from datasets==1.2.1) (0.70.12.2)
Requirement already satisfied: dill in /usr/local/lib/python3.7/dist-packages (from datasets==1.2.1) (0.3.4)
Collecting tqdm<4.50.0,>=4.27
Downloading tqdm-4.49.0-py2.py3-none-any.whl (69 kB)
|████████████████████████████████| 69 kB 6.4 MB/s
Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.7/dist-packages (from requests>=2.19.0->datasets==1.2.1) (2021.5.30)
Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.7/dist-packages (from requests>=2.19.0->datasets==1.2.1) (2.10)
Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.7/dist-packages (from requests>=2.19.0->datasets==1.2.1) (3.0.4)
Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python3.7/dist-packages (from requests>=2.19.0->datasets==1.2.1) (1.24.3)
Requirement already satisfied: typing-extensions>=3.6.4 in /usr/local/lib/python3.7/dist-packages (from importlib-metadata->datasets==1.2.1) (3.7.4.3)
Requirement already satisfied: zipp>=0.5 in /usr/local/lib/python3.7/dist-packages (from importlib-metadata->datasets==1.2.1) (3.5.0)
Requirement already satisfied: python-dateutil>=2.7.3 in /usr/local/lib/python3.7/dist-packages (from pandas->datasets==1.2.1) (2.8.2)
Requirement already satisfied: pytz>=2017.2 in /usr/local/lib/python3.7/dist-packages (from pandas->datasets==1.2.1) (2018.9)
Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.7/dist-packages (from python-dateutil>=2.7.3->pandas->datasets==1.2.1) (1.15.0)
Installing collected packages: xxhash, tqdm, datasets
Attempting uninstall: tqdm
Found existing installation: tqdm 4.62.3
Uninstalling tqdm-4.62.3:
Successfully uninstalled tqdm-4.62.3
Successfully installed datasets-1.2.1 tqdm-4.49.0 xxhash-2.0.2

ファインチューニングの実行

ファインチューニングの実行を行います。

各パラメータの意味は以下の通りです。

  • model_name_or_path
    モデル名
  • do_train
    学習するかどうか
  • do_eval
    検証するかどうか
  • max_seq_length
    最大シーケンス長
  • per_device_train_batch_size
    バッチサイズ
  • use_fast_tokenizer
    ファストトークナイザーの利用
  • learning_rate
    学習率
  • num_train_epochs
    学習のエポック数
  • train_file
    学習データ(csvファイル、jsonファイル)
  • validation_file
    検証データ(csvファイル、jsonファイル)
  • output_dir
    出力先フォルダのパス
  • overwrite_output_dir
    出力フォルダの上書き
  • logging_steps
    何ステップごとにチェックポイントを出力するか

[Google Colaboratory]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
%%time

# ファインチューニングの実行
!python ./transformers/examples/text-classification/run_glue.py \
--model_name_or_path=cl-tohoku/bert-base-japanese-whole-word-masking \
--do_train \
--do_eval \
--max_seq_length=128 \
--per_device_train_batch_size=32 \
--use_fast_tokenizer=False \
--learning_rate=2e-5 \
--num_train_epochs=10 \
--train_file=train.csv \
--validation_file=dev.csv \
--output_dir=output/ \
--overwrite_output_dir \
--logging_steps=100

ファインチューニングは少し時間がかかりますので、気長にお待ちください。

[実行結果]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
10/02/2021 06:53:19 - WARNING - __main__ -   Process rank: -1, device: cuda:0, n_gpu: 1distributed training: False, 16-bits training: False
10/02/2021 06:53:19 - INFO - __main__ - Training/evaluation parameters TrainingArguments(output_dir=output/, overwrite_output_dir=True, do_train=True, do_eval=True, do_predict=False, evaluation_strategy=IntervalStrategy.NO, prediction_loss_only=False, per_device_train_batch_size=32, per_device_eval_batch_size=8, gradient_accumulation_steps=1, eval_accumulation_steps=None, learning_rate=2e-05, weight_decay=0.0, adam_beta1=0.9, adam_beta2=0.999, adam_epsilon=1e-08, max_grad_norm=1.0, num_train_epochs=10.0, max_steps=-1, lr_scheduler_type=SchedulerType.LINEAR, warmup_ratio=0.0, warmup_steps=0, logging_dir=runs/Oct02_06-53-19_e352111af80c, logging_strategy=IntervalStrategy.STEPS, logging_first_step=False, logging_steps=100, save_strategy=IntervalStrategy.STEPS, save_steps=500, save_total_limit=None, no_cuda=False, seed=42, fp16=False, fp16_opt_level=O1, fp16_backend=auto, fp16_full_eval=False, local_rank=-1, tpu_num_cores=None, tpu_metrics_debug=False, debug=False, dataloader_drop_last=False, eval_steps=100, dataloader_num_workers=0, past_index=-1, run_name=output/, disable_tqdm=False, remove_unused_columns=True, label_names=None, load_best_model_at_end=False, metric_for_best_model=None, greater_is_better=None, ignore_data_skip=False, sharded_ddp=[], deepspeed=None, label_smoothing_factor=0.0, adafactor=False, group_by_length=False, report_to=['tensorboard'], ddp_find_unused_parameters=None, dataloader_pin_memory=True, skip_memory_metrics=False, _n_gpu=1)
10/02/2021 06:53:19 - INFO - __main__ - load a local file for train: train.csv
10/02/2021 06:53:19 - INFO - __main__ - load a local file for validation: dev.csv
Downloading: 5.33kB [00:00, 4.14MB/s]
Using custom data configuration default
Downloading and preparing dataset csv/default-3977538288dff7b4 (download: Unknown size, generated: Unknown size, post-processed: Unknown size, total: Unknown size) to /root/.cache/huggingface/datasets/csv/default-3977538288dff7b4/0.0.0/2960f95a26e85d40ca41a230ac88787f715ee3003edaacb8b1f0891e9f04dda2...
Dataset csv downloaded and prepared to /root/.cache/huggingface/datasets/csv/default-3977538288dff7b4/0.0.0/2960f95a26e85d40ca41a230ac88787f715ee3003edaacb8b1f0891e9f04dda2. Subsequent calls will reuse this data.
[INFO|file_utils.py:1386] 2021-10-02 06:53:20,548 >> https://huggingface.co/cl-tohoku/bert-base-japanese-whole-word-masking/resolve/main/config.json not found in cache or force_download set to True, downloading to /root/.cache/huggingface/transformers/tmpx2iuwgdb
Downloading: 100% 479/479 [00:00<00:00, 423kB/s]
[INFO|file_utils.py:1390] 2021-10-02 06:53:20,673 >> storing https://huggingface.co/cl-tohoku/bert-base-japanese-whole-word-masking/resolve/main/config.json in cache at /root/.cache/huggingface/transformers/573af37b6c39d672f2df687c06ad7d556476cbe43e5bf7771097187c45a3e7bf.abeb707b5d79387dd462e8bfb724637d856e98434b6931c769b8716c6f287258
[INFO|file_utils.py:1393] 2021-10-02 06:53:20,673 >> creating metadata file for /root/.cache/huggingface/transformers/573af37b6c39d672f2df687c06ad7d556476cbe43e5bf7771097187c45a3e7bf.abeb707b5d79387dd462e8bfb724637d856e98434b6931c769b8716c6f287258
[INFO|configuration_utils.py:463] 2021-10-02 06:53:20,674 >> loading configuration file https://huggingface.co/cl-tohoku/bert-base-japanese-whole-word-masking/resolve/main/config.json from cache at /root/.cache/huggingface/transformers/573af37b6c39d672f2df687c06ad7d556476cbe43e5bf7771097187c45a3e7bf.abeb707b5d79387dd462e8bfb724637d856e98434b6931c769b8716c6f287258
[INFO|configuration_utils.py:499] 2021-10-02 06:53:20,674 >> Model config BertConfig {
"architectures": [
"BertForMaskedLM"
],
"attention_probs_dropout_prob": 0.1,
"gradient_checkpointing": false,
"hidden_act": "gelu",
"hidden_dropout_prob": 0.1,
"hidden_size": 768,
"id2label": {
"0": "LABEL_0",
"1": "LABEL_1",
"2": "LABEL_2"
},
"initializer_range": 0.02,
"intermediate_size": 3072,
"label2id": {
"LABEL_0": 0,
"LABEL_1": 1,
"LABEL_2": 2
},
"layer_norm_eps": 1e-12,
"max_position_embeddings": 512,
"model_type": "bert",
"num_attention_heads": 12,
"num_hidden_layers": 12,
"pad_token_id": 0,
"position_embedding_type": "absolute",
"tokenizer_class": "BertJapaneseTokenizer",
"transformers_version": "4.4.2",
"type_vocab_size": 2,
"use_cache": true,
"vocab_size": 32000
}

[INFO|configuration_utils.py:463] 2021-10-02 06:53:20,802 >> loading configuration file https://huggingface.co/cl-tohoku/bert-base-japanese-whole-word-masking/resolve/main/config.json from cache at /root/.cache/huggingface/transformers/573af37b6c39d672f2df687c06ad7d556476cbe43e5bf7771097187c45a3e7bf.abeb707b5d79387dd462e8bfb724637d856e98434b6931c769b8716c6f287258
[INFO|configuration_utils.py:499] 2021-10-02 06:53:20,803 >> Model config BertConfig {
"architectures": [
"BertForMaskedLM"
],
"attention_probs_dropout_prob": 0.1,
"gradient_checkpointing": false,
"hidden_act": "gelu",
"hidden_dropout_prob": 0.1,
"hidden_size": 768,
"initializer_range": 0.02,
"intermediate_size": 3072,
"layer_norm_eps": 1e-12,
"max_position_embeddings": 512,
"model_type": "bert",
"num_attention_heads": 12,
"num_hidden_layers": 12,
"pad_token_id": 0,
"position_embedding_type": "absolute",
"tokenizer_class": "BertJapaneseTokenizer",
"transformers_version": "4.4.2",
"type_vocab_size": 2,
"use_cache": true,
"vocab_size": 32000
}

[INFO|file_utils.py:1386] 2021-10-02 06:53:20,926 >> https://huggingface.co/cl-tohoku/bert-base-japanese-whole-word-masking/resolve/main/vocab.txt not found in cache or force_download set to True, downloading to /root/.cache/huggingface/transformers/tmpjq6xsip6
Downloading: 100% 258k/258k [00:00<00:00, 3.12MB/s]
[INFO|file_utils.py:1390] 2021-10-02 06:53:21,164 >> storing https://huggingface.co/cl-tohoku/bert-base-japanese-whole-word-masking/resolve/main/vocab.txt in cache at /root/.cache/huggingface/transformers/15164357d71cd32532e56c1d7c2757141326ae17c53e2277bc417cc7c21da6ea.a7378a0cbee5cff668832a776d72b97a25479604fe9564d5595897f75049e7f4
[INFO|file_utils.py:1393] 2021-10-02 06:53:21,164 >> creating metadata file for /root/.cache/huggingface/transformers/15164357d71cd32532e56c1d7c2757141326ae17c53e2277bc417cc7c21da6ea.a7378a0cbee5cff668832a776d72b97a25479604fe9564d5595897f75049e7f4
[INFO|file_utils.py:1386] 2021-10-02 06:53:21,533 >> https://huggingface.co/cl-tohoku/bert-base-japanese-whole-word-masking/resolve/main/tokenizer_config.json not found in cache or force_download set to True, downloading to /root/.cache/huggingface/transformers/tmpvwenqgcb
Downloading: 100% 110/110 [00:00<00:00, 105kB/s]
[INFO|file_utils.py:1390] 2021-10-02 06:53:21,664 >> storing https://huggingface.co/cl-tohoku/bert-base-japanese-whole-word-masking/resolve/main/tokenizer_config.json in cache at /root/.cache/huggingface/transformers/0e46f722799f19c3f0c53172545108a4b31847d3b9a2d5b100759f6673bd667b.08ae4e4044742b9cc7172698caf1da2524f5597ff8cf848114dd0b730cc44bdc
[INFO|file_utils.py:1393] 2021-10-02 06:53:21,664 >> creating metadata file for /root/.cache/huggingface/transformers/0e46f722799f19c3f0c53172545108a4b31847d3b9a2d5b100759f6673bd667b.08ae4e4044742b9cc7172698caf1da2524f5597ff8cf848114dd0b730cc44bdc
[INFO|tokenization_utils_base.py:1702] 2021-10-02 06:53:21,789 >> loading file https://huggingface.co/cl-tohoku/bert-base-japanese-whole-word-masking/resolve/main/vocab.txt from cache at /root/.cache/huggingface/transformers/15164357d71cd32532e56c1d7c2757141326ae17c53e2277bc417cc7c21da6ea.a7378a0cbee5cff668832a776d72b97a25479604fe9564d5595897f75049e7f4
[INFO|tokenization_utils_base.py:1702] 2021-10-02 06:53:21,790 >> loading file https://huggingface.co/cl-tohoku/bert-base-japanese-whole-word-masking/resolve/main/added_tokens.json from cache at None
[INFO|tokenization_utils_base.py:1702] 2021-10-02 06:53:21,790 >> loading file https://huggingface.co/cl-tohoku/bert-base-japanese-whole-word-masking/resolve/main/special_tokens_map.json from cache at None
[INFO|tokenization_utils_base.py:1702] 2021-10-02 06:53:21,790 >> loading file https://huggingface.co/cl-tohoku/bert-base-japanese-whole-word-masking/resolve/main/tokenizer_config.json from cache at /root/.cache/huggingface/transformers/0e46f722799f19c3f0c53172545108a4b31847d3b9a2d5b100759f6673bd667b.08ae4e4044742b9cc7172698caf1da2524f5597ff8cf848114dd0b730cc44bdc
[INFO|tokenization_utils_base.py:1702] 2021-10-02 06:53:21,790 >> loading file https://huggingface.co/cl-tohoku/bert-base-japanese-whole-word-masking/resolve/main/tokenizer.json from cache at None
[INFO|file_utils.py:1386] 2021-10-02 06:53:21,968 >> https://huggingface.co/cl-tohoku/bert-base-japanese-whole-word-masking/resolve/main/pytorch_model.bin not found in cache or force_download set to True, downloading to /root/.cache/huggingface/transformers/tmpa845b2k1
Downloading: 100% 445M/445M [00:12<00:00, 36.5MB/s]
[INFO|file_utils.py:1390] 2021-10-02 06:53:34,325 >> storing https://huggingface.co/cl-tohoku/bert-base-japanese-whole-word-masking/resolve/main/pytorch_model.bin in cache at /root/.cache/huggingface/transformers/cabd9bbd81093f4c494a02e34eb57e405b7564db216404108c8e8caf10ede4fa.464b54997e35e3cc3223ba6d7f0abdaeb7be5b7648f275f57d839ee0f95611fb
[INFO|file_utils.py:1393] 2021-10-02 06:53:34,325 >> creating metadata file for /root/.cache/huggingface/transformers/cabd9bbd81093f4c494a02e34eb57e405b7564db216404108c8e8caf10ede4fa.464b54997e35e3cc3223ba6d7f0abdaeb7be5b7648f275f57d839ee0f95611fb
[INFO|modeling_utils.py:1051] 2021-10-02 06:53:34,325 >> loading weights file https://huggingface.co/cl-tohoku/bert-base-japanese-whole-word-masking/resolve/main/pytorch_model.bin from cache at /root/.cache/huggingface/transformers/cabd9bbd81093f4c494a02e34eb57e405b7564db216404108c8e8caf10ede4fa.464b54997e35e3cc3223ba6d7f0abdaeb7be5b7648f275f57d839ee0f95611fb
[WARNING|modeling_utils.py:1159] 2021-10-02 06:53:37,781 >> Some weights of the model checkpoint at cl-tohoku/bert-base-japanese-whole-word-masking were not used when initializing BertForSequenceClassification: ['cls.predictions.bias', 'cls.predictions.transform.dense.weight', 'cls.predictions.transform.dense.bias', 'cls.predictions.transform.LayerNorm.weight', 'cls.predictions.transform.LayerNorm.bias', 'cls.predictions.decoder.weight', 'cls.seq_relationship.weight', 'cls.seq_relationship.bias']
- This IS expected if you are initializing BertForSequenceClassification from the checkpoint of a model trained on another task or with another architecture (e.g. initializing a BertForSequenceClassification model from a BertForPreTraining model).
- This IS NOT expected if you are initializing BertForSequenceClassification from the checkpoint of a model that you expect to be exactly identical (initializing a BertForSequenceClassification model from a BertForSequenceClassification model).
[WARNING|modeling_utils.py:1170] 2021-10-02 06:53:37,781 >> Some weights of BertForSequenceClassification were not initialized from the model checkpoint at cl-tohoku/bert-base-japanese-whole-word-masking and are newly initialized: ['classifier.weight', 'classifier.bias']
You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference.
100% 3/3 [00:00<00:00, 6.14ba/s]
100% 1/1 [00:00<00:00, 7.77ba/s]
10/02/2021 06:53:39 - INFO - __main__ - Sample 456 of the training set: {'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'input_ids': [2, 9680, 21436, 28589, 472, 19366, 9594, 1754, 35, 6006, 28645, 10622, 14, 14930, 25910, 18920, 3723, 28, 6, 1532, 35, 12590, 9, 36, 5342, 16, 80, 38, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'label': 1, 'sentence': '【Sports Watch】妻・SHIHOが凄艶ヌード披露も、夫・秋山は「聞いてない」', 'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}.
10/02/2021 06:53:39 - INFO - __main__ - Sample 102 of the training set: {'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'input_ids': [2, 63, 2000, 623, 6234, 7875, 29182, 17489, 6848, 65, 5, 612, 11, 2461, 104, 14, 16089, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'label': 2, 'sentence': '『劇場版 FAIRY TAIL』の一部を原作者が暴露', 'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}.
10/02/2021 06:53:39 - INFO - __main__ - Sample 1126 of the training set: {'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'input_ids': [2, 4623, 2710, 5, 3245, 21324, 237, 4158, 2720, 14, 690, 315, 40, 398, 971, 19, 126, 5, 28404, 11, 1174, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'label': 0, 'sentence': '進む資料のデジタルアーカイブ化\u3000国会図書館が明治時代から昭和27年までの官報を公開', 'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}.
[INFO|trainer.py:483] 2021-10-02 06:53:48,144 >> The following columns in the training set don't have a corresponding argument in `BertForSequenceClassification.forward` and have been ignored: sentence.
[INFO|trainer.py:483] 2021-10-02 06:53:48,145 >> The following columns in the evaluation set don't have a corresponding argument in `BertForSequenceClassification.forward` and have been ignored: sentence.
[INFO|trainer.py:946] 2021-10-02 06:53:48,352 >> ***** Running training *****
[INFO|trainer.py:947] 2021-10-02 06:53:48,352 >> Num examples = 2114
[INFO|trainer.py:948] 2021-10-02 06:53:48,352 >> Num Epochs = 10
[INFO|trainer.py:949] 2021-10-02 06:53:48,352 >> Instantaneous batch size per device = 32
[INFO|trainer.py:950] 2021-10-02 06:53:48,353 >> Total train batch size (w. parallel, distributed & accumulation) = 32
[INFO|trainer.py:951] 2021-10-02 06:53:48,353 >> Gradient Accumulation steps = 1
[INFO|trainer.py:952] 2021-10-02 06:53:48,353 >> Total optimization steps = 670
{'loss': 0.2883, 'learning_rate': 1.701492537313433e-05, 'epoch': 1.49}
{'loss': 0.0415, 'learning_rate': 1.4029850746268658e-05, 'epoch': 2.99}
{'loss': 0.0058, 'learning_rate': 1.1044776119402986e-05, 'epoch': 4.48}
{'loss': 0.0024, 'learning_rate': 8.059701492537314e-06, 'epoch': 5.97}
{'loss': 0.0019, 'learning_rate': 5.074626865671642e-06, 'epoch': 7.46}
75% 500/670 [09:48<03:22, 1.19s/it][INFO|trainer.py:1558] 2021-10-02 07:03:37,211 >> Saving model checkpoint to output/checkpoint-500
[INFO|configuration_utils.py:314] 2021-10-02 07:03:37,212 >> Configuration saved in output/checkpoint-500/config.json
[INFO|modeling_utils.py:837] 2021-10-02 07:03:38,494 >> Model weights saved in output/checkpoint-500/pytorch_model.bin
[INFO|tokenization_utils_base.py:1896] 2021-10-02 07:03:38,495 >> tokenizer config file saved in output/checkpoint-500/tokenizer_config.json
[INFO|tokenization_utils_base.py:1902] 2021-10-02 07:03:38,495 >> Special tokens file saved in output/checkpoint-500/special_tokens_map.json
{'loss': 0.0015, 'learning_rate': 2.08955223880597e-06, 'epoch': 8.96}
100% 670/670 [13:13<00:00, 1.13it/s][INFO|trainer.py:1129] 2021-10-02 07:07:01,701 >>

Training completed. Do not forget to share your model on huggingface.co/models =)


{'train_runtime': 793.3481, 'train_samples_per_second': 0.845, 'epoch': 10.0}
100% 670/670 [13:13<00:00, 1.18s/it]
[INFO|trainer.py:1558] 2021-10-02 07:07:02,143 >> Saving model checkpoint to output/
[INFO|configuration_utils.py:314] 2021-10-02 07:07:02,144 >> Configuration saved in output/config.json
[INFO|modeling_utils.py:837] 2021-10-02 07:07:03,410 >> Model weights saved in output/pytorch_model.bin
[INFO|tokenization_utils_base.py:1896] 2021-10-02 07:07:03,411 >> tokenizer config file saved in output/tokenizer_config.json
[INFO|tokenization_utils_base.py:1902] 2021-10-02 07:07:03,411 >> Special tokens file saved in output/special_tokens_map.json
[INFO|trainer_pt_utils.py:656] 2021-10-02 07:07:03,442 >> ***** train metrics *****
[INFO|trainer_pt_utils.py:661] 2021-10-02 07:07:03,442 >> epoch = 10.0
[INFO|trainer_pt_utils.py:661] 2021-10-02 07:07:03,442 >> init_mem_cpu_alloc_delta = 1MB
[INFO|trainer_pt_utils.py:661] 2021-10-02 07:07:03,442 >> init_mem_cpu_peaked_delta = 0MB
[INFO|trainer_pt_utils.py:661] 2021-10-02 07:07:03,442 >> init_mem_gpu_alloc_delta = 422MB
[INFO|trainer_pt_utils.py:661] 2021-10-02 07:07:03,442 >> init_mem_gpu_peaked_delta = 0MB
[INFO|trainer_pt_utils.py:661] 2021-10-02 07:07:03,443 >> train_mem_cpu_alloc_delta = 0MB
[INFO|trainer_pt_utils.py:661] 2021-10-02 07:07:03,443 >> train_mem_cpu_peaked_delta = 94MB
[INFO|trainer_pt_utils.py:661] 2021-10-02 07:07:03,443 >> train_mem_gpu_alloc_delta = 1324MB
[INFO|trainer_pt_utils.py:661] 2021-10-02 07:07:03,443 >> train_mem_gpu_peaked_delta = 3394MB
[INFO|trainer_pt_utils.py:661] 2021-10-02 07:07:03,443 >> train_runtime = 793.3481
[INFO|trainer_pt_utils.py:661] 2021-10-02 07:07:03,443 >> train_samples = 2114
[INFO|trainer_pt_utils.py:661] 2021-10-02 07:07:03,443 >> train_samples_per_second = 0.845
10/02/2021 07:07:03 - INFO - __main__ - *** Evaluate ***
[INFO|trainer.py:483] 2021-10-02 07:07:03,557 >> The following columns in the evaluation set don't have a corresponding argument in `BertForSequenceClassification.forward` and have been ignored: sentence.
[INFO|trainer.py:1775] 2021-10-02 07:07:03,559 >> ***** Running Evaluation *****
[INFO|trainer.py:1776] 2021-10-02 07:07:03,559 >> Num examples = 529
[INFO|trainer.py:1777] 2021-10-02 07:07:03,559 >> Batch size = 8
100% 67/67 [00:07<00:00, 9.09it/s]
[INFO|trainer_pt_utils.py:656] 2021-10-02 07:07:11,070 >> ***** eval metrics *****
[INFO|trainer_pt_utils.py:661] 2021-10-02 07:07:11,070 >> epoch = 10.0
[INFO|trainer_pt_utils.py:661] 2021-10-02 07:07:11,070 >> eval_accuracy = 0.9698
[INFO|trainer_pt_utils.py:661] 2021-10-02 07:07:11,070 >> eval_loss = 0.1554
[INFO|trainer_pt_utils.py:661] 2021-10-02 07:07:11,070 >> eval_mem_cpu_alloc_delta = 0MB
[INFO|trainer_pt_utils.py:661] 2021-10-02 07:07:11,071 >> eval_mem_cpu_peaked_delta = 0MB
[INFO|trainer_pt_utils.py:661] 2021-10-02 07:07:11,071 >> eval_mem_gpu_alloc_delta = 0MB
[INFO|trainer_pt_utils.py:661] 2021-10-02 07:07:11,071 >> eval_mem_gpu_peaked_delta = 33MB
[INFO|trainer_pt_utils.py:661] 2021-10-02 07:07:11,071 >> eval_runtime = 7.3979
[INFO|trainer_pt_utils.py:661] 2021-10-02 07:07:11,071 >> eval_samples = 529
[INFO|trainer_pt_utils.py:661] 2021-10-02 07:07:11,071 >> eval_samples_per_second = 71.507
CPU times: user 6.09 s, sys: 875 ms, total: 6.96 s
Wall time: 14min

14分ほどで終了しました。

学習状況の確認

TensorBoardで学習の状況を確認します。

runフォルダに出力されている統計情報を可視化します。

[Google Colaboratory]

1
2
3
# 学習状況の確認
%load_ext tensorboard
%tensorboard --logdir runs

[実行結果]

損失(loss)が0に収束しているので、きちんと学習できていることが分かります。

損失は正解値と推論値の差になります。学習はこの損失の最小化を目的としています。

テキスト分類の推論

テキスト分類の推論を行います。

textに推論対象の文章を設定します。

[Google Colaboratory]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import torch
from transformers import BertJapaneseTokenizer, AutoModelForSequenceClassification

# トークナイザーとモデルの準備
tokenizer = BertJapaneseTokenizer.from_pretrained('cl-tohoku/bert-base-japanese-whole-word-masking')
model = AutoModelForSequenceClassification.from_pretrained('output/')

# テキスト
text = "Win11配布開始"

# テキストをテンソルに変換
input = tokenizer.encode(text, return_tensors='pt')

# 推論
labels = ['IT', 'スポーツ', '映画']
model.eval()
with torch.no_grad():
outputs = model(input)[0]
print(labels[torch.argmax(outputs)])

[実行結果]

1
IT

「Win11配布開始」ITであることが正しく推論できています。


次は「阪神快勝!」を推論してみます。

[Google Colaboratory]

1
2
3
4
5
6
7
8
9
10
11
12
# テキスト
text = "阪神快勝!"

# テキストをテンソルに変換
input = tokenizer.encode(text, return_tensors='pt')

# 推論
labels = ['IT', 'スポーツ', '映画']
model.eval()
with torch.no_grad():
outputs = model(input)[0]
print(labels[torch.argmax(outputs)])

[実行結果]

1
スポーツ

問題なくスポーツと推論できました。


最後に「全米が泣いた」を推論してみます。

[Google Colaboratory]

1
2
3
4
5
6
7
8
9
10
11
12
# テキスト
text = "全米が泣いた"

# テキストをテンソルに変換
input = tokenizer.encode(text, return_tensors='pt')

# 推論
labels = ['IT', 'スポーツ', '映画']
model.eval()
with torch.no_grad():
outputs = model(input)[0]
print(labels[torch.argmax(outputs)])

[実行結果]

1
映画

映画と正しく推論できました。

Transformers(8) - テキスト分類①学習データと検証データの生成

テキスト分類を2回に分けて説明していきます。

今回は、データセットをダウンロードし、そのデータから学習データと検証データを生成します。

データセットのダウンロード

まずlivedoor ニュースコーパスからニュース記事のデータセットをダウンロードします。

[Google Colaboratory]

1
!wget https://www.rondhuit.com/download/ldcc-20140209.tar.gz

[実行結果]

1
2
3
4
5
6
7
8
9
10
--2021-10-01 20:42:32--  https://www.rondhuit.com/download/ldcc-20140209.tar.gz
Resolving www.rondhuit.com (www.rondhuit.com)... 59.106.19.174
Connecting to www.rondhuit.com (www.rondhuit.com)|59.106.19.174|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 8855190 (8.4M) [application/x-gzip]
Saving to: ‘ldcc-20140209.tar.gz’

ldcc-20140209.tar.g 100%[===================>] 8.44M 2.99MB/s in 2.8s

2021-10-01 20:42:37 (2.99 MB/s) - ‘ldcc-20140209.tar.gz’ saved [8855190/8855190]

データセットの解凍

ダウンロードした圧縮ファイル(ldcc-20140209.tar.gz)を解凍します。

[Google Colaboratory]

1
!tar xzvf ldcc-20140209.tar.gz

textディレクトリが作成され、その中に各ジャンル別にニュース記事のテキストファイルがたくさん解凍されます。

学習データと検証データの生成

解凍したデータセットから、学習データ(dev.csv)検証データ(train.csv)を生成します。

[Google Colaboratory]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import os
import pandas as pd

# タイトルリストの取得
def get_title_list(path):
title_list = []
filenames = os.listdir(path)
for filename in filenames:
# ファイルの読み込み
with open(path+filename) as f:
title = f.readlines()[2].strip()
title_list.append(title)
return title_list

# データフレームの作成
df = pd.DataFrame(columns=['label', 'sentence'])
title_list = get_title_list('text/it-life-hack/')
for title in title_list:
df = df.append({'label':0 , 'sentence':title}, ignore_index=True)
title_list = get_title_list('text/sports-watch/')
for title in title_list:
df = df.append({'label':1 , 'sentence':title}, ignore_index=True)
title_list = get_title_list('text/movie-enter/')
for title in title_list:
df = df.append({'label':2 , 'sentence':title}, ignore_index=True)

# シャッフル
df = df.sample(frac=1)

# CSVファイルの保存
num = len(df)
df[:int(num*0.8)].to_csv('train.csv', sep=',', index=False)
df[int(num*0.8):].to_csv('dev.csv', sep=',', index=False)

正常に処理が実行されると、学習データ(dev.csv)検証データ(train.csv)が作成されます。

次回は、この学習データと検証データを使ってテキスト分類の学習と推論を行います。

Transformers(7) - トークナイザー

今回は、トークナイザーを使ってみます。

(Transformersのインストールは完了している想定となります。)

トークナイザー

トークナイザーは自然言語の入力テキストを深層学習モデルの入力データに変換する処理です。

深層学習モデルの入力データはテンソルと呼ばれる多次元配列になります。

トークナイザーの準備

AutoTokenizerクラスの作成時に‘bert-base-cased’を指定すると、BERTモデル用のトークナイザーとなります。

[Google Colaboratory]

1
2
3
4
from transformers import AutoTokenizer

# トークナイザーの準備
tokenizer = AutoTokenizer.from_pretrained('bert-base-cased')

[実行結果]

1
2
3
4
5
6
7
8
Downloading: 100%
570/570 [00:00<00:00, 13.3kB/s]
Downloading: 100%
213k/213k [00:00<00:00, 563kB/s]
Downloading: 100%
436k/436k [00:00<00:00, 587kB/s]
Downloading: 100%
29.0/29.0 [00:00<00:00, 725B/s]

自然言語テキストをテンソルにエンコード

tokenizer.encodeを使うと、自然言語テキストをテンソルにエンコードすることができます。

[Google Colaboratory]

1
2
3
# 自然言語テキストをテンソルにエンコード
input = tokenizer.encode("Hello, I'm a single sentence!", return_tensors='pt', max_length=512, truncation=True)
print(input)

[実行結果]

1
tensor([[ 101, 8667,  117,  146,  112,  182,  170, 1423, 5650,  106,  102]])

テンソルを自然言語テキストにデコード

tokenizer.decodeを使うと、テンソルを自然言語テキストにデコードすることができます。

[Google Colaboratory]

1
2
# テンソルを自然言語テキストにデコード
print(tokenizer.decode(input.numpy()[0]))

[実行結果]

1
[CLS] Hello, I'm a single sentence! [SEP]

複数の自然言語テキストをテンソルにエンコード

tokenizer.encode_plusを使うと、複数の自然言語テキストをテンソルにエンコードすることができます。

[Google Colaboratory]

1
2
3
# 複数の自然言語テキストをテンソルにエンコード
inputs = tokenizer.encode_plus('This is a question', 'This is a context!', return_tensors='pt')
print(inputs)

戻り値の意味は次の通りです。

  • input_ids
    トークンIDの配列
  • token_type_ids
    複数の文章を判定するバイナリマスク
  • attention_mask
    パディング時に埋め込み文字かどうかを判定するバイナリマスク

[実行結果]

1
2
3
{'input_ids': tensor([[ 101, 1188, 1110,  170, 2304,  102, 1188, 1110,  170, 5618,  106,  102]]), 
'token_type_ids': tensor([[0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1]]),
'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])}

テンソルを複数の自然言語テキストにデコード

tokenizer.decodeを使うと、テンソルを複数の自然言語テキストにデコードすることができます。

[Google Colaboratory]

1
2
# テンソルを複数の自然言語テキストにデコード
print(tokenizer.decode(inputs['input_ids'].numpy()[0]))

[実行結果]

1
[CLS] This is a question [SEP] This is a context! [SEP]

BERTのスペシャルトークンとしては、次のようなものがあります。

  • [CLS]
    文頭に埋め込むトークン(classification)
  • [SEP]
    文と文の間に埋め込むトークン(separator)
  • [PAD]
    指定された長さに満たさない文を埋めるトークン(padding)
  • [MASK]
    マスクしたトークン(mask)

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×