ニューラルネットワークのデータ圧縮

画像 この記事では、ニューラルネットワークによって解決される別のクラスの問題、つまりデータ圧縮について説明します。 この記事で説明されているアルゴリズムは、より効率的なアルゴリズムが存在するため、実際の戦闘条件で使用されることを主張していません。 直ちに、 ロスレス圧縮のみに焦点を当てることを予約します。

ほとんどのインターネットソースは、データ圧縮を解決する3つの主要なニューラルネットワークアーキテクチャがあると主張しています。



1. Kohonenネットワークとそのバリエーション。 多くの場合、品質の低下を伴う画像の圧縮に使用されますが、可逆圧縮アルゴリズムではありません。



2. 連想メモリ (ホップフィールドネットワーク、双方向連想メモリなど)。 このクラスのネットワークの「データ圧縮」は、「機能」であり、副作用です。主な目的は、ノイズの多い/破損した入力データから元の信号/画像を復元するためです。 ほとんどの場合、同じ次元のノイズの多い画像がこれらのネットワークの入力に到着するため、データ圧縮については話していません。



3. 「ボトルネック」メソッド。



最後の方法については、記事で説明します。



メソッドの本質



画像 ネットワークアーキテクチャと学習アルゴリズムは、比較的小さなチャネルを介して、ニューラルネットワークの入力からその出力に大きな次元のベクトルを送信する必要があるようなものです。 類推として-砂時計、水まき缶、ボトルネック、誰にでも近いです。 この種の圧縮を実装するには、次のアーキテクチャの多層パーセプトロンを使用できます。入力層と出力層のニューロンの数は同じで、サイズの小さいいくつかの隠れ層がそれらの間に配置されます。

学習には、逆伝播アルゴリズムが使用され、シグモイド(シグモイド関数、双極シグモイド関数)が活性化関数として使用されます。

ネットワークは2つの部分で構成されます-1つはデータ圧縮に、もう1つはリカバリに機能します。 両方の手順に費やされる時間はほぼ同じです。 実際の使用では、結果のネットワークは2つに分割されます。 最初のネットワークの出力は、通信チャネルを介して送信され、解凍を実行する2番目のネットワークの入力に送られます。



学習には何が影響しますか?



ネットワーク学習率に影響を与える重要なレバーは、学習率係数の巧みな調整です。 最も単純なオプション-前の時代のネットワークエラーと比較して、ネットワークエラーが比較的小さい値(たとえば、0.0000001未満)に変化した場合、係数を小さくする必要があります。 学習速度を変更するためのよりインテリジェントなアルゴリズムがあります。

そして、トレーニングにおけるもう1つの非常に重要な要素は、全能ランダム性です。 重み係数を使用してニューロンを作成するときは、小さなランダム値を設定するのが一般的です。 ネットワークが訓練されていないか、エラーの収束が非常に小さくなるように、値がランダムに設定される場合があります。



実装



実装ではAForge.NETライブラリを使用しました 。 長さ10のベクトル、次に長さ20のベクトルで主な実験を行いましたが、本質は変わりませんでした。したがって、次元を増やすことはしませんでしたが、もう1つの理由があります。 なぜもっと長いベクターで実験していないのですか? 長いベクトルで大きなトレーニングセットを生成してみませんか? これは、いくつかの問題と不便を引き起こすため、 怠inessが原因です。 そのようなサンプルには矛盾があるかもしれません。 たとえば、ベクトルの入力セットには、2つ以上の同一または類似のベクトルが存在する場合があり、その望ましい出力は完全に異なります。 その場合、そのようなトレーニングサンプルのネットワークはトレーニングされず、「競合する」ベクトルを見つけるのはかなり困難です。



結果と結論



私にとって最も興味深い質問は、このネットワークをどのように効果的に構築できるのかということでした。 彼女はいくつの隠れ層を持つべきですか? トレーニングはどれくらいの速さですか? 圧縮と復元の速度はどれくらいですか?

このネットワークを構築するための2つの主な可能なオプションで実験が行われました。



「クイック圧縮」


「高速圧縮」を使用したネットワークは、隠れ層のニューロンの数が入力/出力層よりもはるかに少ない(3、5など)ネットワークであり、ネットワークは入力、出力、2つの4つの層で構成されます。非表示(例:10-3-3-10)。 同様のネットワークトポロジは、場合によっては非常に効果的であることが証明されています。 まず、このようなネットワークは非常に迅速に学習します。 これは、トレーニングアルゴリズムが、隣接するレイヤー間の比較的少数の結合の重み係数を調整する必要があるという事実によるものです。 第二に、ネットワークの機能中の結果の出力速度も非常に高速です(同じ理由で)。 裏側-ネットワークは、入力(およびそれに応じて出力)層のニューロンの数に対して小さなサンプルでのみトレーニングされます(許容されるベクトルの数は、ネットワークの最初/最後の層のニューロンの半分にほぼ等しくなります)。 また、スティックを曲げてレイヤー間で差をつけすぎないでください。最良のオプションは、非表示レイヤーのニューロンの数が入力/出力レイヤーよりも約3倍少なくなることです。



「順次圧縮」


「シーケンシャル」または「余暇」圧縮のネットワークとは、隣接する層のニューロンの数がそれほど変わらない(最大25%)ネットワークで、4つ以上の隠れ層(10-8-5-3-3-など)が含まれるネットワークです。 5-8-10)。 そのようなネットワークは私の期待に応えられませんでした。 小さなトレーニングサンプルとベクトルの長さでさえ、学習に非常に長い時間がかかります。 まあ、もちろん、それらは遅くなります。 彼らは実際の戦闘条件ではより安定していると言いますが。 しかし、トレーニング時間が非常に長いため、これを検証できませんでした。



効率と稼働時間について


実用的な観点から、2つの事実が興味深いです-圧縮率と圧縮/回復時間。 ネットワークはほぼ100%トレーニングされ、完全に機能し、データを3回圧縮します。 作業のスピードも楽しいです。 アーキテクチャ(10-3-3-10)の場合、フルサイクル実行時間(圧縮と回復)は00:00:00.0000050です。 (20-6-6-20)-00:00:00.000006565の場合 1つのベクトルの圧縮または復元のために、2で安全に分割し、00:00:00.000002525および00:00:00.0000033を取得できます。

テストは、AMD Athlon II x240 2.80 Ghzプロセッサで実施されました。





例として、ネットワークの作成、トレーニング、および操作の基本的な例を説明する小さなコメント付きのコード(C#)。 ネットワークはベクトルを3回圧縮し、98%のケースで訓練されます。 機能させるには、AForge.NETライブラリを接続する必要があります。



using System;

using AForge.Neuro;

using AForge.Neuro.Learning;



namespace FANN

{

class Program

{

static void Main( string [] args)

{

// 4 ( 10,3,3,10 , )

ActivationNetwork net = new ActivationNetwork((IActivationFunction) new SigmoidFunction(), 10,3,3,10);

// -

BackPropagationLearning trainer = new BackPropagationLearning(net);



//

double [][] input = new double [][] {

new double []{1,1,1,1,1,1,1,1,1,1},

new double []{0,0,0,0,0,0,0,0,0,0},

new double []{1,1,1,1,1,0,0,0,0,0},

new double []{0,0,0,0,0,1,1,1,1,1},

};



//

double [][] output= new double [][] {

new double []{1,1,1,1,1,1,1,1,1,1},

new double []{0,0,0,0,0,0,0,0,0,0},

new double []{1,1,1,1,1,0,0,0,0,0},

new double []{0,0,0,0,0,1,1,1,1,1},

};



// ,

double prErr = 10000000;

//

double error = 100;

//

trainer.LearningRate = 1;

//

while (error > 0.001)

{

//

error = trainer.RunEpoch(input, output);

// ,

if ( Math .Abs(error - prErr) < 0.000000001)

{

// 2

trainer.LearningRate /= 2;

if (trainer.LearningRate < 0.001)

trainer.LearningRate = 0.001;

}



prErr = error;

}



//

double [] result;

result = net.Compute( new double [] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 });

result = net.Compute( new double [] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 });

result = net.Compute( new double [] { 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 });

result = net.Compute( new double [] { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1 });

}

}

}




* This source code was highlighted with Source Code Highlighter .








文献とメモ






All Articles