2006年7月アーカイブ

VS2005 C++/CLI で、アンマネージなライブラリを使う場合、ライブラリの関数の引数がアンマネージな文字列型(char*, wchar_t*, LPSTR, LPWSTR)の時がある。そんな時に必要な変換。
using namespace System::Runtime::InteropServices;	//Marshal使うから

//変換元
String ^srcStr = "Hello";

//char*
char* dstChar;
dstChar = (char*)(void*)Marshal::StringToHGlobalAnsi(srcStr);

//wchar_t*
wchar_t *dstWchar_t;
int strLen = srcStr->Length;
dstWchar_t = (wchar_t*)malloc((strLen+1)*sizeof(wchar_t));
for(int i = 0 ; i < strLen ; i++) {
  dstWchar_t[i] = srcStr[i];
}
dstWchar_t[strLen] = '\0';

//LPSTR
LPSTR dstLPSTR;
dstLPSTR = (LPSTR)dstChar;

//LPWSTR
LPWSTR dstLPWSTR;
dstLPWSTR = (LPWSTR)dstWchar_t;
wchar_t* への変換だが、文字数が高々知れてるのならば、malloc を使わずに
wchar_t dstWchar_t[100];
ってすればよい。
SmartOCR とは
・日本語対応OCRソフト。
 (OCRとは、光学文字認識(Optical Character Recognition) のこと。つまり、画像の中の文字をテキストとして認識してくれるもの)
・認識率の高さと Lite Edition がフリーなことで、有名になった。
・Lite Edition の他に Professional Edition や SmartOCR Library SDK の販売も行っていた。
・しかし、開発元である スマートリーディング が解散してしまったために今では手に入らない。


SmartOCR Lite Edition を試しに使ってみた。
ちなみに設定はすべてデフォルト(文字位置や文字方向は自動認識)。

SmartOCR01.jpgスクリーンショット(クリックで拡大)
左が元画像で右が認識結果。
"一時的に"が"一時的促"になっているが、その他は正しく認識されている。

SmartOCR02.jpgスクリーンショット(クリックで拡大)
メインの文字の"飲めないのに、お中元でビール・・・・・・いくらで売れる?"は正しく認識されている。
右の"今も、誰かがトクしてる。"とか"オークション"という文字は認識できていない。
あと、傾いた"お中元"という文字や、スロットが回ってるところを、わけの分からん文字として誤認識している。

あと、他にも10枚ぐらい試した。


まとめ
・割と認識率はよいようだ。
・小さい文字は認識しにくい。
・やっぱ、漢字は誤認識がどうしても起こるようだ。
・背景と文字のコントラストが低いと文字として認識できない時がる。
・背景の周波数が激しい箇所が、わけの分からん文字として誤認識する。
・フォントが特殊だと誤認識しやすい。


これだけのものをフリーで提供しているのはすごい。
オープンソースで開発されている OCR があるようだが、どれも日本語に対応していないし。

SDK を販売していたそうだが、今は手に入らないのが悔やまれる(いくらで売ってたのかは知らないけど)。
他の 日本語対応OCRソフト の SDK は、くそ高い(20万円以上とか)ので手が出ない。
個人で OCR 組み込んだプログラム作るのは無理ってことかー?!
サポートベクターマシン(以下 SVM) とは
・ニューラルネットワークの一種
・教師ありクラスタリング

SVM の基本的な考え方
・元々2クラスの線形分離手法として提案される
・単層パーセプトロンに似ているが、SVM はマージン最大化という手法をとっているのがポイント。
・マージン最大化とは、超平面と学習データの隙間となるマージンをなるべく大きく取ろうというもの。
 (ここでいう超平面とは、2つのクラスにぶった切る平面のこと)
・ちなみに超平面と、ちょうどマージンの分だけ離れている学習データをサポートベクトルという。
・このマージン最大化という考えを取り入れることによって、テストデータの識別精度を高めている。


SVM の発展
・線形分離不可能な問題への対応
 - ソフトマージン(学習データが多少マージンにくい込んだり、反するクラスの空間にくい込んだりしても許す)で対応
  (↑まだ、超平面自体は線形であることに注意)
・非線形問題への対応
 - カーネルトリックにより非線形な問題も対応
  (ちなみに、PCA(主成分分析)や部分空間法もカーネルトリックにより、非線形に拡張可能)
 - このカーネルトリックにより SVM の精度が飛躍的に向上し、SVM がメジャーになった。
・2クラスより多いクラスタリング問題への対応
 - 複数のSVMを組み合わせることにより対応


SVM の利点
・データの特徴量の次元が大きくなっても識別精度がよい(マージン最大化のおかげ)
 - 一般的にデータの特徴量の次元をむやみに増やすと識別精度が悪くなる(ヒューズの現象、球面集中現象)。
  なので、本来次元数の数倍の学習データを用意しなければいけないとされている。
  しかし、SVM は特徴量の次元数が大きくても対応できるため、画像認識の分野で頻繁に使われる。
  (文字認識の問題では、元の画像をグレースケールにして 20x20Pixel に正規化して、そのまま400次元の特徴量として SVM にぶち込んでやるという手法もとられている。)
・最適化するべきパラメータが少ない
 - ニューラルネットワークでは、良い精度を得るためにパラメータを試行錯誤して決定する必要があるが、SVM では割と簡単に最適なパラメータが求められる。

SVM の欠点
・学習データが増えると計算量が膨大となる
 - 特徴量の次元は大きくても対応できるが、学習データ数が増えるとタイヘン。
・基本は2クラスの識別の手法
 - 複数のSVMを組み合わせることで多クラスの識別が可能だが、多クラスを考慮に入れた識別関数の最適化をすることができない。

参考 : 前田英作, "痛快! サポートベクトルマシン ~古くて新しいパターン認識手法~", 情報処理学会誌, Vol.42, No.7, pp.676-683, (2001).
    http://www.neuro.sfc.keio.ac.jp/~masato/study/SVM/index.htm
    とか、あといろいろ見たよ。



実際に計算してみよう!
パッケージとしては、"LIBSVM"と"SVMlight"が有名なようだ。
http://www.bi.a.u-tokyo.ac.jp/~tak/svm.html
R(オープンソースの統計処理ソフトウェア) のインタフェースが用意されているということで、LIBSVM を選択。
http://www.csie.ntu.edu.tw/%7Ecjlin/libsvm/
LIBSVM は、R の"e1071"というパッケージに入っています。

パラメータをどのように設定したらいいかは以下の pdf を参照。
http://www.csie.ntu.edu.tw/~cjlin/papers/guide/guide.pdf

e1071 の仕様は以下の pdf を参照。
http://cran.r-project.org/doc/packages/e1071.pdf

e1071 を使ったサンプル
http://www.csie.ntu.edu.tw/%7Ecjlin/libsvm/R_example
(↑とか、e1071.pdf のサンプルとかを実際に入力して練習してみるといいよ)

LIBSVM の FAQ
http://www.csie.ntu.edu.tw/%7Ecjlin/libsvm/faq.html


最適なパラメータの探し方
・主に精度の良し悪しを決めるのは kernel の選び方と γ(gamma) と C(cost) の設定である。
・上の guide.pdf を参考にすると設定法は以下となる
 - kernel はデフォルトの RBF 一択でOK。
 - γとC は、grid serch により最適な値をヒューリスティックに探す。
  grid serch は、例えば調べる値を γ=(0.5, 0.25) C=(1, 2, 4)として入力したら、
  (γ,C) = (0.5, 1),(0.5, 2),(0.5, 4),(0.25, 1),(0.25, 2),(0.25, 4)
  の 6 種類すべて、cross-validation(または、bootstrap) で性能評価し、一番制度の良いものを提示してくれる。
  (e1071 では、grid serch を tune という関数で行う。)
 - 最初は大雑把な値で、次に詳細な値で、探すといいよ(coarse to fine(祖から密へ) の考え方で)。
 - ただし、特徴量の次元がバカでかい(数千次元)などの特別な場合は、他の手法を取る必要があるよ。

その他のパラメータについて
・type について
 - "C-classification" と "nu-classification" の違い
  FAQに該当箇所がある
  http://www.csie.ntu.edu.tw/%7Ecjlin/libsvm/faq.html#f411
  基本的には同じということだし、デフォルトが"C-classification"だし、教科書的な方法は"C-classification"みたいだし(詳しくは以下の pdf 参照)、デフォルトままでよさそう。
  http://www.csie.ntu.edu.tw/~cjlin/papers/libsvm.pdf
・scale について
 - デフォルトのTRUE だと、すべての特徴量の次元ごとでスケーリング(正規化)を行う。
 - 特徴量の次元ごとに重みを変えたい場合は、scale を FALSE にして、自分で重みを考慮したスケーリングすると調整するとできるのかな?
・class.weights について
 - クラスの重みを変えることができる。
 - 例えば、犬の画像と猫の画像をクラスタリングすることを考える。
  自分は犬の画像が大好きなので、犬の画像にクラスタリングされる画像が欲しいのだが、
  一枚の犬の画像も見逃したくはない、という場合に犬のクラスタの重みを大きくする。
  すると、犬の画像が猫の画像だと誤認識される確率は減り、犬の画像の再現率が上がる。
  でも、猫の画像が紛れ込む可能性が上がるけどね。
  という感じにクラスの重みを調整できる。


type パラメータについてもっと詳しく
・"C-classification" (or "nu-classification") (分類)について
 - 普通のクラスタリング問題の時に使う。
 - 例えば、犬の画像と猫の画像のクラスタリング問題を考えると
  テストデータの予測(predictの)結果は、犬クラスか猫クラスかという2値(2クラスタなので)で出力される。
・"eps-regression" (or "nu-regression") (回帰)について
 - 上の"C-classification"では、テストデータの予測結果は、犬クラスか猫クラスかという2値で与えられるが、
  このパラメータを使用すると、予測結果は数値として出力される。
  つまり、そのテストデータがどれくらい犬クラス(猫クラス)として尤もらしいかを知りたい時に使用する。
 - ラベルは数値で与える。
 - 例えば、学習データの犬の画像に -1、猫の画像に 1 のラベルを与えたとする。
  すると予測(predictの)結果は -0.10516366 や -0.80516366 という値として出力される。
  両方とも犬クラスとして判定されたことになるが、前者(-0.10516366)より後者(-0.80516366)の方が、犬の画像として尤もらしいことが分かる。
  なお、0 より小さい値を犬クラス、0 より大きい値を猫クラスと判定すれば、"C-classification" と同じことになる。
  たぶん。
・"one-classification" (1クラスSVM)について
 - 1つのクラスとその他にクラスタリングしたいときに使用する。
 - 例えば、種々雑多な画像群から犬の画像だけ取って来たい場合
  犬の画像のみで学習し、犬の画像とそれ以外の画像にクラスタリングする。
 - e1071 では、ラベルの引数を与えずに 関数svm でモデルを作れば、
  自動的に type="one-classification" となり、1クラスSVM となる。


SVM 使った感想
・精度タケー!
FFmpeg とは、オープンソースで開発されている動画エンコーディングパッケージである。
動画のエンコーディング/コーデック変換をする ffmpeg、動画再生をする ffplay、動画配信のためのサーバーである ffserver を提供する。
http://ffmpeg.mplayerhq.hu/index.html

ffmpeg の利点
・エンコードが速く、対応フォーマットも多い。
・コマンドラインから使えるために自作のアプリケーションから呼び出して使える。
 ("携帯動画変換君"や"Riva FLV Encoder"の中でも使われている。)
・動画のエンコーディング/デコーディングを担当するライブラリである libavcodec も直接利用可能。
参考 : http://megaui.net/oss4art/wiki/FFmpeg
    http://www.xucker.jpn.org/pc/ffmpeg_install.html


試しに使ってみた。
自分でコンパイルするのが面倒なので、"携帯動画変換君"をダウンロードして、その中から ffmpeg.exe を引っこ抜いてきた。

コマンドラインで
ffmpeg -i input.avi -f mov output.mov
と入力。
avi形式である input.avi を mov形式の output.mov に変換できた。
うおー!
参考 : http://www.nurs.or.jp/~calcium/wiki/index.php?ffmpeg%20usage

でも、wmv → avi に変換しようとしたら、エラーが起きて実行できなかった。
どうやら、パラメータとかちゃんと指定してやらないといけないらしい?
自己組織化マップとは
・ニューラルネットワークの一種
・教師なしクラスタリング(k-means法に動作が似ている)
・多次元のデータを圧縮して低次元(2次元)にマッピングするもの。(そういう意味では、非線形の主成分分析+クラスター分析とも言える。)
・多次元データを2次元にマッピングできることから、多次元データの可視化にも使われる。


実際に計算するには
・文献などでは、パッケージとして SOM_PAK が有名だが、R(オープンソースの統計処理ソフトウェア)の方が日本語のドキュメントも多く、分かりやすい。
RでSOM(自己組織化マップ) の関連リンクにある pdf の "Rと自己組織化マップ" というのが分かりやすい。


学習のパラメータについて
以下、コホネン先生著の"自己組織化マップ"より、ものすごくテキトーに抜粋
・単調減少関数は、線形的でも反比例的でも指数的でもさほど問題ではない。
・学習回数は、最低でもユニット数の500倍。
・学習回数はユニットの数に依存し、学習データの数には依存しない。
・半径の初期値は、マップが断片的にならないようにネットワーク全体の直径以上。
・フェーズを2つに分けて学習する場合(マップの断片化を防ぐために)
 -最初のフェーズでは、大域的な学習を行う。1000ステップぐらいで α=0.9 など α は 1 に近い値がよい。
 -次のフェーズで、微調整を行う。学習回数は長めに設定する必要がある。α は 0.02 より小さな値に達するようにする
・ユニットの初期値が乱数ではなく大まかな入力密度関数に適応した初期値(順序付けられた状態)で開始できる場合、近傍関数が狭く、かつ α=0.2 とか 0.1 のような低い値であっても、学習過程は急速に収束する。

このアーカイブについて

このページには、2006年7月に書かれたブログ記事が新しい順に公開されています。

前のアーカイブは2006年6月です。

次のアーカイブは2006年8月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

プロフィール

profile.jpg

モローチョ(moro-tyo)

Webエンジニア。

詳しいプロフィール

このblogのはてブ

Powered by Movable Type 4.1