読者です 読者をやめる 読者になる 読者になる

Bag of ML Words

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

Python: シリアライズって、偉大だったんだ・・・

今までずっと*1学習したモデルとかは

パラメータをテキストに書き出して再度読み込ませていました。

 

が、それってダメだったんですね。

いや、ダメじゃないんだけど。

 

シリアライズ、覚えました。

 

経緯

今、scikit-learnのSVMパッケージ

http://scikit-learn.org/stable/modules/svm.html#svm

を使っているのですが、それで沢山のSVMモデルを学習して、

後で再利用するということが必要です。

 

そこで、SVMインスタンスの内部パラメータをファイルに書き出して再読み込みしようとしたところ、動きませんでした。

 

幸い、近くにscikit-learnのコントリビュータがいるのでどうすればいいか聴いたところ、

シリアライズしなよ

ということでした。

 

scikit-learnにおける、モデルのシリアライズのやり方

http://scikit-learn.org/0.10/tutorial.html#model-persistence

に書いてありますが、これは少し冗長なようです。

以下で十分。

>>> from sklearn import svm
>>> from sklearn import datasets
>>> clf = svm.SVC()
>>> iris = datasets.load_iris()
>>> X, y = iris.data, iris.target
>>> clf.fit(X, y)
SVC(C=1.0, cache_size=200, coef0=0.0, degree=3, gamma=0.25, kernel='rbf',
  probability=False, scale_C=False, shrinking=True, tol=0.001)

>>> from sklearn.externals import joblib # do seriarize >>> joblib.dump(clf, 'svm.learned')
>>> .....
>>> clf2 = joblib.load('svm.learned') # do deseriarize

 

 

シリアライズのご利益

  • 早い: バイナリなので、読み込みも書出しも早いです。
  • 軽い: 例えば実際の局面では10000次元程度の線形SVMをつかったのですが、svmインスタンスのパラメータ全てをテキストに書くと259K byte。いっぽうシリアライズしたモデルは799 byte。300分の1になってる・・・
  • 間違いが起こらない: 自分でモデルのパラメータをテキストファイルに書き出して、再度読ませると、その読み書きのメソッドを書く過程でバグが混入します。でもシリアライズだとそのままオブジェクト(インスタンス)を再現するのでそんな事が起こります。安心です
  • 簡単に状態を再現できる: 上記の理由から、例えば学習中のモデルとか、事後分布と全パラメータの最終結果なんかを、簡単にプログラム内で再現させることができます。特に、ライブラリにモデル化をお任せしている場合には有効ですね。

シリアライズのあかんところ

まだ、こういう状況に遭遇していませんが、きっと以下のような問題があります

  • 人の目で読めない: バイナリなので。例えばこれはどんな特徴量が効いているのかな、とか、クラスタリング結果はどうなのかな、とかの時に、いちいちプログラムを起動して、プログラム内で読ませないといけません。
  • その言語(プログラム)じゃないと読めない: Javaの計算結果をシリアライズしても、それをmatlabPythonに持って行ってよむことができません*2。さらに言えば同じJavaでも、まったく同じクラス構造を定義していなければ読めません。自分の研究専用の実装とかでやっていると、あまり嬉しくないのかも・・・??

 

結論

たとえばMCMCの計算過程を途中でシリアライズしてdump, 別の温度のMCMCに放り込んで、とかはすごくやり易くなりますね。あとデータサイズ小さいなら、例えばmatlabPythonならば、今までの結果保存に加えて最終結果のシリアライズinstanceがあればお絵かきや評価などもやり易いかも知れません

*1:Javaとかの時も

*2:や、ひょっとしたら出来るのかも知れないけど