「PCソフト『メゾピアノ』開発 2 (2024/06/05)」


「Bを見たらミュートするソフト」、
メゾピアノの解説。第2回。



//説明の為の疑似コード
for (;;)
{
//特定の画面領域をキャプチャーして、
  var bitmap = capture(rect);
  
//ニューラルネットワークで、画像をカテゴリA/カテゴリBに分類。
  var ab = AorB(bitmap)
  
//Aと判定されたら → 何もしない。そのまま映す。
  if (ab==AB.a)
    do_nothing();
//Bと判定されたら → 領域を隠す & スピーカーをミュート。
  else if (ab==AB.b)
    mask_mute();

//スリープ。
  System.Threading.Thread.Sleep(1000);


//もし判定が間違ってたら、ユーザーが指摘を入れる
  if (ab != truth_ab)
  {
    ・データセットのtrain/A、train/Bに追加して、
    ・学習側 train.pyで再トレーニング。
    ・ウェイトの更新
    ・予測側 predict.pyでウェイトの再ロード
  }
}





で、問題は。
  「どうやって A/Bを見分ける?」
ですが。

Aの一例 、Bの一例: 


これはニューラルネットワークの
  画像の分類問題 (Imageを入力に受け取って、テキストラベルを返す)
に相当し。

NNの適用分野として
最もポピュラーな題材の一つです。
いわゆる「画像検索」。


探せばいくらでも.pyコードは出てくるので。

ニューラルネットワークの練習問題として、
ぜひ自分で環境を構築してください。

NNの組み方は勉強しておいて
絶対に損はないです。



そして肝心の
ニューラルネットワークネットワーク設計:


#説明のための擬似コード
class Network(nn.Module):
  def __init__(self,train_option,classes):
    ~
    print(self);

#-------------------------
Network(
(relu): ReLU(inplace=True)
(pool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(sequential): Sequential(
(0): Conv2d(3, 32, kernel_size=(3, 3), stride=(1, 1))
(1): ReLU(inplace=True)
(2): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1))
(3): ReLU(inplace=True)
(4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(5): Flatten(start_dim=1, end_dim=-1)
(6): Dropout2d(p=0.1, inplace=False)
(7): Linear(in_features=28800, out_features=2, bias=True)
)
)


  (Conv2d → ReLU → MaxPool2d) x N
を繰り返して特徴を抽出し、
最後に(フラット化 → リニア → A/B)で二値に収束させる。

「画像の分類問題」としては
これまた非常にスタンダードな手法です。



Conv2dの段数は2段としました。
NNとしては非常に浅いです。

浅くした理由としては:

  1. 毎秒キャプチャー、毎秒A/B判定してもらうので
   とにかくスピード重視。NNは軽いほどよい。

  2. Bは毎回同じ画像が出てくる。
  
    段数を深くしてのディープな因子解析や、
    凝ったA/B予測はせずとも。
    
    単純に「入力画像は、Bの中にあるか?
    
    それだけを調べてくれれば良いので
    浅いネットワーク設計でも十分動く。
    
    
  3. 新しいBが出てきた時や、
    もしくはA/Bの判定を間違ったら、
    データセットに画像を追加してトレーニングを開始します。
    
    その時、NNが浅ければ計算コストが安い。
    トレーニング→ウェイト更新 までの時間が短くなる。
    
    
そういう事を色々と。
実践的に試行錯誤して。
このNN設計にたどり着きました。



さて。このNNで
A 100,000枚

B 5,000枚

に対してトレーニングさせると
ほぼ100%の確率でA/Bを見分けてくれるようになります。

Bはいつも決まった画像が出てくる。
全部登録して丸暗記させれば十分判定可能だからです。



最後に、
  1. メゾピアノ.exe     画面をキャプチャー。image.pngに書き出し。
  2. predict.py       image.pngを判定。結果をresult.txtに書き出す。
  3. メゾピアノ.exe     result.txtを読み出す。
  
ファイル越しにデータを受け渡しすることで
キャプチャー画面の
A/B判定を実現しています。




次回。軽量化・高速化の手法を色々。