SVM LIBSVM - eiichiromomma/CVMLAB GitHub Wiki
(SVM) LIBSVM
grid.pyを並列コンピューティングで使う
(toolsで提供されているグリッドサーチのPythonスクリプトgrid.pyを利用)
- 全てWindowsマシン(Linuxの場合はcygwin関係を飛ばす)
- sshは使い慣れたcygwinのを利用
- host1がローカルマシン。host2以降は同一セグメント上に繋れている
- 全てにcygwinがインストール済み
- host2以降はcygwinのsshdもロック解除等設定済み
- host2以降にはパスフレーズでログイン可能。
- host1にPythonがc:\Python26へインストール済み
- host1にgnuplot for windowsがc:\local\gnuplotにインストール済み
- LIBSVMは全てc:\local\libsvm-2.89に存在
※本来はNFS等で共通のディレクトリを使っているのが理想だが、面倒なので共有して同じファイルを放り込むのが手っ取り早い。
- svmtrain_exe、gnuplot_exeをローカルマシン向けのフルパスで記述
- ssh_workersがsshで実行する対象のホスト名Listになるので、ホスト名をプロセス数だけ列挙
- nr_local_workerがローカルマシンでのプロセス数
- SSHWorkerの内容をcygwin形式のパスに変更
class SSHWorker(Worker):
def __init__(self,name,job_queue,result_queue,host):
Worker.__init__(self,name,job_queue,result_queue)
self.host = host
self.cwd = "/cygdrive/c/local/libsvm-2.89/windows/"
self.svmtrain_exe = "/cygdrive/c/local/libsvm-2.89/windows/svm-train"
def run_one(self,c,g):
cmdline = 'ssh -x %s "cd %s; %s -c %s -g %s -v %s %s %s"' % \
(self.host,self.cwd,
self.svmtrain_exe,c,g,fold,pass_through_string,dataset_pathname)
result = Popen(cmdline,shell=True,stdout=PIPE).stdout
for line in result.readlines():
if find(line,"Cross") != -1:
return float(split(line)[-1][0:-1])
※著作権は作者であるChih-Chung Chang and Chih-Jen Linに帰属します
- ホスト | コア数
- host1 | 4
- host2 | 2
- host3 | 6
- host4 | 6
- host5 | 6
スクリプト実行中はパスフレーズ無しでログイン出来る状態にしなければならないので、ssh-agentを使う。 cygwinのbashを開き
eval `ssh-agent`
ssh-add
とし、パスフレーズを入力。
cd /cygdrive/c/local/libsvm-2.89/windows
/cygdrive/c/Python26/python.exe ../tools/grid.py LIBSVM用の学習データ
を実行。
分散コンピューティングが不要な程度の規模のデータを用いた場合、挙動が怪しいのでshuttle.scaleあたりでテストすると良い。
LIBSVMを並列化する
--- C:/local/orglibsvm-2.9/Makefile.win Wed Dec 03 15:39:58 2008
+++ C:/local/libsvm-2.9/Makefile.win Tue Mar 02 15:46:27 2010
@@ -7,7 +7,7 @@
PYTHON_LIB = c:\python26\libs\python26.lib
##########################################
CXX = cl.exe
-CFLAGS = -nologo -O2 -EHsc -I. -D __WIN32__ -D _CRT_SECURE_NO_DEPRECATE
+CFLAGS = -nologo -O2 -EHsc -I. -D __WIN32__ -D _CRT_SECURE_NO_DEPRECATE -openmp
TARGET = windows
all: $(TARGET)\svm-train.exe $(TARGET)\svm-predict.exe $(TARGET)\svm-scale.exe $(TARGET)\svm-toy.exe
--- C:/local/orglibsvm-2.9/svm.cpp Wed Aug 19 20:50:50 2009
+++ C:/local/libsvm-2.9/svm.cpp Tue Mar 02 15:46:01 2010
@@ -6,6 +6,7 @@
#include <string.h>
#include <stdarg.h>
#include "svm.h"
+#include <omp.h>
int libsvm_version = LIBSVM_VERSION;
typedef float Qfloat;
typedef signed char schar;
@@ -1267,6 +1268,7 @@
int start, j;
if((start = cache->get_data(i,&data,len)) < len)
{
+#pragma omp parallel for private(j)
for(j=start;j<len;j++)
data[j] = (Qfloat)(y[i]*y[j]*(this->*kernel_function)(i,j));
}
@@ -2481,6 +2483,7 @@
int l = model->l;
double *kvalue = Malloc(double,l);
+#pragma omp parallel for private(i)
for(i=0;i<l;i++)
kvalue[i] = Kernel::k_function(x,model->SV[i],model->param);
Visual StudioツールのコマンドラインからLIBSVMのフォルダに移動して
nmake /f Makefile.win
とする。プログラムはwindowsフォルダに作られる。
grid.pyによるグリッドサーチをする場合には、OpenMPを使っていないsvm-*の方が効率が良いかも(?)