Bag of ML Words

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

Dockerfileの中でファイルやディレクトリ作るとownerがroot:rootになっちゃうのが嫌な時・・・

COPYコマンド(ADDよりはCOPYのほうがいいらしい)でchownオプションがつけられるよ!

 

COPY --chown=[user name]:[user name] from_dir_path_in_local to_dir_path_in_container 

 

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 

 

自分のファイルのパスを取得(python)

current_dir_path = os.path.abspath(os.path.dirname(__file__))

 

これで、当該実行ファイルの位置を取得できるので

libraryのツリー内の好きなファイルを見に行けるぞ

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 .