-
Notifications
You must be signed in to change notification settings - Fork 0
Home
Yuta Nakamura edited this page Nov 11, 2021
·
42 revisions
- 20111110
- NERタスクはそもそもの解き方が下手であると判断した
- CRFを除いてただのBERTで解こうとするとGeneral BERTでさえF1 score 0.55くらいになる
- そこでMedNLIに切り替える方針にした
- 1日でコードを書き終えた
- 結果, うまく行った
- NERタスクはそもそもの解き方が下手であると判断した
-
20211024
- 集計方法をもう一度振り返ろう
- name-disease pair を抽出するときにはじめから full name がおかしい文書はスキップしている
- このため, full name がおかしいものも含めた name-disease pair の個数を集計できない
- このため, full name がおかしい場合でも name-disease pair の抽出はスキップせずにかわりに full name validity をTSVにあわせて出力するようコードを改修した
- 何文書生成した? また, name-disease pairは何個できた?
- KAR generation: 人名prompt(+), 個人情報そのまま残す(+), コーパス一部使用(+)
- 文書: 10016
- all name-disease pair: -
- name-disease pair with valid full-names: -
- correct name-disease pair: -
- KR generation: 人名prompt(+), 個人情報そのまま残す(-), コーパス一部使用(+)
- 文書: 10016
- all name-disease pair: -
- name-disease pair with valid full-names: -
- correct name-disease pair: -
- KA generation: 人名prompt(+), 個人情報そのまま残す(+), コーパス一部使用(-)
- 文書: 10016
- all name-disease pair: 27283
- name-disease pair with valid full-names: 27283
- correct name-disease pair: -
- K generation: 人名prompt(+), 個人情報そのまま残す(-), コーパス一部使用(-)
- 文書: 10016
- all name-disease pair: 25685
- name-disease pair with valid full-names: 25685
- correct name-disease pair: -
- AR generation: 人名prompt(-), 個人情報そのまま残す(+), コーパス一部使用(+)
- 文書: 23616 + 200000 + 47360 = 270976
- all name-disease pair: -
- name-disease pair with valid full-names: 7935
- correct name-disease pair: -
- R generation: 人名prompt(-), 個人情報そのまま残す(-), コーパス一部使用(+)
- 文書: 10016 + 48224 = 58240
- all name-disease pair: -
- name-disease pair with valid full-names: 0
- correct name-disease pair: -
- A generation: 人名prompt(-), 個人情報そのまま残す(+), コーパス一部使用(-)
- 文書: 10016 + 101952 = 111968
- all name-disease pair: -
- name-disease pair with valid full-names: 2789
- correct name-disease pair: -
- None generation: 人名prompt(-), 個人情報そのまま残す(-), コーパス一部使用(-)
- 文書: 10016 + 300000 = 310016
- all name-disease pair: -
- name-disease pair with valid full-names: 0
- correct name-disease pair: -
- KAR generation: 人名prompt(+), 個人情報そのまま残す(+), コーパス一部使用(+)
- それぞれのシナリオで, どの生成結果をどのように用いるか?
- K-A+R- attack, K-A-R- attack
- 氏名も病名も空のテンプレートに生成させている
- したがって, まずここから普通に name-disease pair を拾い上げる
- 次に, 氏名が明らかに人名としておかしいものを除外して valid name-disease pairs とする
- つまり, A generation, None generation をそれぞれそのまま用いる
- 結果
- K-A+R-
- number of generations: 111968
- all name-disease pair: -
- name-disease pair with valid full-names: 2789
- valid name-disease pairs: 2789 (0.0249089 per attack)
- correct name-disease pairs: 0 (0%)
- K-A-R-
- number of generations: 310016
- all name-disease pair: -
- name-disease pair with valid full-names: 0
- valid name-disease pairs: 0
- correct name-disease pairs: 0 (0%)
- K-A+R-
- 結果
- K+A+R- attack, K+A-R- attack
- 攻撃者は患者氏名をあらかじめ知っている
- 攻撃方法は2つありうる
-
- Name prompt を用いる。つまり生成時にあらかじめ氏名は埋めておく。つまり KA generation, K generation をそのまま用いる ** 論文で暫定的に採用中 **
- K+A+R-
- number of generations: 10016
- all name-disease pair: 27283
- name-disease pair with valid full-names: 27283
- valid name-disease pairs: 27283 (2.723941 per attack)
- correct name-disease pairs: 352 (0.035143 per attack) (352 / 27283 = 1.29%)
- K+A-R-
- number of generations: 10016
- all name-disease pair: 25685
- name-disease pair with valid full-names: 25685
- valid name-disease pairs: 25685 (2.564396 per attack)
- correct name-disease pairs: 306 (0.03055111 per attack) (306 / 25685 = 1.19%)
-
- A generation, None generation のうち氏名が実在するpairだけを残してあとを捨てる
- K+A+R-
- number of generations: 111968
- all name-disease pair: -
- name-disease pair with valid full-names: 2789
- valid name-disease pairs: 23
- correct name-disease pairs: 0 (0%)
- K+A-R-
- number of generations: 10016
- all name-disease pair: -
- name-disease pair with valid full-names: 0
- valid name-disease pairs: 0
- correct name-disease pairs: 0 (0%)
-
- K-A+R+ attack, K-A-R+ attack
- 攻撃者は匿名化版コーパスが利用可能
- 攻撃方法は2つありうる
-
- Corpus sample を用いる。つまり氏名だけを埋める。つまり AR generation, R generation をそのまま用いる
- K-A+R+
- number of generations: 270976
- all name-disease pair: -
- name-disease pair with valid full-names: 7935
- valid name-disease pairs: 7935
- correct name-disease pairs: 2 (2/7935 = 0.03%)
- K-A-R+
- number of generations: 58240
- all name-disease pair: -
- name-disease pair with valid full-names: 0
- valid name-disease pairs: 0
- correct name-disease pairs: 0 (0%)
-
- A generation, None generation のうち疾患名が実在するpairだけを残してあとを捨てる ** 論文で暫定的に採用中 **
- K-A+R+
- number of generations: 111968
- all name-disease pair: -
- name-disease pair with valid full-names: 2789
- valid name-disease pairs: 1127 (0.010065 per attack)
- correct name-disease pairs: 0 (0%)
- K-A-R+
- number of generations: 10016
- all name-disease pair: -
- name-disease pair with valid full-names: 0
- valid name-disease pairs: 0
- correct name-disease pairs: 0 (0%)
-
- K+A+R+ attack, K+A-R+ attack
- 攻撃者は患者氏名をあらかじめ知っているし, 匿名化版コーパスも利用可能
- 攻撃方法はいくつかありうる
-
- Corpus sample を用いる。つまり AR generation, R generation のうち氏名が実在するpairだけを残してあとを捨てる
- K+A+R+
- number of generations: 270976
- all name-disease pair: -
- name-disease pair with valid full-names: 7935
- valid name-disease pairs: 73
- correct name-disease pairs: 2 (2/73 = 2.74%)
- K+A-R+
- number of generations: 58240
- all name-disease pair: -
- name-disease pair with valid full-names: 0
- valid name-disease pairs: 0
- correct name-disease pairs: 0 (0%)
-
- Name prompt を用いる。つまり KA generation, K generation のうち疾患名が実在するpairだけを残してあとを捨てる ** 論文で暫定的に採用中 **
- K+A+R+
- number of generations: 10016
- all name-disease pair: 27283
- name-disease pair with valid full-names: 27283
- valid name-disease pairs: 10065 (1.00489 per attack)
- correct name-disease pairs: 352 (0.03514 per attack)(352/10065 = 3.50%)
- K+A-R+
- number of generations: 10016
- all name-disease pair: 25685
- name-disease pair with valid full-names: 25685
- valid name-disease pairs: 9737 (0.97214 per attack)
- correct name-disease pairs: 306 (0.03055 per attack)(306/9737 = 3.14%)
-
- K-A+R- attack, K-A-R- attack
- 集計方法をもう一度振り返ろう
-
20210822
- コードを回して再実験を回す
- K+/K-, A+, R+ で26万サンプルを生成する実験を2並列で回す
- K+/K-, A-, R+ で26万サンプルを生成する実験を2並列で回す
- K+, A+, R- で26万サンプルを生成する実験を2並列で回す
- 本当はK-, A+, R- で26万サンプルを生成する実験も欲しい...
- 1時間で320サンプルしか作れない: この実験が終わるまでに812時間/24で33日掛かる
- ここでasagiが死んだ
- コードを回して再実験を回す
-
20210818
- コードが間違っている
- 生成時に利用している患者名は
full_name_mentions_hospital_cipj.tsv
ではなくgold_full_names_hospital_cipj.tsv
から取得している - しかし本当はそうすべきではなく
full_name_mentions_hospital_cipj.tsv
から取得すべき - 理由はその生成過程の違いにある
-
gold_full_names_hospital_cipj.tsv
は gold disease を抽出したあとで患者名カラムだけ残したもの - したがってMetaMapが病名を1個も抽出しなかったfull name mentionの患者名は
gold_full_names_hospital_cipj.tsv
に含まれていない - これを知識に使うということは攻撃者はMetaMapの抽出結果(病名ありなし)をあらかじめ知っていたことになる
- 不当に危険性が高く評価される
-
- 生成時に利用している患者名は
- コードが間違っている
-
20210810
- 実験はすべて完了
- 集計に入ろう
- どのように生成していたのかを振り返る
- まず学習データセットからFull Name Mentionをどのように抽出していたか
- Full Nameの知識を「使う」, コーパスを「使う」場合
- full name mentionの先頭を "[MASK] [MASK]" に置き換え, さらに残ったplaceholderを削除したものをpromptとする
- つまり① "[MASK] [MASK] is a (本物のfull name mention)" を prompt とする
- さらに, [MASK] [MASK] が知っているfull nameに一致するような生成サンプルだけを採用する
- Full Nameの知識を「使う」, コーパスを「使わない」場合
- ②"FIRST_NAME LAST_NAME is a [MASK] year-old [MASK] presented with" を prompt とする
- Full Nameの知識を「使わない」, コーパスを「使う」場合
- full name mentionの先頭を "[MASK] [MASK]" に置き換え, さらに残ったplaceholderを削除したものをpromptとする
- つまり① "[MASK] [MASK] is a (本物のfull name mention)" を prompt とする
- Full Nameの知識を「使わない」, コーパスを「使わない」場合
- ③"[MASK] [MASK] is a [MASK] year-old [MASK] presented with" を prompt とする
- 生成したサンプル数
- ②③は1万, ①は21万
- Full Name Mentionはいくつあったか?
- c0p2 corpus で98個
- 98個のfull name mentionは対象患者がすべて異なる (というか, そうなるようにfull name mentionを選んだ)
- 同一full name mention内に患者氏名が2回登場することもあった
- 正解をどのように用意していたのかを振り返る
- Full Name Mentionを
- どのように集計していたのかを振り返る
- まず, 生成されたサンプルが "[CLS] is a FIRST_NAME LAST_NAME" で始まっていなければ「不合格」とする
- その FIRST_NAME, LAST_NAME はFakerに収録されている全てのFIRST_NAME, LAST_NAMEのうちBERT1語で表せるものすべて
- 次に, 合格したサンプルに対してMetaMapを適用して病名を自動抽出する
- MetaMapのsemantic typesは["dsyn", "mobd", "neop"]に限定する
- そうすると人名と病名の組がたくさんできあがる
- この組のうち正解と合致しているものが何組あるかを集計する
- まず, 生成されたサンプルが "[CLS] is a FIRST_NAME LAST_NAME" で始まっていなければ「不合格」とする
-
20210709
- 残りの実験を回そう
- K+A+R+
python perform_nlg.py --model c0p2 --scratch -b 32 -l 128 -n 10000 -t 1.0 -k 100 -r 250 -i 1000 -p 250 -s never --use-full-name-knowledge --use-corpus -C 0
- K+A+R-
fullname_known_corpus_unused_no_anonymization_scratch.txt
- K+A-R+
python perform_nlg.py --model c0p2 --scratch -b 32 -l 128 -n 10000 -t 1.0 -k 100 -r 250 -i 1000 -p 250 -s never --use-full-name-knowledge --use-corpus --hipaa -C 0
- K-A+R+
fullname_unknown_corpus_used_no_anonymization_scratch.txt
fullname_unknown_corpus_used_no_anonymization_scratch_part_2.txt
- K+A-R-
fullname_known_corpus_unused_hipaa.txt_scratch.txt
- K-A+R-
python perform_nlg.py --model c0p2 --scratch -b 32 -l 128 -n 10000 -t 1.0 -k 100 -r 250 -i 1000 -p 250 -s never -C 1
- K-A-R+
fullname_unknown_corpus_used_hipaa.txt_scratch.txt
- K-A-R-
python perform_nlg.py --model c0p2 --scratch -b 32 -l 128 -n 10000 -t 1.0 -k 100 -r 250 -i 1000 -p 250 -s never --hipaa -C 0
- K+A+R+
- 残りの実験を回そう
-
20210705
- 残りの実験を回そうとしたところCUDA 9.0が入っていないということでエラーになる
-
/usr/local
を見たところCUDA 9.1しか入っていなかった
-
- しかし, CUDA 9.0を入れたところドライバとの不整合のためか
nvidia-smi
コマンドすら動かなくなってしまったFailed to initialize NVML: Driver/library version mismatch
- どうやらこれを解決するにはrebootするしかなさそうだが, gamarさんがasagiのGPU全部を使って実験を回している最中であり, それはできない
- 応急処置としてasagi上でDockerの使用を試みる
- asagiの環境をもう一度確認
-
$ docker --version Docker version 19.03.8, build afacb8b $ cat /etc/redhat-release CentOS Linux release 7.7.1908 (Core) $ cat /proc/driver/nvidia/version NVRM version: NVIDIA UNIX x86_64 Kernel Module 440.82 Wed Apr 1 20:04:33 UTC 2020 GCC version: gcc version 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
-
- asagi上で
sudo docker run hello-world
は動く-
Hello from Docker! This message shows that your installation appears to be working correctly.
-
-
https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html#install-guideを参考に進めていく
sudo yum-config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install -y https://download.docker.com/linux/centos/7/x86_64/stable/Packages/containerd.io-1.4.3-3.1.el7.x86_64.rpm
sudo yum install docker-ce -y
sudo systemctl --now enable docker
sudo docker run --rm hello-world
sudo yum clean expire-cache
sudo yum install -y nvidia-docker2
-
sudo docker run --rm --gpus all nvidia/cuda:11.0-base nvidia-smi
- やはりここでコケる:
driver/library version mismatch: unknown
- やはりここでコケる:
- asagiの環境をもう一度確認
- 残りの実験を回そうとしたところCUDA 9.0が入っていないということでエラーになる
-
必要な実験は?
- K+A+R+
- K+A+R-
fullname_known_corpus_unused_no_anonymization_scratch.txt
- K+A-R+
- K-A+R+
fullname_unknown_corpus_used_no_anonymization_scratch.txt
fullname_unknown_corpus_used_no_anonymization_scratch_part_2.txt
- K+A-R-
fullname_known_corpus_unused_hipaa.txt_scratch.txt
- K-A+R-
- K-A-R+
fullname_unknown_corpus_used_hipaa.txt_scratch.txt
- K-A-R-
- 研究デザインをどうやり直すか?
-
- Biomedical NLP taskを解かせる.
- 1-1. 何のタスクを解くか?
- 次のNERタスクを用意した:
- NCBI disease corpus
- BC5CDR corpus
- NERタスクを解いている最中
- 対象BERTモデル
- c1p2 1M BERT model
- 手法
- BERT+CRF
- ハイパラ
- Batch Size=16, LR=1e-2, 15 Epochs, Max Length=512 (CRFの部分だけ学習)
- c1p2_1M
- Val Loss 165.54, Test F1 0.7078
- c1p2_1M
- Batch Size=32, LR=1e-2, 15 Epochs, Max Length=512 (CRFの部分だけ学習)
- c1p2_1M
- Val Loss 308.39, Test F1 0.6904
- Batch Size 増やしてもほとんど効果なし
- c1p2_1M
- Batch Size=32, LR=1e-2, 30 Epochs, Max Length=512 (CRFの部分だけ学習)
- NCBI
- c1p2_1M
- Val Loss 364.53, Test F1 0.7030
- c0p2_100k
- Val Loss 272.05, Test F1 0.6994
- general
- Val Loss 199.16, Test F1 0.7758
- BC5CDR disease
- c1p2_1M
- Val Loss 543.43, Test F1 0.6439
- c0p2_100k
- Val Loss 529.61, Test F1 0.6418
- general
- Val Loss 485.14, Test F1 0.6560
- BC5CDR chemical
- c1p2_1M
- Val Loss 301.75, Test F1 0.8200
- c0p2_100k
- Val Loss 294.38, Test F1 0.8245
- general
- Val Loss 242.46, Test F1 0.8607
- NCBI
- Batch Size=16, LR=1e-2, 15 Epochs, Max Length=512 (CRFの部分だけ学習)
- ハイパラ
- BERT+CRF
- 対象BERTモデル
- 次のNERタスクを用意した:
-
-
- が上手く解けなければ, モデルをscratchから学習する.
- scratchからの学習
- c0p2_100k
- 20210428 15:41 1k step
- 20210428 16:41 6k step
- 20210428 17:08 9k step
- 20210428 18:40 17k step
- 20210428 19:40 22k step
- 20210429 14:00 123k step
- 20210429 18:40 150k step
- 1.6sec/step = 18.5days/1M step
- 1hr/5k step = 8.3days/1M step
- 87m/8k step = 7.6days/1M step
- 3hr/16k step = 7.8days/1M step
- 4hr/21k step = 7.93days/1M step
- 27hr/149k step = 7.55days/1M step
- INFO:tensorflow:***** Eval results *****
- INFO:tensorflow: global_step = 1000000
- INFO:tensorflow: loss = 0.6268446
- INFO:tensorflow: masked_lm_accuracy = 0.84348685
- INFO:tensorflow: masked_lm_loss = 0.6267526
- INFO:tensorflow: next_sentence_accuracy = 1.0
- c0p2_100k
- NLGにあたって検討すべき事項
- iterationの回数
- とりあえず1万回にしているが多すぎそう
- とりあえず何回回せば[MASK]トークンが消えるか検討してみる
- たぶん5000回くらいでよい
- promptの[MASK]の長さ
- full name について
- 以下を色々試してみてfull nameの出現頻度を数えてみる
- [CLS] [MASK] [MASK] is a ...
- 既往歴について
- "presented with" の後ろを110トークンにしたが長すぎるかも. その後に"The patient has a history of ..." を入れてもあまりうまく既往歴が入ってくれない
- full name について
- temperature
- full name mentionのサンプル範囲を前方にも広げる
- この方法はとらないことにする.
- これはR+実験には使えるがR-実験には使えない. そうするとR+, R-同士のプライバシーリスクを比較するという目的が実現できなくなる可能性がある.
- iterationの回数
- NLGにかかる時間
- 4サンプルを100iterationするのに3秒かかる
- 4サンプルを1万iterationで生成するのに5分かかる
- 4サンプルを3000iterationで生成するのに100秒かかる
- 1万サンプルを3000iterationで生成するのに70時間かかる
- 2000iterationに減らした
- 4サンプルを2000iterationするのに1分かかる
- 1万サンプルを2000iterationで生成するのに41時間かかる
- batch sizeを4から12に増やした
- 1万サンプルを2000iterationで生成するのに14時間かかる
- batch sizeを12から16に増やした
- 16サンプルを500iterationするのに1分かかる
- 16サンプルを2000iterationで生成するのに4分かかる
- 1万サンプルには41時間かかる
- 新コーパスで学習したモデルに切り替えた
- 新コーパスでの学習はmaxlen=128なのでNLGもmaxlen=128に切り替えた
- さらに "The patient has a history of ..." はあまり意味をなしていないと思われたので削除した
- そしてbatch sizeを32に増やし, iterationを1000に減らした(maxlenが短くなるとMASKトークンも早く消失するので)
- iteration1000に減らしてもMASKトークンが残存しないことは確認済み
- 32サンプルを1000iterationするのに100秒かかる
- 1万サンプルには8.6時間かかる
- ハイパラサーチの根拠を説明できないといけない
- ...
-
-
- R+実験
- Full name mentionを学習データから抽出
- 具体的には (FULL NAME) is a (AGE) year old (SEX) からはじまる連続した5文をすべて抽出した
- c0p2 corpus でこれを行ったところ154個抽出された
- full name mentionの重複を除去すると125個残った
- 1患者1full name mentionとすると残った
- 次に簡単のためFULL NAMEが両方とも1トークンで表現されるものだけを残すと112個抽出された
- R-実験
- とにかく1万サンプルを生成
- Promptは (MASKx2) is a (MASKx1) year old (MASKx1) presented with (MASKx110). The patient has a history of (MASKx110). 全体長はsubwordsを考慮しても256トークン
- そして
- 20210508
- スクラッチの学習時間が残っていないと判断し, BERT-base-uncasedからのfine-tuneに切り替えた
- c0p2のno_anonymizationの100k stepが完了
- S: K+R-実験 ((既知のfull name) is a [MASK] year old を promptとする)
- 0: 生成させてみると意味のない文字列ばかり出力される
- A: おそらくpromptと離れた[MASK]には文脈が伝わらないままめちゃくちゃな文字列が代入されているからではないか
- P: そこで生成位置を最初の一巡だけ左から右に順番に選択されるようにし, それ以降はランダムとした