SVM LIBSVM - eiichiromomma/CVMLAB GitHub Wiki

(SVM) LIBSVM

グリッドサーチ

grid.pyを並列コンピューティングで使う

(toolsで提供されているグリッドサーチのPythonスクリプトgrid.pyを利用)

前提

  1. 全てWindowsマシン(Linuxの場合はcygwin関係を飛ばす)
  2. sshは使い慣れたcygwinのを利用
  3. host1がローカルマシン。host2以降は同一セグメント上に繋れている
  4. 全てにcygwinがインストール済み
  5. host2以降はcygwinのsshdもロック解除等設定済み
  6. host2以降にはパスフレーズでログイン可能。
  7. host1にPythonがc:\Python26へインストール済み
  8. host1にgnuplot for windowsがc:\local\gnuplotにインストール済み
  9. LIBSVMは全てc:\local\libsvm-2.89に存在

※本来はNFS等で共通のディレクトリを使っているのが理想だが、面倒なので共有して同じファイルを放り込むのが手っ取り早い。

grid.pyの変更

変更点

  1. svmtrain_exe、gnuplot_exeをローカルマシン向けのフルパスで記述
  2. ssh_workersがsshで実行する対象のホスト名Listになるので、ホスト名をプロセス数だけ列挙
  3. nr_local_workerがローカルマシンでのプロセス数
  4. 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

スクリプト実行中はパスフレーズ無しでログイン出来る状態にしなければならないので、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あたりでテストすると良い。

OpenMPで並列化

LIBSVMを並列化する

変更箇所

Makefile.win

--- 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

svm.cpp

--- 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-*の方が効率が良いかも(?)

⚠️ **GitHub.com Fallback** ⚠️