LoginSignup
4
3

More than 5 years have passed since last update.

Pylearn2でMaxout + CNNを使う

Last updated at Posted at 2014-12-20

Pylearn2 で Maxout + CNN(Convolutional Neural Network) を使ったときにいくつかはまったのでメモ。
GPU必須です。

環境

  • OS: Windows7 64bit
  • Python2.7.8 |Anaconda 2.1.0 (64-bit)
    Python DistributionのAnacondaを使っています。
  • Theano
    公式ページのManual installation に従ってインストールしました。
  • Pylearn2
  • Cuda6.5
  • Visual Studio 2013

準備(Windows用)

以下はWindows環境で必要な設定・修正です。
LinuxやMacでは必要ないかもしれませんが、確認していません。

pthreadライブラリ をインストールする

pylearn2内部でpthreadを使っているのでインストールします。
pthreadなしだと学習時に以下のエラーメッセージを出力します。

pylearn2\sandbox\cuda_convnet\nvmatrix.cuh(39) fatal error C1083: include ファイルを開けません。'pthread.h':No such file or directory

今回は以下のサイトからライブラリをダウンロードしました。
https://sourceware.org/pthreads-win32/

pthreadライブラリへのパスを設定

pylearn2/sandbox/cuda_convnet/pthreads.py でpthreadライブラリへのパスを設定します。
以下に例を記載します。

pthreads.py
from theano.configparser import AddConfigVar, StrParam

AddConfigVar('pthreads.inc_dir',
        "location of pthread.h",
        StrParam("C:\\lib\\pthreads-w32-2-9-1-release\\Pre-built.2\\include"))

AddConfigVar('pthreads.lib_dir',
        "location of library implementing pthreads",
        StrParam("C:\\lib\\pthreads-w32-2-9-1-release\\Pre-built.2\\lib\\x64"))

AddConfigVar('pthreads.lib',
        'name of the library that implements pthreads (e.g. "pthreadVC2" if using pthreadVC2.dll/.lib from pthreads-win32)',
        StrParam("pthreadVC2"))

pthreadVC2.dll を実行ディレクトリに置く

POSIX threadに含まれるpthreadVC2.dllを以下のディレクトリに置きます。
pylearn2/scripts/papers/maxout

pthreadVC2.dllの配置を行わないと以下のエラーが発生します。
これはpydファイルから参照しているdllが見つからないために発生しているエラーです。

DLL load failed:

同様のエラーが発生する場合には、以下のサイトにあるDependency Walkerを使ってpydの依存関係を調べるとよいと思います。
http://www.dependencywalker.com/

cuda_ndarrayライブラリへのパスを通す

Pylearn2による学習時にcuファイルのコンパイルを行うのですが、リンクエラーが発生します。
以下のファイルを修正して、cuda_ndarrayライブラリを読み込めるようにします。

pylearn2/sandbox/cuda_convnet/convnet_compile.py
                    compiler.compile_str('cuda_convnet',
                            code,
                            location = cuda_convnet_loc,
                            include_dirs = [this_dir, config.pthreads.inc_dir] if config.pthreads.inc_dir else [this_dir],
                            lib_dirs = nvcc_compiler.rpath_defaults + [cuda_convnet_loc] + ([config.pthreads.lib_dir] if config.pthreads.lib_dir else []),
-                            libs = ['cublas', config.pthreads.lib] if config.pthreads.lib else ['cublas'],
+                            libs = ['cublas', 'cuda_ndarray', config.pthreads.lib] if config.pthreads.lib else ['cublas', 'cuda_ndarray'],
                            preargs = ['-O3'] + args,
                            py_module=False)
pylearn2/sandbox/cuda_convnet/base_acts.py
     def c_libraries(self):
         if config.pthreads.lib:
-            return ['cuda_convnet', config.pthreads.lib]
+            return ['cuda_convnet', 'cuda_ndarray', config.pthreads.lib]
         else:
-            return ['cuda_convnet']
+            return ['cuda_convnet', 'cuda_ndarray']

学習

Pylearn2のpylearn2/scripts/papers/maxout にある mnist.yaml を使いました。
このファイルで使われている pylearn2.models.maxout.MaxoutConvC01B が Maxout + CNN のモデルクラスです。
MaxoutConvC01B を使うためにはGPUが必要です。
pylearn2/scripts/papers/maxout に移動した後、以下のコマンドで学習を行います。

python ..\..\train.py mnist.yaml

学習後のモデルは mnist_best.pkl に保存されます。

結果の確認

以下のファイルを作成し、
python mnist_result.py mnist_best.pkl
を実行するとテストデータに対する認識結果を確認することができます。
私の環境では 9940/10000 でした。

mnist_result.py
import numpy as np
import pickle
import sys
import theano
import pylearn2.datasets.mnist as mnist
from pylearn2.space import VectorSpace


def simulate(inputs, model):
    space = VectorSpace(inputs.shape[1])
    X = space.get_theano_batch()
    Y = model.fprop(space.format_as(X, model.get_input_space()))
    f = theano.function([X], Y)
    result = []
    for x in xrange(0, len(inputs), 100):
      result.extend(f(inputs[x:x + 100]))
    return result

def countCorrectResults(outputs, labels):
    correct = 0;
    for output, label in zip(outputs, labels):
        if np.argmax(output) == label:
            correct += 1
    return correct

def score(dataset, model):
    outputs = simulate(dataset.X, model)
    correct = countCorrectResults(outputs, dataset.y)

    return {
        'correct': correct,
        'total': len(dataset.X)
    }

model = pickle.load(open(sys.argv[1]))
test_data = mnist.MNIST(which_set='test')
print '%(correct)d / %(total)d' % score(test_data, model)

さらに学習

mnist.yamlで学習した後、mnist_continued.yamlを使って学習を行うと、mnist_best.pklをさらに学習するようです。
学習後のモデルはmnist_continued.pklに保存されます。

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3