「PCソフト『メゾピアノ』開発 1 (2024/05/29)」
最近「メゾピアノ」と言うPC用ソフトを作ってます。
原理は非常にシンプル。
//説明の為の疑似コード
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でウェイトの再ロード
}
}
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に分類するか。
それはユーザーが決める事なので
何でもいいのですが。
まあ、一例を挙げれば
私がAにカテゴライズした画像
(約100,000枚)
Bにカテゴライズした画像
(約5,000枚)
この方式のメリットは、
・TV型のB(Aの合間にBが流れる)
・ストリーム型のB(Bを見終わるまでAが流れてこない)
・動画埋め込み型のB (通常のA動画の中に、宣伝用のBパートが埋め込まれてる)
等...。
シンプルに「画面に写っている画像で判定」
しているだけなので、
あらゆるソースで通用する。
またこのソフトは:
ユーザー側では「B」はきちんと受け取ってるし、
ブラウザも「B」を表示している。
データのブロック行為は一切行っていません。
非常にクリーンな技術です。
これはただ単に:
「Bを見たらミュート。Aを見たらミュート解除」
人間が手作業でやっていた作業を、
学習型ニューラルネットワークで
自動運転化しただけ。
とは言え、
「原理的にはシンプル」
と言うだけで。
そのままじゃ実用できないのがソフト開発。
具体的に発生する問題点としては:
・数秒おきにキャプチャー& predict.pyを実行するのでCPUに負荷がかかる
・真実Aなのに判定B、真実Bなのに判定Aとされる
誤判定が常に付きまとう。
そのためにはA/Bを分類するのに十分な情報量。
数万枚~のA/B画像を集める必要がある。
・誤判定を修正する為に、ユーザーがA/B画像を1枚データセットに追加する度に
トレーニングが発生。
データセット全体で再学習させる必要がある。
そしてニューラルネットワークの学習コストは・・・かなり高い。
・予測側 predict.pyにもリアルタイムの応答が必要。
とにかく、可能な限り低い計算コストで。
A/Bを分類するためにニューラルネットワークの設計を
最適化する必要がある。
・Bを見たら画面を隠すのに、じゃあどうやってAが来たってわかるの?
→ 1ドットの覗き穴をあちこちに開けて、そこから覗き見る
・「train/A、train/Bに分類・・・?
test/A,test/B も使わないとイカンでしょ。」
→ 私自身で色々実験した結果:
Bには強い再現性。全く画像が繰り返される法則があります。
trainで学習した時に見たBが、
本番でもそのまま出てくる。
トレーニングと本番が同じだから、
test/による 模擬前をいれる必要性がないんですね。
だから、データは全てtrain/に放り込んで
Bの全データを丸暗記させる事にしました。
だからtest/システムは使ってません。
・でもtestを使わないと過学習が・・・えーんか?
→問題なし。
過学習とはそもそも、
練習問題(train)を一生懸命勉強してたし、100点も出したのに。
本番問題(test)が全然違っていて、ひどい点数になった!
このtrain内容とtest内容のギャップが
過学習を発生させるわけですが・・・・
だが「メゾピアノ」のトレーニング風景は
そもそもtest/を持たない。
train /のみでやっています。
(理由は先述)
だから、 過学習の問題は成立しません。
・あと例えば、黒一色や白一色など。
原理的にA/Bの判定がつかない画像はどうするの?
→ 前回の判定結果を使う
・同じ画像(そっくりな画像)をA/Bの両方に入れたら判定はどうなるの?
→ A80%、B20%のようにデータセット内の枚数で
確率的に出てきます。
(dropoutと言う、あえてランダムノイズを加える事で
ウェイトを鍛えるノードがあるので。
全く同じ画像を与えてもノイズが加わっていつも変化してる)
・真実Aなのに判定B、真実Bなのに判定Aとされる
誤判定が常に付きまとう。
そのためにはA/Bを分類するのに十分な情報量。
数万枚~のA/B画像を集める必要がある。
・誤判定を修正する為に、ユーザーがA/B画像を1枚データセットに追加する度に
トレーニングが発生。
データセット全体で再学習させる必要がある。
そしてニューラルネットワークの学習コストは・・・かなり高い。
・予測側 predict.pyにもリアルタイムの応答が必要。
とにかく、可能な限り低い計算コストで。
A/Bを分類するためにニューラルネットワークの設計を
最適化する必要がある。
・Bを見たら画面を隠すのに、じゃあどうやってAが来たってわかるの?
→ 1ドットの覗き穴をあちこちに開けて、そこから覗き見る
・「train/A、train/Bに分類・・・?
test/A,test/B も使わないとイカンでしょ。」
→ 私自身で色々実験した結果:
Bには強い再現性。全く画像が繰り返される法則があります。
trainで学習した時に見たBが、
本番でもそのまま出てくる。
トレーニングと本番が同じだから、
test/による 模擬前をいれる必要性がないんですね。
だから、データは全てtrain/に放り込んで
Bの全データを丸暗記させる事にしました。
だからtest/システムは使ってません。
・でもtestを使わないと過学習が・・・えーんか?
→問題なし。
過学習とはそもそも、
練習問題(train)を一生懸命勉強してたし、100点も出したのに。
本番問題(test)が全然違っていて、ひどい点数になった!
このtrain内容とtest内容のギャップが
過学習を発生させるわけですが・・・・
だが「メゾピアノ」のトレーニング風景は
そもそもtest/を持たない。
train /のみでやっています。
(理由は先述)
だから、 過学習の問題は成立しません。
・あと例えば、黒一色や白一色など。
原理的にA/Bの判定がつかない画像はどうするの?
→ 前回の判定結果を使う
・同じ画像(そっくりな画像)をA/Bの両方に入れたら判定はどうなるの?
→ A80%、B20%のようにデータセット内の枚数で
確率的に出てきます。
(dropoutと言う、あえてランダムノイズを加える事で
ウェイトを鍛えるノードがあるので。
全く同じ画像を与えてもノイズが加わっていつも変化してる)
次回はそこら辺の改善策や
疑問点を解説してゆきます。