Bag of ML Words

ML = Machine Learning, Music Love, and Miscellaneous things in daily Livings

Chainerで訓練の半自動再開(resume semi-automatically)

会社的に推奨されたので、適当にsnapshotとってresumeする仕組みを実装した。

 

やりかったことは

  • 適当なタイミングでtrainerのsnapshotをとって、そこから学習再開できるようにする
  • chainermnだとmaybe_loadという便利関数があってiteration数とか解決してくれるんだけど、普通のchainerにはそれがない
  • ので、resume用のsnapshotは名前を固定、随時上書き方針として、resume flagを立てて起動すると固定のsnapshotファイルがあればロードしてそこからやりなおす

 

適当なタイミングでsnapshotをとる@固定の名前

frequency = args.epoch if args.frequency == -1 else max(1, args.frequency)
snapshot_filename = args.prefix + "_snapshot_for_resume.npz"
trainer.extend(extensions.snapshot(filename=snapshot_filename), trigger=(frequency, 'epoch')) 

 

こんな感じ。argsにfrequencyというsnapshotの頻度指定を入れておくのと、共通ファイル名は{args.prefix}_snapshot_for_resume.npz。

これで、frequency epochごとに trainerのout引数に指定したディレクトリに{args.prefix}_snapshot_for_resume.npzが保存される

 

フラグでresumeチェックする

parser.add_argument('--resume', '-r', action="store_true", help='Resume training from snapshot') 

 これをonにすると、起動時に上記ファイルがあるかどうかチェックする

 

if args.resume and os.path.exists(model_dir + "/" + snapshot_filename):

  print("Resuming a training from a snapshot '{}'".format(model_dir + "/" + snapshot_filename))
  chainer.serializers.load_npz(model_dir + "/" + snapshot_filename, trainer)

trainer.run()

 

 model_dirというのが、trainerのout引数に指定したディレクトリだと思ってください。

trainer.run()の直前に上記のコードを書き足す

 

あとは、train.pyの起動時に -f 10 -r と書き足すと、10エポックごとにsnapshotとるのと、もしすでにsnapshotがあればそこから学習する

Dockerfileでsourceを使う。というかbashを使う for installing chainer-cv

Dockerfileの中だとsourceコマンドが使えないというのは良く知られた話のようで、それはDockerfileの中ではシェルがbashではなくてshだから。

 

で、chianer-cvのインストール

Installation Guide — ChainerCV 0.11.0 documentation

のところを見ると、sourceがあるので。

 

結局、以下のようにしたらOKになった。

RUN ["/bin/bash", "-c", "source activate chainercv"]

のところ。

 

RUN git clone git://github.com/pyenv/pyenv.git ./.pyenv
RUN mkdir -p ./.pyenv/versions ./.pyenv/shims
ENV PYENV_ROOT $HOME/.pyenv
ENV PATH $PATH:$HOME/.pyenv/shims:$HOME/.pyenv/bin
RUN chmod 777 $HOME/.pyenv -R

ARG python_version="anaconda3-5.1.0"
RUN pyenv install ${python_version}
RUN pyenv global ${python_version}

# --- Install modules ---
WORKDIR $HOME/
RUN pip install --upgrade pip
RUN pip install numpy scipy
RUN pip install matplotlib
RUN pip install pandas
RUN pip install chainer
RUN pip install tqdm
RUN pip install joblib
RUN git clone https://github.com/chainer/chainer
RUN pip install cupy-cuda92
RUN pip install optuna

# Chainer CV
RUN git clone https://github.com/chainer/chainercv
WORKDIR chainercv
RUN conda env create -f environment.yml
RUN ["/bin/bash", "-c", "source activate chainercv"]
RUN pip install -e .

 

natbib on arxiv...

ご無沙汰しています。

 

すっっっっっっっっっっっっごく久しぶりに論文を投稿したのですが、例によってarXivでのコンパイルエラーで苦しみました。

というか、bibの部分。

 

Error: Bibliography not compatible with author-year citations.

 

これ。生成されたbblファイルが、arXivの期待するnatbibスタイルになってない。

 

My FIx: [numbers]{natbib}

 

  1. main.textがあったとして、.bibファイルはmain.bibにしておく。
  2. \bibliograph{main}はいじらなくてよろしい
  3. \usepackage{natbib} --> \usepackge[numbers]{natbib}
  4. main.bblファイルも同梱すればいけた。

dockerの使い方

これも恥ずかしいけど、基本的なところから

 

イメージを作成する

Dockerfileのあるディレクトリで?

docker build -t [image name] [path to save image?]

 

ログインしないで、取得したイメージでコンテナを起動、則コマンドを実行する

docker run [image name] [command]

e.g. docker run my_image:latest echo "hello world"

 echo "hello world"がコマンド。

 

取得したイメージでコンテナを起動、bashシェルでログイン

docker run -i -t [image name] /bin/bash

 

zzshでログインするなら/bin/zsh

 

コンテナとホストの間でファイルのコピー

docker conainer ps でコンテナのID番号を調べて

docker cp {container ID}:{file path on container} {dir(file?} path on host}

docker cp {file path on host} {container ID}:{dir(file?) path on container} 

 

 

コンテナにホストのファイルシステムをマウント

 

Docker imageなどの管理系

 

作成したdocker imageをprivateなレジストリに置くためにタグをつける

docker tag {作ったdocker imageの名前} {docker-hostのドメイン}/{リポジトリ名}:{tag}

今のイメージが新しい名前で登録される。 

 

作ったイメージをレポジトリとかにpush

dockerpush {docker-hostのドメイン}/{リポジトリ名}:{tag} 

 

使っていない/止まっているコンテナ、イメージなどの整理

docker system prune

 

git(hub)の使い方 自分用メモ(随時修正)

恥ずかしい気もするけど間違えるよりはずっといい。

 

これもメモしていかないと・・・

 

レポジトリやブランチをもらってくる系の操作

 

レポジトリをコピー(clone)してくる

git clone <.git アドレス>

 

特定のブランチをコピー(clone)してくる

git clone -b <branch name> <.gitアドレス>

 

ローカルに新しいブランチを作る

現在のブランチのファイル内容そのままで名前だけ変わる

git branch <new branch name>

 

ローカルで指定のブランチに移る

git checkout <branch name>

 

ローカルの指定のブランチをremote/originに一致(pull)させる

git checkout <branch name>

git pull origin <branch name>

 

git pullは実際にはfetchしてmergeするのに似ている。

あえてfetch, mergeと分けたほうがいいこともある。

特に、upstreamなど、origin以外のリモートレポジトリを参照するとき。

 

あるレポジトリを参照するリモート ブランチに追加。upstreamという名前にする

git remote add upstream <repository .git to refer>

 

自分のmasterを、公式レポのmasterに追従するときとかに使える。(でも、ものとしては公式とは分離しておく、危ないから)

 

git checkout master # これはローカルのmaster

git fetch upstream master   # upstreamの最新masterをダウンロード

git merge upstream/master # upstreamのmasterブランチを、自分のローカルブランチに統合(merge)

 

リモートレポはいくらでも作れる。

 

消す系の操作

ローカルの特定ファイルの修正をなかったことにする

git checkout <file name>

 

ローカルのすべてのファイルの修正をなかったことにする

git checkout .

 

ローカルで特定のブランチを消す

git branch -D <branch name to be deleted>

 

HEADとかの操作系

ローカルで開発しているうちにmasterが進んでいたので、masterの先頭から延びたようにする

git checkout master

git pull origin master

git checkout <developing branch>

git rebase origin/master

 

 

Headとは、ツリーとは。。。

勉強して自分の理解を記録していく

 

rebaseしたらコンフリクトしたので修正してrebase続行

git add <fixed file>

git rebase --continue

 

 

git rebaseよくわからない!取りやめ!

git rebase --abort

 

Pull Request

送るとき

 

rebaseをきれいに実施して、commit logをきれいにしておくといい

 

 

受けたとき

 

てもとで動作させるために、ローカルにリクエストを持ってくる

$ git checkout <pull request URL>

これでやってみて、動くようならいいし、動かないようなら修正してもらう

 

 

PRを間違ってmergeしてしまったとき

 

tweeeety.hateblo.jp

 

git submoduleの自分用メモ書き

git submoduleはほかのレポジトリの「特定コミット」を自分の内部の構成要素にする仕組みで、大きいものを作るときや、各要素が複雑enoughな時に役立つっぽい。

 

基本の理解

 

  • submodule内のレポと本体のレポは別物
  • 本体としてはsubmoduleのコミット番号のみを記憶している
  • submoduleを直接修正pushしてらsubmoduleのレポだけが更新されるが、本体は何の更新も見えない
  • submodule更新してから、submoduleのディレクトリの外でgit submodule updateすると、本体レポの記憶しているコミット番号が更新される

 

これ良かったね 

Git submodule の基礎 - Qiita

 

基本コマンド

git submodule update --recursive

これでトラックするsubmoduleのコミット状況を更新かな?

 

 

git submodule foreach git pull origin master

foreachコマンドはその名の通り、同じ処理を繰り返し順番にやってくれる。

これでやれるのは各submoduleにおいてpull origin masterをするってこと

 

git pull origin [specific-commit identifier]

各submoduleのディレクトリにおりて、そこで上記の通常pullを行うと、そのsubmoduleについては特定のコミットを落としてくることができる。