A certain engineer "COMPLEX"

.NETで機械学習を試してみる libsvm.net編 第1回

Introduction


機械学習といえば猫も杓子もディープラーニングって感じですが、ディープラーニングを使うにはちょっと重すぎるという場合に、まだまだいけるのが Support
Vector Machine (SVM)
です。
.NETでSVMを扱えるライブラリはそこまで多くありません。

  • Accord.NET
  • KMLib
  • LibSVMsharp
  • libsvm.net
  • libsvm.clr

位が簡単に見つかるところです。
dlibでもsvmは扱えますが、ラップ処理が終わっていませんのでdlib.netでは扱えません。
(テンプレートを.NETを移植するのは本当に辛いです)

今回は、libsvm.netを使います。
libsvm.netはlibsvmのC#ラッパーです。
libsvmはwikipediaによれば、

LIBSVMおよびLIBLINEARは広く使われるオープンソースの機械学習ライブラリである。両方とも国立台湾大学で開発され、C言語APIを用いたC++で記述されている。

とあります。
2000年あたりから開発されているようで、現在でも開発が続いています。
(最終更新は2016年12月!!)

ソースは下記になります

Get Started


libsvm.netを使うには下記の作業が必要です。

      1. Nugetからlibsvm.netのインストール

以上!!!

で完了です。

Sample


SVMといえば、2値判定が有名ですが、多値判定も可能です。
今回は多値判定をテストします。

ただし、libsvmは遅いです。これは今後解説しますが、データが線形で分類できるなら、liblinearの使用をお勧めします。
公式ページにも

When to use LIBLINEAR but not LIBSVM
There are some large data for which with/without nonlinear mappings gives similar performances. Without using kernels, one can quickly train a much larger set via a linear classifier. Document classification is one such application. In the following example (20,242 instances and 47,236 features; available on LIBSVM data sets), the cross-validation time is significantly reduced by using LIBLINEAR:

LIBSVMではなくLIBLINEARを使用するとき
非線形マッピングが有無に関わらず、近似したパフォーマンスが得られる巨大なデータがあります。カーネルを利用しない場合、線形分類器を通じて非常に大きなデータセットを高速に訓練できます。ドキュメント分類はそのアプローチの一つです。下記のサンプル (20,242インスタンスと47,236の特徴量; LIBSVMで利用可能なデータセット) において、LIBLINEARを使用することで交差検定の時間を大幅に減らしています。 (注:345.569sが2.944sと170倍の性能をたたき出しています!!)

また、libsvm.netの弱点として、IKVM.NETを利用しているため、libsvmをダイレクトに利用するより遅くなる、という弱点があります。
今回は単純な訓練なので、そのままlibsvmを使います。

まず、学習データについて。
libsvm.net、というかlibsvmは、学習データをテキスト形式で用意します。
各学習対象データを整数または小数のベクトルで表現します。
例えば、

0.334343 0.7080 -23222 0 54544

というデータがある場合、

と表現します。
libsvmにおいて、0という値は無視することができます。
そのために、ベクトル内の各値の先頭に1から始める要素番号を付与することで、0をスキップしたことを認識することができます。
1行1データとして学習データを生成します。
そして、大事なことですが、labelは整数または小数で指定します。さもなくばクラッシュします。文字列なんか使えません。

今回のサンプルでは、テストデータの生成も含んでいます。
内容は、

  • 0以上10未満の小数を 0 から 9 の整数に分類

というもの。
例えば、0.5455は0、8.9843は8というような感じです。

ソースを見てもそこまで難しいことはしていません。
そして、実行すると下記のような出力を行います。

10クラスで学習データが5000、テストデータが1000で、毎回99.0%以上の精度を叩き出します。
100%で欲しかったところですが、まぁまぁでしょう。

Conclusion


簡単にSVMを試すことができて良い感じではあります。
ただ、機械学習系のライブラリは、ここ最近Pythonのが手軽な感じが否定できません。
もう少し日本語のドキュメントやC#のライブラリが充実してくれると良いのですが....

Source Code


https://github.com/takuya-takeuchi/Demo/tree/master/SVM1

開発メモ その110 Debian with Raspberry Pi Desktop on VirtualBoxでWebCamがselect timeoutで使えない

Introduction


WebCamをVirtualBox上のゲストOS Debian with Raspberry Pi Desktop に接続してキャプチャをしても動かない件。
具体的には、

と表示され何も動作しない。

Resolution


下記のページが参考になりました。

USB 2.0 camera error on Virtual Machine (Virtual Box, VMWare) in Open CV : Farshbaf.NET Artificial Intelligence Blog</title> <title>USB 2.0 camera error on Virtual Machi...
As who loves embedded system development and Image processing all together, I decided to run my Open CV programs on an embedded Linux systems. For my...

I have change the usb setting in VM ware settings and make it to support USB 3.0.
On the other hand I attached the camera to a USB 2.0 port and that works both of them

要するに、

  • USB 3.0をサポートするように仮想マシンの設定を変更
  • カメラをUSB 2.0ポートに接続

ということ。
仮想マシン設定のUSBから USB 3.0 (xHCI) コントローラーに変更すればOKです。

これでうまく動きます。
コードは下記です。

ただ、上のコードだと保存される画像が、960x544になっていました。

これは、指定したサイズがカメラでサポートしているサイズではなかったためです。
恐らく指定したサイズに何かしらのルールで近しいサイズに強制的に変更していると思われます。
テストしたカメラには、確かに960x544というサイズがありました。

開発メモ その109 Debian with Raspberry Pi Desktop on VirtualBoxでUSB機器を有効にする

Introduction


VirtualBoxを使うメリットでゲスト側でUSB機器を使えることにあります。
Hyper-Vでも使えないことはないのですが、RemoteFX USB リダイレクトとかよーわからないテクノロジーを使わないといけません。
ましてやゲストOSがWindows 10 Enterprise限定。こんなのおかしいよ!!

じゃぁVirtualBoxでUSB機器を使うのが簡単か?というとそうでもない。

What's problem?


通常、仮想OSウィンドウの右下にあるUSBアイコンから認識したいUSB機器を選択すればよいのだが、それが失敗する。

何がダメなのか詳しいメッセージをください...

How to use USB device?


ゲストOSの拡張コンポーネントExtension Packをインストールする必要があります。

Download

まず公式からダウンロードしてきます。

Install

続いてインストール。
ファイル -> 環境設定からダイアログを開き、機能拡張タブを選択します。

右側の+ボタンを選択し、ダウンロードしてきたファイルを選択します。

ライセンス条項は、最下段までスクロールしないと同意できません。

Enable USB

インストールできたらUSBを有効にします。
次は、ゲストOSの設定からUSBを選択します。ゲストOS起動中には使えません。

右側の+ボタンから追加したいデバイスを選択、追加します。

機器によっては、USB 3.0 (xHCI) コントローラーを選択しないとゲストOSが認識してくれません。
上の画像のIntel Realsenseがまさにそれです。
実際のデバイスがUSB 3.0ポートにつながっているかどうかは関係ないです。

設定完了後、ゲストOSを起動して、先述のエラーメッセージが表示されなければ成功です。

開発メモ その108 Debian with Raspberry Pi Desktop on VirtualBoxでGuest Additionsを追加する

Introduction


VirtualBoxでもHyper-Vのゲスト拡張機能のようなものが用意されています。

How to install?


VirtualBox上のDebian with Raspberry Pi Desktopへの拡張インストールは下記が詳しいです。

Raspbian x86 on VirtualBox on a Windows PC
How to run a Raspberry Pi desktop as a virtual machine on your Microsoft Windows PC or laptop.

ちなみに先にssh接続できるようにしておくと、コマンドをコピペできるので間違えなくて済みます。

まず、次のコマンドでDebianのリポジトリを使用可能にします。どうもRaspbianのGuest Additionsは長らくメンテされていない模様。

ちなみに、apt-keyは下記の引数でproxyを指定することができます。会社とかのセキュアの環境ではこれが必要になるでしょう。

そしてインストール。

これで拡張機能が使えます。

開発メモ その107 Debian with Raspberry Pi Desktop on VirtualBoxにssh接続

Introduction


Windows10のVirtualBox上に構築したDebian with Raspberry Pi Desktopに対して、ssh接続するのに少し嵌ったのでメモ。

How to do?


VirtualBox内の仮想マシンに外部からアクセスする場合、VirtualBoxのネットワーク設定をNATにした上で、指定したポートを仮想マシンにポートフォワードする必要がある。
通常、sshは22で待ち受けるので、ホストPCへの22宛の通信をゲストOSの22へフォワードすればよい。

が、これがうまくいかない。
外から、sshでホストPC宛に接続を試みても、

というエラーが返ってくる。
そこで、下記のコマンドで、sshの接続に失敗したログを見てみる。

しかし、ログそのものが出力されていない。
こうなると、そもそもssh接続が仮想マシン側に到達していない、と考えるとが筋である。

なので、ポートフォワーディングを

のようにし、22ポート以外に変更する。
ssh接続も

に変更する。

こうすると上手くいった。

Why?


ポートフォーワーディングは転送元ポートと転送先ポートが同じでも問題ないはずである。
なのにそれが失敗したのは、ホスト側で別のアプリが22でLISTENしていたからだと考えられる。

なので、ホストPCでLISTENしているポートを調べてみた。
外部から22ポート宛にssh接続してみる。

なんか22ポート使っている奴がいる...
Windows10端末で22ポートで待ち受けするアプリなぞ思い当たらないので、調べてみた。
下記の記事を発見。

Windows 10でSSH(Secure Shell)サーバーを使う
Windows 10のAnniversary Update(RS1)から、開発者モードをオンにすると、SSHサーバーが起動するようになっている。

上の記事によると、

ハッキリしているのは、Windows 10(Desktop、Mobile、IoT)で開発者モードをオンにすると、SSH関連の2つのサービス(SSH Server Broker、SSH Server Proxy)が起動するようになるということだ。

確かに動いています。
気づかなかった...

とりえあず、Windows10端末でssh接続する予定はないので、この2つのサービスの自動起動を無効、停止しました。