Colab + PyTorch Lightning + Comet ML

背景

Kaggle の上位ランカーが PyTorch Lightning について言及していたの試してみる。同様に Comet ML も。Kaggle の試行錯誤を Colab (or Colab Pro) に移行できるかもあわせて検討する。

ToDO

以下淡々と ToDOをこなしていきメモを残す。

Lightning 基礎

  • Lightning の transformers example を Colab 単体で動かす。
  • 上記の dataloader を少ないデータに改造 end to end で素早く回せるようにする。

Lightning training resume

Checkpointing によると2つ方法がある。

1つめ

Trainer の resume_from_checkpoint 引数で checkpoint のパスを指定する。

resume = False
if resume:
  trainer = pl.Trainer(gpus=1,
                                    max_epochs=4,
                                    resume_from_checkpoint='lightning_logs/version_0/checkpoints/_ckpt_epoch_1.ckpt')  
else:
  !rm -rf lightning_logs/  
  trainer = pl.Trainer(gpus=1, max_epochs=2)

trainer.fit(bert_finetuner) 

まず最初の training 時には以下のようなログ。

Epoch 1: 100%|██████████| 4/4 [00:01<00:00,  2.22batch/s, avg_val_acc=0.2, batch_idx=2, gpu=0, loss=1.138, v_num=0, val_loss=1.12]
Epoch 2: 100%|██████████| 4/4 [00:29<00:00,  7.26s/batch, avg_val_acc=0.2, batch_idx=2, gpu=0, loss=1.084, v_num=0, val_loss=1.08]

次に resume すると

Epoch 2: 100%|██████████| 4/4 [00:01<00:00,  2.22batch/s, avg_val_acc=0.6, batch_idx=2, gpu=0, loss=0.992, v_num=1, val_loss=0.916]
Epoch 3: 100%|██████████| 4/4 [00:01<00:00,  2.34batch/s, avg_val_acc=0.6, batch_idx=2, gpu=0, loss=0.952, v_num=1, val_loss=0.844]
Epoch 4: 100%|██████████| 4/4 [00:05<00:00,  1.14s/batch, avg_val_acc=0.8, batch_idx=2, gpu=0, loss=0.911, v_num=1, val_loss=0.751]
Epoch 5: 100%|██████████| 4/4 [00:31<00:00,  7.86s/batch, avg_val_acc=1, batch_idx=2, gpu=0, loss=0.865, v_num=1, val_loss=0.659]

training をresumeできる。ただし Epoch 2 を2回やっているように見える。注意しないといけないのは dataloader は state が resume されるわけではないこと。なので shuffle 前提であるとどこかに書いてあった。

2つめ

experiment version 番号を使う方法。experiment version については、pytorch_lightning.loggers.tensorboard moduleの version 引数に説明がある。version は上記のversion_0 とか version_1 が自動で割り振られるをやめて特定の物を指定する。

コードは

from pytorch_lightning.logging.tensorboard import TensorBoardLogger
bert_finetuner = BertMNLIFinetuner()

resume = False # True

logger = TensorBoardLogger(save_dir='experiments', version=10)
if resume:
  trainer = pl.Trainer(gpus=1, max_epochs=5, logger=logger)
else:
  !rm -rf default/version_10/  
  trainer = pl.Trainer(gpus=1, max_epochs=2, logger=logger)
trainer.fit(bert_finetuner) 

Train 開始。

Epoch 1: 100%|██████████| 4/4 [00:02<00:00,  1.49batch/s, avg_val_acc=0, batch_idx=2, gpu=0, loss=1.122, v_num=10, val_loss=1.26]
Epoch 2: 100%|██████████| 4/4 [00:29<00:00,  7.35s/batch, avg_val_acc=0.2, batch_idx=2, gpu=0, loss=1.032, v_num=10, val_loss=1.18]

Train resume。

INFO:root:model and trainer restored from checkpoint: /content/default/version_10/checkpoints/_ckpt_epoch_1.ckpt
Epoch 2: 100%|██████████| 4/4 [00:01<00:00,  1.54batch/s, avg_val_acc=1, batch_idx=2, gpu=0, loss=0.844, v_num=10, val_loss=0.56]
Epoch 3:  75%|███████▌  | 3/4 [00:01<00:00,  1.54batch/s, avg_val_acc=1, batch_idx=2, gpu=0, loss=0.767, v_num=10, val_loss=0.56]
Epoch 3: 100%|██████████| 4/4 [00:02<00:00,  1.54batch/s, avg_val_acc=1, batch_idx=2, gpu=0, loss=0.767, v_num=10, val_loss=0.446]
Epoch 4: 100%|██████████| 4/4 [00:05<00:00,  1.54batch/s, avg_val_acc=1, batch_idx=2, gpu=0, loss=0.696, v_num=10, val_loss=0.356]
Epoch 5: 100%|██████████| 4/4 [00:31<00:00,  7.81s/batch, avg_val_acc=1, batch_idx=2, gpu=0, loss=0.619, v_num=10, val_loss=0.287]

こちらの方法が自動的に新しい version が振られることなく自然で使いやすいと思う。

Google Drive への保存

Colab はいつセッションが切れるか分からないので Google Drive に保存する。以下のようなコードで Google Drive がマウントされていない場合のみにマウント処理。

from google.colab import drive
from pathlib import Path

def mount_drive_if_necessary():
    drive_path = Path('/content/drive')
    if not drive_path.exists():
      drive.mount(str(drive_path))

mount_drive_if_necessary()

train のコードは

from pytorch_lightning.logging.tensorboard import TensorBoardLogger
bert_finetuner = BertMNLIFinetuner()

resume = True

save_root_path = Path('/content/drive/My Drive/kaggle/tf2.0')
logger = TensorBoardLogger(save_dir= save_root_path / 'logs', version=10, name='simple_bert')
if resume:
  trainer = pl.Trainer(gpus=1, max_epochs=5, logger=logger, default_save_path=save_root_path)
else:
  !rm -rf default/version_10/  
  trainer = pl.Trainer(gpus=1, max_epochs=2, logger=logger, default_save_path=save_root_path)

trainer.fit(bert_finetuner) 

実際の check points と log は以下のように保存される。

/content/drive/My Drive/kaggle/tf2.0
/content/drive/My Drive/kaggle/tf2.0/logs
/content/drive/My Drive/kaggle/tf2.0/logs/simple_bert
/content/drive/My Drive/kaggle/tf2.0/logs/simple_bert/version_10
/content/drive/My Drive/kaggle/tf2.0/logs/simple_bert/version_10/events.out.tfevents.1582691888.8883d33e5953.1505.0
/content/drive/My Drive/kaggle/tf2.0/logs/simple_bert/version_10/meta_tags.csv
/content/drive/My Drive/kaggle/tf2.0/logs/simple_bert/version_10/events.out.tfevents.1582692040.8883d33e5953.1505.1
/content/drive/My Drive/kaggle/tf2.0/simple_bert
/content/drive/My Drive/kaggle/tf2.0/simple_bert/version_10
/content/drive/My Drive/kaggle/tf2.0/simple_bert/version_10/checkpoints
/content/drive/My Drive/kaggle/tf2.0/simple_bert/version_10/checkpoints/_ckpt_epoch_1.ckpt
/content/drive/My Drive/kaggle/tf2.0/simple_bert/version_10/checkpoints/_ckpt_epoch_4.ckpt

ハイパーパラメータを checkpoint と同時に保存する

以下のような警告が出ているので調べる。

UserWarning: Did not find hyperparameters at model.hparams. Saving checkpoint without hyperparameters
  "Did not find hyperparameters at model.hparams. Saving checkpoint without"

hparams が checkpoint と一緒に保存されてうれしいのは load_from_checkpoint で load するとき。Trainer 経由で resume するときはその限りではない気がする。 ちなみに hparams はモデルで

class BertMNLIFinetuner(pl.LightningModule):

    def __init__(self, hparams):
        super(BertMNLIFinetuner, self).__init__()
        
        self.bert = bert
        self.W = nn.Linear(bert.config.hidden_size, 3)
        self.num_classes = 3
        self.hparams = hparams
        self.learning_rate = hparams.learning_rate

...snip...
hparams = Namespace(**{'learning_rate': 2e-05})

bert_finetuner = BertMNLIFinetuner(hparams)

こうすることで hparams が別ファイルとして保存される。

! cat tf2.0/logs/simple_bert/version_10/meta_tags.csv
key,value
learning_rate,2e-05

この hparams と comet.ml などの連携も調べなければいけない。

Comet ML

以下のように Trainer に CometLogger を渡せばOK。オフラインモードはインターネット接続がない環境向けなので使わない。

comet_logger = CometLogger(
    api_key='',
    workspace='higepon',
    project_name="simple-bert-test", # Optional
    experiment_name="my_experiment_name_long7",
    rest_api_key = '')

trainer = pl.Trainer(gpus=1, max_epochs=30, logger=comet_logger, default_save_path=save_root_path)

Code タブ

各 Experiment ごとにソースコードを紐付けることができる。そうすれば各バージョンごとに Diff がとれるようになる。Colab の場合以下のようにソースコードを Comet に送る。

code = ''
for cell_in in In:
  code += cell_in + '\n'

comet_logger.experiment.set_code(code)

f:id:higepon:20200227154801p:plain

Metrics を追加する

デフォルトでは train loss しか Comet で見ることができない。自分の場合は val loss も欲しかったので以下のようにした。

    def validation_end(self, outputs):
        avg_loss = torch.stack([x['val_loss'] for x in outputs]).mean()
        avg_val_acc = torch.stack([x['val_acc'] for x in outputs]).mean()

        tensorboard_logs = {'val_loss': avg_loss, 'avg_val_acc': avg_val_acc}
        self.logger.experiment.log_metric('val_loss', avg_loss.detach().cpu().numpy(), step=self.global_step, epoch=self.current_epoch, include_context=True)
        return {'avg_val_loss': avg_loss, 'progress_bar': tensorboard_logs}

training の resume

CometLogger は training の resume に対応していないことがわかった(pytorch-lightning/comet.py)。というか TensorboardLogger が resume に対応しているのだね。つまり Lightning と Comet を同時に使いたいなら CometLogger 経由ではなく Comet API を直接叩くのが良さそう。

存在する experiment に追記できてる?

Experiment Overview - Comet.ml よると experiment.get_key(self) を利用して ExistingExperiment を作れる。実際に試してみたらうまく行った。

if resume:
   experiment = comet_ml.ExistingExperiment(api_key='',
                                            previous_experiment=experiment_key,
                                      project_name="simple-bert-test",
                                      workspace='higepon',
                                      ) 
else:
  experiment = comet_ml.Experiment(api_key='',
                                      project_name="simple-bert-test",
                                      workspace='higepon',
                                      )

apex amp を有効にする

Trainer に use_amp=True を渡す。Colab で環境を整えるのはちょっと面倒。

try:
  from apex import amp
except ImportError:
  !pip install https://download.pytorch.org/whl/cu100/torch-1.2.0-cp36-cp36m-manylinux1_x86_64.whl
  !pip install https://download.pytorch.org/whl/cu100/torchvision-0.4.0-cp36-cp36m-manylinux1_x86_64.whl    
  !git clone https://github.com/NVIDIA/apex
  !cd apex;pip3 install -v --no-cache-dir --global-option="--cpp_ext" --global-option="--cuda_ext" .

! pip -q install pytorch-lightning==0.6.0
! pip -q install transformers==2.1.1
! pip -q install comet_ml

続きます。

GCP + Visual Studio Code 開発環境構築

前提

GCP への ssh 接続。GCP の AI notebooks インスタンスに ssh できなかったので調べた - higepon blog

目標

  • Visual Studio Code のリモート接続を利用して GCP 上のコードを快適に編集。
  • git 周りの操作もそのまま行いたい。
  • Visual Studio Code 自体の習熟。
  • Kaggle 用に directory layout も最適化。

手順

GCP の AI notebooks インスタンスに ssh できなかったので調べた

動機

Visual Studio Code でコードをリモート編集したい。そのためには local Mac からインスタンスssh が必要。

事実

ssh -v

ssh -v  [外部IPアドレス]
OpenSSH_7.9p1, LibreSSL 2.7.3
debug1: Reading configuration data /Users/higepon/.ssh/config
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 48: Applying options for *
debug1: Connecting to [外部IPアドレス] [[外部IPアドレス]] port 22.
debug1: connect to address[外部IPアドレス] port 22: Operation timed out
ssh: connect to host [外部IPアドレス] port 22: Operation timed out

ファイアーウォールの設定

まずヘルプドキュメントを読む。

設定してみよう。"VPC ネットワーク" - "ファイアーウォールルール" を開く。

  1. ファイアウォール ルールの作成
  2. 名前: higepon-kaggle-ssh
  3. ネットワーク:インスタンスのネットワークと同じものを選ぶこと!
  4. 優先度:999
  5. 上り
  6. ターゲットタグ:higepon-kaggle-ssh
  7. ソースIPの範囲:0.0.0.0/0
  8. tcp:22
  9. インスタンス詳細設定
  10. ネットワークタグ:higepon-kaggle-ssh
  11. ssh -v [外部IPアドレス] で無事接続できた!

## 自分用メモ
インスタンス側で ssh 認証鍵を higepon と jupyter 両方で登録しておくこと。

Host kaggle-gcp
    HostName 外部IPアドレス
    User jupyter
    IdentityFile /Users/higepon/.ssh/google_compute_engine
    UserKnownHostsFile=/Users/higepon/.ssh/google_compute_known_hosts
    HostKeyAlias=compute.xxxxx
    IdentitiesOnly=yes
    CheckHostIP=no

突発性脳脊髄液減少症になり1ヶ月以上寝たきりだった話

時間のない人向けのまとめ

  • ある日突然激しい頭痛に見舞われ即入院。
  • 突発性脳脊髄液減少症低髄液圧症候群)と診断され手術。何らかの原因で、脳脊髄液が硬膜から漏れて髄液圧が低下することで頭痛などの症状が起こる病気。
  • 起立性頭痛(頭痛があるがしばらく横になると楽になる)がある場合は病院に行き症状を医師に伝えよう。
  • 確定診断・治療できる病院&先生はとても少ない。関東エリアならS病院T先生。

このまとめについて

ある日の朝、原因不明の激しい頭痛に見舞われた際の、入院、手術、回復までのまとめ。最近少しずつ知られるようになった病気で(ラジエーションハウス~放射線科の診断レポート~でも取り上げられた)。正しく診断してもらえない場合が多いようだ。病院をたらい回しにされ、心療内科うつ病と誤診されることもある。何ヶ月も原因不明で苦しむこともある。ここに詳細な記録を残すことで同じ病気にかかった人が、正しい診断・治療を受ける助けになれば幸いである。

感謝

闘病初期は原因不明で、一生寝たきりになる覚悟をした。はげまし支えてくれた妻と息子に深く感謝。また治療に尽力してくれた医療関係者のみなさんにも感謝と尊敬の念しかない。ある日突然出社できなくなって、職場の皆さんにも迷惑かけたが「仕事のことは気にせず治療に専念して」とバックアップしていただいて本当にありがたかった。

発症1日目

目が冷めて激しい頭痛に気づく。吐き気がひどい。トイレにこもり嘔吐。辛くて立てない。床にうずくまると少し楽になる気がする。頭痛持ちではないので、何らかの突発的なやばい病気かもしれない。近所の大きいK病院に行こうと思って着替えたが、まったく頭が回らない。僕の様子がおかしいことに気づいて妻がすぐにタクシーで病院に連れて行ってくれた。目がまわり頭痛がひどい。タクシーでは前かがみになりずっと下を向いて「早く着け」と念じていたのを覚えている。

病院到着後、すぐにストレッチャーで脳外科に運ばれ優先的に見てもらえた。この時点でベッドで横になると頭痛がすっと消えることに気づいていた。CT と MRI 検査。緊急を要する病気(脳梗塞くも膜下出血?)の兆候は見られないと言われ安心。寝ると頭痛が消えることを先生に伝えると「過去に一度だけ見たことがあるが、これは髄液が漏れているかも」と言われる(この先生の判断が得られたことが本当にラッキーだった)。CT と MRI を見ると若干脳が下垂しているように見えるとも。ただし髄液が本当に漏れているかはわからなかった。その場でK病院での入院が決まる。治療方針は水分を取りつつベッドで寝たきりの絶対安静。あとで調べてわかったのだが脳脊髄液減少症の治療方法は大きく分けて2つあり。2-3週間の保存的治療(ベッドで安静)とブラッドパッチ(硬膜外自家血注入)があり、後者は対応している病院がとても少ないのだ。

発症2日目から14日目 K病院

水分をたくさん取る必要があり毎日点滴。食事とトイレ以外はベッドで安静。起き上がるときは頭を低くして60度くらいのお辞儀をしている状態だと少し楽な気がする。食事はおにぎりなど、文字通り寝ながら食べた。

  • 発症2日目: 朝症状改善せず。水を飲んだが全て吐いた。昼から夕方まで気力がなくスマホで動画見ることさえもできない。寝ていても頭が痛い気がする。家族が見舞いに来て少し安心した。朝昼ご飯ほどんど食べられず。夕飯はほぼ食べた。夜も動画見る気は起きなかった。
  • 発症3日目: 朝起きたら少し楽になってた。顔を上げてもすぐには頭痛が来ない。昨夜までは後頭部にずーんと頭痛がきていたが、少し来るくらい。長く立ってると眉間が痛い気がする。本当にほぼ寝ているので生活に必要なものすべてを、ベッドから手が届く範囲においた。
  • 発症4日目: 可もなく不可もなく。悪くもなっていないか良くもなってない。
  • 発症5日目: 変わらず。昼にもう一度CT。寝ながらパン食べると楽なことを発見。ブラッドパッチについて調べ始める。病棟内の自販機まで前かがみで行ってみた。行けたけど。気持ち悪くなった。
  • 発症6日目: ようやく発見したが朝気持ち悪いことが多い。水分不足?。首のMRI撮影。車椅子で移動で気持ち悪くなりしばらくベッドで休んだ。夕方の時点でも気持ち悪い。
  • 発症7日目: 起き上がってざわざわと頭痛がが来るまでの時間が長くなった気がする。少し良くなってる。ただ顔の左側に若干に違和感。TODOリストを作ろうという気力が湧いたので多分良くなってる。首のMRIでほぼ低脳髄液症確定。自販機まで歩いてみた。往路は快調。復路で少しずつ頭が重くなる感じ。昨日よりはかなり良い。
  • 発症8日目: 今日からカフェインを薬として服用。頭痛に効くらしい。起き上がってどれくらいで頭痛が来るか測定しよう。47秒、50秒。カフェインのため夜寝られず。眠剤もらった。
  • 発症9日目: 時間測定。1:50まで待っても。頭痛来ず。頭が若干重くなる。寝過ぎの肩こりとかと同化してよく分からない。3分で来ることがわかった。デイルーム往復くらい。夜測定したら6分。
  • 発症10日目: デイルーム往復くらいで頭痛。昨日と変わらずか?10分歩いた。7分ぐらいで軽い頭痛が始まる。10分の時点で頭が痛くなり終了。痛さは二日酔いよりは軽い。寝たら徐々に良くなる。回復に3-4分かかる?シャワー許可され20分浴びたら頭が痛くなった。
  • 発症11日目: 10分座るとズキズキして寝たくなる。昨日かなり調べたおかげで自分の状態について先生にまともな質問ができるようになった。
    • 漏れている箇所は見つかったか?
      • 見つかってない。脳の下がり具合(下垂)の程度は低く症状は軽いと考えている。首のMRIで漏れているっぽいことはわかっている。もう一度MRIを取れば客観的に良くなっているか分かるだろう。
    • 専門医S病院のT先生に紹介状を書いて欲しい
      • 問題ない(ただし予約が2ヶ月先までいっぱい)。造影剤を入れてのRIで漏れている箇所の特定する検査は、K病院ではやってない。
  • 発症12日目: 午前に血液検査と首のMRI。詳細を職場の上司に送った。座って5分経っても平気だった。怖いので途中でやめた。K病院とS病院の、病院連携で2日後にS病院での初診外来予約が取れた(ここもラッキーである。予約がいっぱいのところにねじ込んでもらえた)。僕は行かずに妻がMRIなどの情報を持って届けることに。
  • 発症13日目: 朝試してみたら約7分で頭痛がくる。もう一度測定。ベッドで座るバージョン。10分で頭が重くなってきた。右目の奥が痛い感じ?頭振ると痛い。13分で「うー」やめよう。となった。
  • 発症14日目: 今日はS病院で妻が話を聞いてくれた。T先生からまず間違いなく突発性低髄液症候群であろうとの診断が。5日後にS病院に入院することが決定。ブラッドパッチの予定。

発症15日目から18日目 一時退院

  • 発症15日目: 一時退院して自宅へ。自宅でも寝たきり。夜は家ですき焼き。家族との時間はかけがいのないものだ。帰宅で調子にのったせいかめまいなどが酷い。夜にとても暴力的な夢を見て怖くなる。頭痛の影響だろうか。自分の人格が変わってしまったのかと思いとても凹んだ。
  • 発症16日目: 朝から気持ち悪くほぼ全てを吐いた。その後11:30am まだずっとゆっくりしてたらよくなった。目をつぶったらめまいがする。夕方には完全に良くなった。なんだったんだろう。
  • 発症18日目: とても気分がよい。ベッドにいる分には健康に思える。明日はS病院への入院。多少吐き気があったが、息子との最後のお風呂になるかもしれないので一緒に入った。頭痛が来るまでに上がらないといけないので5分と短いが、幸せである。

発症19日目から22日目

  • 発症19日目: タクシーでS病院へ。起き上がっている時間が最大限短くなるように妻ががんばってタクシーや入院手続きを最速でやってくれた。感謝。すぐにT先生登場。柔らかな雰囲気の患者に安心感を与える良い先生。K病院の情報からほぼ間違いなく低髄液だろうとのこと。早速 RI シンチ検査。放射性同位体の造影剤を腰椎から注入して、その造影剤の拡散具合で髄液の漏出やその箇所の特定をするもの。ネット情報だが、この検査がやれる病院がそもそも少ないようだ。
    • 腰に注射して髄液の抜き取り。麻酔の注射が少し痛い程度でほぼ痛くなかった。髄液抜き取りの際に、出てくる単位時間あたりの髄液が少ないことから髄圧が低いことが分かり、低髄液であることがほぼ確定と先生が仰った。その後造影剤を注入。これも麻酔のおかげか痛くない。処置後先生が髄液を見せてくれる。透明な液体である。こんなこともなければ見られない貴重な体験。先生は処置中に、雑談してくれてリラックスさせようとしてくれてるのが良くわかる。良い先生だ。病室に戻りうつ伏せで少し寝かされる。しばらくすると仰向けになるように言われる。腰は痛いと言うより全体的に重い感じ。何となくお腹が痛いなあというのが背中側にあるのに近い。この後は小便を我慢しつつ撮影を待つ。これを書いている時点であと20分。撮影のため起き上がる。うげげ。腰痛い。我慢できる範囲だがすごい腰痛めた感じ。寝てる時は気づかなかった。撮影はCTミエロとRI脳槽シンチ。寝てるだけ。予告通り頭も痛くなってきた。髄液抜かれた分痛くなるらしい。全ての移動は車椅子。
    • T先生の回診。RI で二箇所の漏れが見られる。首と背中二箇所のブラッドパッチの方向で同意書をもらった。CTでも似たような所見。念のため頭部撮影したが脳出血はなさそう。採取した髄液を国の研究に使って良いか?の書類ももらった。快諾した。今日は3回、明日の朝1回RIがある。2回目終了した時点で、漏れが確認されているわけだがあと2回やる必要あるなだろうか。
  • 発症20日目: 腰の痛みがかなり良くなり、座ってもずーんと痛くならない変な姿勢にならない。でもまだ痛い。立って歩けるようになった。髄液抜き取りの影響も減ったようだ。
    • RI 9時から。朝食は7:30くらい。昨夜は眠剤節約のため普通に就寝。23時くらいまで眠れなかった。
    • シャワーを10分ほど浴びたら眉間と後頭部が痛くなった。まだまだだね。
    • 明日はブラッドパッチなので夜に緊張。治る。絶対治ると自分に言い聞かせて眠りにつく。
  • 発症21日目:
    • ブラッドパッチを 10:30-10:50 に受けた。
      • T先生と看護師さん。そのまま病室で行った。うつ伏せで背中が湾曲するようにお腹にクッション。胸椎と腰椎に麻酔。麻酔は痛いが点滴の針を刺すのと同じ程度。まずは胸椎からブラッドパッチ。静脈からとった自分の血液を注入。背骨と肩甲骨が交わるところあたりに針を刺し注入。点滴針から自分の血を取って注入するらしいがもちろん見えない。針を刺したとき若干痛い。注入時は痛くないかなど様子を聞いてくれる。胸椎終了後に足の指をこっそり動かして何も異常はないことを確認。腰椎はRIをやったあたりから注入。先生の指示で看護師さんは僕の目をずっと観察していた。
      • ブラッドパッチ終了直後。起き上がって座るように言われる。頭が痛くならないか?と問われた。確かに痛くならない。血が固まるまで待つイメージだったのだが即効性があるとは知らなかった。成功して本当に良かった。いろいろな人の助けでこんなに早く治療してもらえたことは本当に幸運だった。
      • T先生術後のお言葉。あまり細かい症状は気にしないこと。もう治りましたよ。
    • 術後2時間経ったので食事とトイレ。立ったり歩いたり計25分。一切頭痛なし。頭痛の兆候すらなし。これは治ったね。泣ける。人生取り戻した!
    • 夕方傷口が痛むのでゆっくり。痛み止めをもらうほどではない。
    • 術後 10-14日はベッドで安静に、その後復職プランを相談しましょうと言われた。
  • 発症22日目:
    • 術部二ヶ所の痛みはかなり引いた。ゼロではないがすっと立ち上がれる。
    • 27分頭痛来ず。朝食や髭剃り、身支度できた。
    • 看護師さんの話
      • マッサージが原因でこの病気にになる人が多い。これを知ってから看護師さんはマッサージに行かなくなったらしい。
      • 発症から診断、治療まで1ヶ月以内というのはかなり珍しい。診断が早めにできたのがかなりラッキー。病気になったのはアンラッキーだがすごいラッキーなことらしい。運が悪いと心療内科にまわされ、心因性のものと診断されてしまうらしい。

発症23日目から35日目 自宅静養

術後2週間は自宅でベッドで静養。ここで油断しないようにひたすら寝る。

  • 発症23日目: 今日は点滴二本で午後に退院。T先生いわく。細かい小さな頭痛は気なさなくて良いとのこと。立ち上がると立ちくらみ。でも帰りのタクシーも全然平気だった。 発症24日目: ますます良くなった。まだ腰の痛みがあるかな。あと太った気がする。頭の痛みはほとんどない。
  • 発症25日目: 立ち上がったときのふらつきが減った気がする。
  • 発症26日目: 首の寝違えみたいな痛みもかなり減った。
  • 発症27日目: 首の寝違いみたいな痛みや、疲れ感も実は病気の症状でそれらが劇的に良くなってきた気がする。寝ていても疲れたりしない。まだ処置跡は重くて鈍い痛みがある。
  • 発症28日目: 処置跡以外は問題なし。と思ったが昼寝して目が覚めたらうっすら気持ち悪いような。気のせいのような。
  • 発症29日目: 朝目が覚めたらスッキリ。傷跡はまたうっすらと痛い。
  • 発症30日目: 頭は一切痛くない。ずっと寝ているので首肩の負担が高い。
  • 発症31日目: 頭痛くない。腰の傷口も痛くないかも。
  • 発症32日目: 腰と肩の痛みはかなり引いた。
  • 発症33日目: トイレに行くときもすっと立てる。1時間起きていても頭痛が来ない。
  • 発症34日目: 3時間寝ずに、起き上がってみる。快調である。ひょっとして治った?
  • 発症35日目: S病院でMRI・診察。先生から「治ったね!」とのお言葉。心配された合併症(脳の血腫)も見られず安心。1-3ヶ月かけて体力を戻していくようにとのこと。職場復帰は数日様子を見て体力が戻ってから。やったー。万歳!
    • ようやく起きて良い許可が出たので、職場に経過を連絡後。このブログをまとめた。

その後

  • 発症36日目: 昨夜首が痛くて目が覚める。朝には治ってた。姿勢の問題?
    • 近所のコンビニに歩いてみる。久しぶりの徒歩。体が重い。強歩大会の後半で足が棒になったときに似てる。ゆっくりなら歩ける。椅子に座ると背もたれのありがたみが分かる。
    • 結局起きてから寝るまで横になることはなく。起立性頭痛はなくなった。
    • 体力の衰えは否めない。
  • 発症37日目: 少しずつ日常へ。週明けに職場復帰をめざす。まずは近所の散歩から。

情報源

入院中はなるべく一次情報にあたるように病気について調べた。英語版 Wikipedia からリンクされている論文を読むのがおすすめ。

How to update existing dataset using Kaggle API

すでにある Kaggle dataset を API 経由で更新する方法。

% mkdir tf2-my-submission-dataset
% cd tf2-my-submission-dataset
% kaggle datasets metadata -p . higepon/tf2-my-submission
% kaggle datasets download  higepon/tf2-my-submission
% unzip  tf2-my-submission.zip

# Update one file
% cp ../out_dir/pytorch_model.bin .

# Update!
% kaggle datasets version -p . -m "Updates model.bin"

If you see KeyError: 'errorMessage' with API version 1.5.6. You need to use 1.5.4.

扁桃腺摘出手術を受けた

口蓋扁桃の摘出手術を受けて7日入院したときの記録。

手術を受けた理由

直接の引き金は先月初旬に扁桃腺炎で40度以上の熱を出し入院したこと。以前から1年に何度も扁桃腺炎になっていた。喉の痛みからはじまり高熱というパターン。最悪の場合は悪化して抗生剤点滴のため入院となる。年に1-2回入院していると思う。過去にも医師に摘出をすすめられたが出血などのリスクが怖くて断っていた。その代わり以下の予防に命をかけていた。

  • 頻繁なうがい。出社、帰宅時はもちろん。トイレで手を洗うときはうがいもする。
  • 通勤時のマスク。これは他者のくしゃみや咳からの予防目的ではない。マスクを付けていることで、自分の手が鼻や口などの粘膜に物理的に触れなくなる。つまり自分の汚い手からの感染を防ぐのが目的。
  • 睡眠
  • 加湿。家には加湿器が2台あり冬場はフル稼働である。
  • 喉の腫れや痛みを感じたらすぐに病院に行き、必要があれば抗生物質を処方してもらう。(今回はこれでも悪化してしまった)。

にも関わらず何度も扁桃腺炎になる。これが以下の2方面で辛かった。

虚弱問題

ネットで扁桃腺摘出体験ブログを読むと大体同じことが書いてある。手術後に、体感で風邪の引きやすさが 1/10 くらいになるらしい。また喉が痛くなる風邪を引いても2-3日でほぼ良くなる。「これが一般人の引く風邪なのか!」と思うらしい。そんなめぐまれた一般人の人たちから見ると、扁桃腺炎にかかってワンシーズンに1-2回。高熱で1週間くらい寝込む人たちは、虚弱体質に見える。もしくは本人の予防努力(もしくは気合)がたりないというレッテルを貼られてしまうのだ。また時には、完全に好意から謎の民間療法をすすめられたりする。これらは地味に辛い。

予定たてられない問題

いつ扁桃腺炎になるか分からないので予定を立てられない。もしくは予定を入れるのがとても不安。覚えているだけでも

  • 昨年の夏。息子とのキャンプの直前に入院。
  • 今年イタリア旅行の前に発熱。

などでやらかしている。家族や知人に迷惑をかけるのが怖くて色々断りがち。仕事の海外出張も怖い。「もし出張中に発症して悪化したら?」「アメリカの病院に行くの?」「入院したら法外なお金かかる」などの不安がつきまとう。その不安がストレスになり扁桃腺が腫れたこともあった。

手術と入院の記録

ツイートしていたものをそのまま貼っておく。

  • Day1: 麻酔科医と看護師さんの説明を受ける以外は今日は何もなし。看護師さんも口蓋扁桃とったらしい。痛いですよー😉と言われた。
  • Day2: 朝から手術。全身麻酔なので記憶なし。終了後3時間安静。痛さは扁桃炎マックスの時と同程度なので耐えられる。血の混じった痰をできるだけ優しく外に出すのが難しい。痛みと麻酔後なので夜までひたすら寝るのみ。同室で同じ手術を受けた人はもっと痛そう。
  • Day3:術後最初の食事。重湯、具なしコンソメスープ、牛乳、りんごジュース。喉の奥に違和感あるが意外と飲み込めるものだ。体調はかなり楽になったが、邦画を見るのはOKだが、もっと頭を使う洋画や読書はしんどい感じ。夜は痛みで寝られず痛み止めをもらった。まだ大きな声ではしゃべれない。
  • Day4:食事がお粥に。スパルタで焼き魚も。全ての薬が経口薬になり点滴とさようなら。術後はじめてシャワー気持ちよかった。矯正のリテーナを長めにつける。英語コンテンツも見られるくらい良くなった。まだ飲み込むと痛い。唾液に血が混らなくなった。家族がお見舞いに来てくれた。ありがたい。アメリカの友人や同僚に「扁桃腺手術ならアイスを食え」と言われたので実践。確かに患部周辺がひんやりして気持ちいい。
  • Day5:食事がお粥から通常のご飯へ。喉の痛みも気持ち穏やかに。読書をする余裕が出てきた。メモの魔力読み中。Switchのウィッチャー3プレイ中。良い意味でリアルなお使いゲーム。さすがに暇なので洗濯して衣類をきれいにたたむなど時間つぶし。この時期に出血のリスクがあるので油断せずに休まないと。
  • Day6:喉の痛さや違和感以外は、全て正常になったように感じる。喉の奥のかさぶたが自然に優しく剥がれれば吉。運悪く一気に剥がれると出血→再手術。というようなことがおきやすいのが今日明日らしい😬。安静にする。そういえば新しいスマホのセットアップは時間をつぶせてよかった。
  • Day7:喉の痛みがさらに良くなった。痛み止めを飲まなくても食事ができる。予定では明日か明後日退院。シャバに出ても運動や固い食べ物などは禁止。
  • Day8:無事退院🎉

追記2020年5月

その後どうなったか。 - 術後の喉の違和感は完全になくなった。つっぱる感じや痛みもない。もちろん出血もない。 - 一度も高熱をだしていない。ただしコロナのせいで家にいたのも大きいと思う。 - 喉が痛かったことは2回あった。ちょっとした痛みで翌日にはなくなっていた(以前なら扁桃腺炎コースだと思う) - 咳、鼻水をともなう風邪はまだ一度もひいてない。

IEEE-CIS Fraud Detection コンペ反省会

IEEE-CIS Fraud Detection コンペに参加。チームとして銀メダルをとりめでたく Kaggle Expert になった。コンペは名前の通り Credit Card のトランザクションを fraud or not に分類するもの。

時系列

  • Table コンペだが Time Series データなのに不安を覚えつつ EDA 。いくつか EDA カーネルを見る。
  • Local CV どうしようかまよったが、まずは KFold で End to End モデルパイプラインを作った。LightGBM。
  • 最初の End to end モデルは動けばよいの categorical features は無視して数値データのみで。
  • KFold の Local CV データを眺めながら label encode するなど。must 的なものをやる。
  • 某氏とチームを組む。初心者と言っていたがみるみる着実に歩を進めるので尊敬しかない。
  • 某コンペ時に count encoding を知らず。「モデルにはそのままだと count 見えないのよ」というありがたいスレッドで勉強になった教訓。それを踏まえて count feature の EDA を意識的にやっていた。
  • 自分で1から作っていたカーネルがいまいち伸び悩んでいたので、public kernel を fork して自分の学びを足す方向で進めた。結果的にこの判断は正しかった。
  • 同額の TransactionAmt の count encoding などをあれこれ EDA しつつためす。このころ 0.94 は 0.93 付近?
  • チームマージ
  • チームマージで似たようなスコアだけど、全く出自(feature engineering) が違うモデルが増えた。
  • チームの誰も手を出してなかった NN モデルを Torch でササッと書いた。過去の経験から GB よりスコアが劣るのはわかっていたが Ensemble で効果があるので。
  • GMEAN of low correlation カーネルでチームの submissions を ensemble してみたら一気に銅メダル圏内。
  • GMEAN of low correlation カーネルをちゃんと読み込んできちんと適用したら銀メダル圏内に到達。
  • 最終日まではあたらしい feature ためす。スコア上がったら Ensemble の繰り返しだった。
  • Final submissions は shake up/down が怖かったが、チームで相談して best score kernels とした

ほか

  • 自分の記録を kibela から Google Docs に移行した。理由は markdown を書くのが面倒になったから。あとどのデバイスからでもかんたんにアクセスできるから。
  • 途中の GPU 制限には本当に困った。
  • seaborn の勉強をしたことで EDA 苦手意識がかなりへった。やはり美しく表示されるとうれしい。
  • 上とすこし矛盾するけど。汚いコードでもいいからグラフを書いて、学びを得る。そのコードは捨てるが学びはとる。お気楽姿勢にして気が楽になった。
  • kaggle api 使って git でコード管理するのを後半から導入して大変良かった。
  • feather で特徴管理みたいなのは、まだ僕のレベルでいらないかも。

さあ Master めざす?