luggage baggage

Machine learning, data analysis, web technologies and things around me.

multiprocessing で tfrecord 作成を高速化する話

お久しぶりです。

TensorFlow でモデル学習をする際、便利に使われるのがtf.dataAPI です。以前はtf.contribで提供されていましたが、非常に使い勝手の良い機能だったこともあり、現在は独立したモジュールとして存在しています。様々な形式のデータ入力に対応している中でも、公式に推奨されているのは
.tfrecordというバイナリ形式のデータを読み取るtf.data.TFRecordDatasetだと思います(むかしの Caffe でいう LMDB みたいなやつ)。

私はいま画像認識系の仕事をしているのですが、先日扱った画像は百数十万枚ほどあり、一枚一枚も10数MBと小さくはなかったため、単純に tfrecord を作成すると30時間以上もかかる状態でした。この記事では、その時に使った非常に雑な高速化手法をご紹介していきます。CPU 数が稼げる環境であれば、10倍速とかは十分に達成できる感じでした。

続きを読む

Python 機械学習コードを Cython でラップして C/C++ から使う

お久しぶりです。吉田弁二郎です。

Cython という便利なトランスパイラ(言語と言語の中間にある言語のようなもの)があります。Python ライクな文法で書ける Cython スクリプトは C/C++ コードに変換・コンパイルされた後に Python から呼び出し可能で、C/C++ ライブラリを Cython スクリプトから呼び出すことも難しくないので、Python ライブラリの高速化作業を効率良くおこなうためによく使われています。

著名なプロジェクトで言うと scikit-learn や pandas だったり、最近利用が広がり始めた cupy などで Cython が使われています。scikit-learn の例で言うと、例えばツリー系のアルゴリズムを実装したこのスクリプトは Cython によるものですね。

また逆の方向として、Python で書いたライブラリを C/C++ コードから手軽に呼び出したい、という時にも Cython を使うことができます。双方向のラッパーとして機能するのですね。今回の記事では、この方向で Cython を使うための簡単な例を紹介していきます。Cython の文法については詳しくは書かないので、ドキュメントもしくはデモコードなどを見ていただけるとよいと思います。

続きを読む

Python の defaultdict には注意しよう

こんにちは。

Python には標準的なデータ型に加えていくつかの便利な型が用意されています。特に collections モジュールには、以前記事に書いた deque や、今回取り上げる defaultdict が格納されています。

通常、辞書型のデータ d にデフォルト値を設定しながら値を詰めていく場合、d.setdefault(key, default_value) といったやり方をするのではないかと思います。このようにしない場合は、例えば d に保存されていないキー k で辞書にアクセスしてしまうと、KeyError が出てしまうのですね。

同様の用途で、より柔軟かつ(おそらく)高速な処理が実現できるのが defaultdict です。

続きを読む

SQLAlchemy + PostgreSQL で Upsert を行う(ユニークキーに重複があるデータのバルクインサート)

こんにちは。吉田弁二郎です。

タイトルにある Upsert とは、Update or Insert のことです。あるテーブルにデータを insert しようとするとき、ユニーク制約が効いているキーが過去データのものと重複して insert できない場合、update に切り替える処理のことですね。データ量が多くキー重複の懸念がある状況で multiple insert したい場合などに有効な手段の一つです。

私はよく PostgreSQL を使うのですが、Python 経由で操作したい時には psycopg2 とか SQLAlchemy を選ぶことが多いです。特に SQLAlchemy はオブジェクト的にデータベースを操作できるため、web アプリを開発する時に使っています。

今回は、PostgreSQL 9.5 以上で利用可能な upsert 構文 ON CONFLICT ... DO UPDATE を SQLAlchemy (>= 1.1) から使う方法について書いていきます。

続きを読む

Python のリスト操作は collections.deque が速い

こんにちは。吉田弁二郎です。

先日タスクスケジューラを Python で実装することがあり、深さ優先探索の方針で作業を進める必要がありました。その際、リストの先頭からデータを取り出し先頭にデータを入れる、ということをやったのですが、デフォルトの list ではなく collections.deque を使うと遥かに効率的に動作することを知ったので共有したいと思います(かなり旧聞にあたる内容ですが、ご容赦ください)。

続きを読む

Pandas メジャーアップデート(0.20.1)の要点〜高速 I/O、集約関数強化など

こんにちは。吉田弁二郎です。

先日(5月5日)、pandas の最新版 0.20.1 がリリースされました。agg/transformメソッドがgroupbyしなくても使えるようになり、10倍以上高速な I/O を実現する feather-format が(試験的に)導入され、スライスの際に頻繁に利用されていた.ixインデクサが deprecated となるなど、全般的に着実な改善もしくは変更がされている印象です。以下、リリースノートのハイライト部分より、目についたものをピックアップしていきます。

続きを読む

GPU 版 TensorFlow 環境を AWS 上にコマンド一発で立ち上げるスクリプトを書きました

こんにちは。吉田弁二郎です。

前置き

最近、TensorFlow のインストールは pip により簡単にできるようになりました。一方で GPU 環境の整備(CuDNN の準備等)が相変わらず面倒だと思うことも多く、GPU 自体の進歩も早いのでオンプレ環境に手を出すのも少しためらわれる感じもします。そこで Amazon Web Services (AWS) の GPU インスタンスを使ってみるものの、毎回ゼロから手作業で TensorFlow 環境を構築するのもそろそろ効率的にしたい、という状況になっています。

そんな訳で、コマンド一発で環境構築するための自動化スクリプトを書きました。もしかしたら誰かがやっているかもしれませんが気にしない。

やり方としては、Ansible を使います。Ansible はエージェントレスな構成管理ツールなどと言われ Web 系の人たちが使っていますが、要するにサーバ上でのディレクトリ作成やソフトウェアのインストール等を自動化するものです。リモートマシン、ローカルマシンのそれぞれに Python2 が入っていれば pip install ansible で使い始めることができます*1

ここでは、Ubuntu Server 16.04 LTS (HVM) を選択し(=あらかじめ GPU 開発環境が設定されていない)、最小限の工数で済ませるために nvidia-docker を使い、TensorFlow の docker image を取得することを大きな方針とします。

(2017.06.19 追記)
こんな AMI が登場したので、もはやこれでよさそうです。笑
AMI 自体が有料ではありますが(本記事の方法では、AMI は無料となります)。
AWS Marketplace: Deep Learning AMI Amazon Linux Version

*1:Python3 対応もされ始めているものの、現状は2系で安定稼働します。今回書いたコードも Python2 で動かすことを前提としています。ただ、Ansible を動かすために2系が必要というだけなので、数値計算用に3系が独立して存在していても問題ないはずです。

続きを読む