Mac OS X でのpyenvによるpython環境構築 - Tensorflow 編

kotaroito.hatenablog.com

というのを以前書いたのですが、Tensorflow を始めるにあたっては anaconda を使ったほうが何かと便利なので、メモを残しておきます。

1. pyenv と pyenv-virtualenv のインストール

brew install pyenv
brew install pyenv-virtualenv

2.bashrcの設定

# pyenv
[[ -s "$HOME/.pyenv" ]] && export PYENV_ROOT="$HOME/.pyenv" && export PATH="$PYENV_ROOT/bin:$PATH" && if which pyenv > /dev/null; then eval "$(pyenv init -)"; eval "$(pyenv virtualenv-init -)"; fi

3. pyenv で anaconda をインストール

pyenv install anaconda3-2.5.0
pyenv local anaconda3-2.5.0

4. Tensorflow をインストール

https://www.tensorflow.org/versions/master/get_started/os_setup.html#download-and-setup

pip install --upgrade https://storage.googleapis.com/tensorflow/mac/tensorflow-0.8.0-py3-none-any.whl

setuptools に起因してうまくインストールできないケースがある。 その際は、 osx 10.11 installation issues · Issue #135 · tensorflow/tensorflow · GitHub を参照のこと。

anaconda には numpy 等、数値計算に必要なライブラリはインストール済みなので、これで Tensorflow 入門ができる。

unicornのlog rotationでハマったが、実は test コマンドの exit コード起因だったという話

unicorn の log を cron で毎日ローテートする設定を書いたところ、下記エラーメールが届いて「なぜだろう」と数時間唸ってました。ようやく解決に至ったので、メモしておきます。

メール

件名:

Cron <root@***> test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )

本文:

/etc/cron.daily/logrotate: error: error running last action script for /path/to/unicorn/log/*.log run-parts: /etc/cron.daily/logrotate exited with return code 1

設定

/etc/logrotate.d に配備した設定ファイル内容は以下の通りです。

/path/to/unicorn/log/*.log {
  daily
  missingok
  rotate 90

  ...

  lastaction
    pid=/path/to/unicorn.pid
    test -s $pid && kill -USR1 "$(cat $pid)"
  endscript
}

原因

ログロテーションは正常に完了しており、"run-parts: /etc/cron.daily/logrotate exited with return code 1" なので last action script に問題がある模様です。

「test -s して存在確認してから実行してるし...何がいけないのかサッパリわからん!」 と思っていたのですが、この test の return code こそが原因でした。

DESCRIPTION
       Exit with the status determined by EXPRESSION.

       --help display this help and exit

       --version
              output version information and exit

       An omitted EXPRESSION defaults to false.  Otherwise, EXPRESSION is true or false and sets exit status.

となっており、test コマンドの成否によって、exit status が設定されるとのこと。

$ test -s /tmp/not_found_file
$ echo $?
1

実際に試してみると、存在しないファイルについては確かに 1 になるようです。。

test -s $pid が false になるのは unicorn を稼働させてなかったからで、これで理屈が通りました。

irisデータをロジスティック回帰とSVMで分類してみた

Coursera の Machine Learning の演習は、コスト関数とその最小化を自前で実装することになるのでなかなか大変だけど、pythonsklearn を使うと交差検定含め、ものすごくカンタンに書ける。

import numpy as np
import sklearn.datasets as datasets
from sklearn.linear_model import LogisticRegression
from sklearn import svm
from sklearn.cross_validation import cross_val_score

iris = datasets.load_iris()
logistic = LogisticRegression()

# Logistic Regression 
scores = cross_val_score(logistic, iris.data, iris.target, cv=5)
print("logistic regression", np.mean(scores))

# SVM(kernel:rbf)
scores = cross_val_score(svm.SVC(kernel='rbf'), iris.data, iris.target, cv=5)
print("svm(rbf): ", np.mean(scores))

# SVM(kernel:linear)
scores = cross_val_score(svm.SVC(kernel='linear'), iris.data, iris.target, cv=5)
print("svm(linear): ", np.mean(scores))
logistic regression 0.96
svm(rbf):  0.98
svm(linear):  0.98

カンタンに書けるが故に、基礎理論をきちんと理解し、思うように結果が出ないときに原因分析できる力が必要だと感じます。 月並みですが。

nginx try_filesディレクティブ

nginx の try_files ディレクティブについての備忘録。

Syntax

Syntax:  try_files file ... uri;
try_files file ... =code;
Default:    —
Context:    server, location

Module ngx_http_core_module

書かれていることを箇条書きでまとめると...

  • 指定された順序で "file" の存在をチェックし(つまり複数設定できる)、最初に見つかったものを処理する。
  • "file" への path は root と alias ディレクティブに従う
  • 何も見つからない場合は、最後に指定した uri に内部リダイレクトする

例1

設定

server {
    root /usr/share/nginx/html;

    location /images/ {
        try_files $uri /images/default.gif;
    }

    location = /images/default.gif {
        expires 30s;
    }
}

ディレクトリ

$ tree /usr/share/nginx/html/
/usr/share/nginx/html/
|-- 50x.html
|-- images
|   |-- default.gif
|   `-- hello.gif
`-- index.html

という場合に、リクエストとレスポンスの対応は以下のとおり。

リクエスト レスポンス 理由
http://example.com/images/hello.gif /images/hello.gif $uri は /images/hello.gif となり、対象ファイルが存在するため。
http://example.com/images/goodbye.gif /images/default.gif $uri は /images/goodbye.gif となり、対象ファイルが存在しない。このため、default.gif にフォールバックする。

例2

server {
    root /usr/share/nginx/html;

    location / {
        try_files $uri $uri/index.html $uri.html =404;
    }
}

http://example.com/hello をリクエストした場合、nginx は root(/usr/share/nginx/html)を起点に /hello, /hello/index.html, /hello.html を順に探し、見つからない場合には 404 エラーページを返す。

例3

location / {
    try_files /system/maintenance.html
              $uri $uri/index.html $uri.html
              @mongrel;
}

location @mongrel {
    proxy_pass http://mongrel;
}

この例では、ファイルが見つからない場合は、@mongrel という名前付ロケーションにフォールバックする。

sshできるdockerコンテナをつくるために最低限必要なこと

3ヶ月ぶりにDockerを触ったのですが、全てを忘れていて愕然としたので最低限必要なことをメモしておきます。 ホストOSは Mac OS X です。

Getting Started

Get Started with Docker for Mac OS X に立ち戻るのが基本です。

以下、Docker Toolbox をインストール済で、OS X のコンソールから docker コマンドを実行できる前提で。

Docker image を build する

Dockerfile を用意します。

パッケージをインストールし、 /var/run/sshd を作成するという簡単なものです。 (きちんとやるなら MAINTAINER 等書く必要あると思いますが、ここでは省いてます)

ubuntu

FROM ubuntu:14.04

RUN apt-get update && apt-get -y upgrade && apt-get install -y build-essential libssl-dev libreadline-dev zlib1g-dev language-pack-ja
RUN apt-get -y install openssh-server ufw curl
RUN mkdir /var/run/sshd

debian

FROM debian:wheezy

RUN apt-get update && apt-get -y upgrade && apt-get install -y build-essential libssl-dev libreadline-dev zlib1g-dev task-japanese sudo
RUN apt-get -y install openssh-server ufw curl
RUN mkdir /var/run/sshd

イメージをビルドします。

$ docker build -t kotaroito/ubuntu .
$ docker images

REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
kotaroito/ubuntu    latest              c6ec79983625        18 seconds ago      485.5 MB

作成したイメージからコンテナを起動するには run サブコマンドを使います。また、 ps サブコマンドでコンテナの状態を確認できます。

$ docker run kotaroito/ubuntu

$ docker ps -a

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                        PORTS                                             NAMES
93e06154f722        kotaroito/ubuntu    "/bin/bash"              1 seconds ago       Exited (0) 2 seconds ago                                                        naughty_pare

不要になったイメージは rmi サブコマンドで削除できます。

$ docker rmi -f c6ec79983625

DockerHub

Dockerhub を利用すれば、イメージの共有・再利用がカンタンです。 アカウントを作成したら、ログインしてプッシュすればokです。

$ docker login --username=kotaroito --email=****@****
$ docker push kotaroito/ubuntu

ssh / sudo できるようにする

最初に作成したイメージではコンテナに ssh / sudo できないので、必要な設定をDockerfileに加えていきます。

FROM ubuntu:14.04

RUN apt-get update && apt-get -y upgrade && apt-get install -y build-essential libssl-dev libreadline-dev zlib1g-dev language-pack-ja
RUN apt-get -y install openssh-server ufw curl
RUN mkdir /var/run/sshd

RUN useradd -m kotaroito && echo "kotaroito:kotaroito" | chpasswd && gpasswd -a kotaroito sudo
RUN mkdir -p /home/kotaroito/.ssh; chown kotaroito /home/kotaroito/.ssh; chmod 700 /home/kotaroito/.ssh
 
ADD ./authorized_keys /home/kotaroito/.ssh/authorized_keys
RUN chown kotaroito /home/kotaroito/.ssh/authorized_keys; chmod 600 /home/kotaroito/.ssh/authorized_keys

CMD /usr/sbin/sshd -D && tail -f /dev/null

最後のCMDはコンテナがexitしない工夫です。 あとは、buildして run すれば ok ですが、sudo するために privileged オプションを付けておきます。

$ docker build -t kotaroito/ubuntu .
$ docker run --privileged -d -p 2222:22 kotaroito/ubuntu

コンテナは Mac OS X の上で直接稼働しているわけではなく、VMVirtualBox 等)上で動いてるので、ssh するためには VMIPアドレスを調べる必要があります。

$ docker-machine ip default
192.168.99.100

これで ssh することができます。

$ ssh -v kotaroito@192.168.99.100 -p2222

なお、sshd を docker コンテナで走らせる必要はない、という議論もあります。 production で使うならこれはその通りだと思います。

blog.docker.com

以上。

Mac OS X でのpyenvによるpython環境構築

pythonで機会学習入門するために Mac OS X に環境構築したので、メモを残しておきます。

1. pyenv と pyenv-virtualenv のインストール

brew install pyenv
brew install pyenv-virtualenv

2.bashrcの設定

# pyenv
[[ -s "$HOME/.pyenv" ]] && export PYENV_ROOT="$HOME/.pyenv" && export PATH="$PYENV_ROOT/bin:$PATH" && if which pyenv > /dev/null; then eval "$(pyenv init -)"; eval "$(pyenv virtualenv-init -)"; fi

3. pyenvの動作確認

pyenv install --list
Available versions:
  2.1.3
  2.2.3
  2.3.7
  2.4
  2.4.1
  2.4.2
  snip...

4. pyenv で python をインストール

pyenv install 3.4.3

5. virtualenv の設定

pyenv virtualenv 3.4.3 my-env-3.4.3

6. 機会学習で利用するパッケージのインストール

pip install numpy
pip install scipy
pip install matplotlib
pip install scikit-learn

7. matplotlibの設定

OS X だと matplotlib がそのまま動かないので、ホームディレクトリに .matplotlib/matplotlibrc を 設置。

backend : TkAgg

8. Tensorflowのインストール

pip3 install --upgrade https://storage.googleapis.com/tensorflow/mac/tensorflow-0.8.0-py3-none-any.whl

追記(2017/4/2)

ローカルに複数プロジェクトがある前提だったのでpyenvを利用していますが、 確かにこういう視点もありますね。勉強になります。

qiita.com

InnoDBのロックに関する記事まとめ

InnoDBのロック機構どうなってたっけ?? と思ったら、読み返したい記事たち。

14.2.6 InnoDB のレコード、ギャップ、およびネクストキーロック

https://dev.mysql.com/doc/refman/5.6/ja/innodb-record-level-locks.html

MySQL InnoDBのネクストキーロック おさらい

http://d.hatena.ne.jp/sh2/20090112

InnoDBのロックの範囲とネクストキーロックの話

http://blog.kamipo.net/entry/2013/12/03/235900

InnoDBで行ロック/テーブルロックになる条件を調べた #mysqlcasual Advent Calendar 2013

http://bluerabbit.hatenablog.com/entry/2013/12/07/075759

良く分かるMySQL Innodbのギャップロック

http://qiita.com/kenjiszk/items/05f7f6e695b93570a9e1