Bag of ML Words

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

Chainerでlearning rateを任意に操作

qiita.com

 

これに書いてあるとおりですが、やり方わかって実際動いたので貼ってみる。

 

class LrScheduler(extension.Extension):
  trigger = (1, 'epoch')
  def __init__(self, base_lr, epochs, optimizer_name='main', lr_name='lr'):
     self._base_lr = base_lr
    self._epochs = [int(e) for e in epochs]
    self._optimizer_name = optimizer_name
    self._lr_name = lr_name
  def __call__(self, trainer):
    optimizer = trainer.updater.get_optimizer(self._optimizer_name)
    e = trainer.updater.epoch

    if e < self._epochs[0]:
      lr = self._base_lr * 0.1 + e * 0.9 * self._base_lr / self._epochs[0]
    elif e > self._epochs[1]:
      lr = self._base_lr * (0.9 ** (e - self._epochs[1]))
    else:
      lr = self._base_lr
    setattr(optimizer, self._lr_name, lr)
# end class
setattr(optimizer, 'lr', 0.1*args.lr)

trainer.extend(LrScheduler(base_lr=args.lr, epochs=('3', '5')))

 

 これで、epoch3までかけてlrが徐々に増加することで突然の局所解を回避。epoch5までは定常飛行して、epoch7から徐々になましていく、という動きが実現できる。

 

progressを貼り付けるとこんな感じ。

epoch elapsed_time lr           main/loss 
1        9.02064          0.001    2.81905 
2        14.4791          0.004    0.757175 
3        19.9546          0.007    0.333922 
4        25.3488          0.01      0.73813 
5        31.0634         0.01       1.48048 
6        37.1175          0.01      1.3194 
7        42.8478         0.009     0.645383 
8        48.345           0.0081   0.404334 
9       53.6649          0.00729 0.359146 

 

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があればそこから学習する

pycharmのdocstring形式

こんなの常識らしいのだけど、知らなかったので。。。

 

pycharmのsettings --> Tools --> PYthon intergrated toolsの中で、Docstringsのフォーマットを選べるよ。reStructedTextがデフォルトらしいけど、numpy formatやgoogle formatの人が多いらしい。

google formatにしてみますか

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