C#でDeep Learning(Accord.NETによる方法)
流行りのDeep LearningをC#で試してみる.機械学習やコンピュータビジョン,信号処理等の.NET向けのオープンソースのライブラリであるAccord.NET FrameworkにDeep Learningが実装されているのでそれを使う.
Deep Belief Networks(DBN), Deep Neural Networks(DNNs)とおまけにRestricted Boltzmann Machine(RBM)を単体で動かしてみる.
Deep Learning自体については以下のページ等を参考に.
MIRU2014 tutorial deeplearning
Deep Learning技術の今
ディープラーニング チュートリアル(もしくは研究動向報告)
Accord.NETのインストール
NuGet経由でインストール可能.プロジェクトを右クリックして「NuGetパッケージの管理」を選択する.オンラインから「Accord.Neuro」を検索・インストール.
ソースコード
- Deep Belief Networks(DBN) - 教師あり学習(Back propagation)
- Deep Belief Networks(DBN) - 教師なし学習(Contrastive Divergence)
- Deep Neural Networks(DNNs)
- Restricted Boltzmann Machine(RBM)
を動かすサンプルコードを載せていくが,いずれのサンプルでも以下のusingを書いておくこと.
using Accord.Neuro; using Accord.Neuro.Networks; using Accord.Neuro.Learning; using AForge.Neuro.Learning; using Accord.Neuro.ActivationFunctions; using Accord.Math;
Deep Belief Networks(DBN) - 教師あり学習(Back propagation)
// トレーニングデータ double[][] inputs = { new double[] { 1, 1, 1, 0, 0, 0 }, new double[] { 1, 0, 1, 0, 0, 0 }, new double[] { 1, 1, 1, 0, 0, 0 }, new double[] { 0, 0, 1, 1, 1, 0 }, new double[] { 0, 0, 1, 1, 0, 0 }, new double[] { 0, 0, 1, 1, 1, 0 }, }; double[][] outputs = { new double[] { 1, 0 }, new double[] { 1, 0 }, new double[] { 1, 0 }, new double[] { 0, 1 }, new double[] { 0, 1 }, new double[] { 0, 1 }, }; // DBNの生成 var network = new DeepBeliefNetwork( inputsCount: inputs.Length, // 入力層の次元 hiddenNeurons: new int[] { 4, 2 }); // 隠れ層と出力層の次元 // ネットワークの重みをガウス分布で初期化する new GaussianWeights(network).Randomize(); network.UpdateVisibleWeights(); // DBNの学習アルゴリズムの生成 5000回繰り返し入力 var teacher = new BackPropagationLearning(network); for (int i = 0; i < 5000; i++) teacher.RunEpoch(inputs, outputs); // 重みの更新 network.UpdateVisibleWeights(); // 学習されたネットワークでテストデータが各クラスに属する確率を計算 double[] input = { 1, 1, 1, 1, 0, 0 }; var output = network.Compute(input); // 一番確率の高いクラスのインデックスを得る int imax; output.Max(out imax); // 結果出力 Console.WriteLine("class : {0}", imax); foreach (var o in output) { Console.Write("{0} ", o); }
実行結果
class : 0 0.883118949465337 0.115560850111682
Deep Belief Networks(DBN) - 教師なし学習(Contrastive Divergence)
// トレーニングデータ double[][] inputs = { new double[] { 1, 1, 1, 0, 0, 0 }, new double[] { 1, 0, 1, 0, 0, 0 }, new double[] { 1, 1, 1, 0, 0, 0 }, new double[] { 0, 0, 1, 1, 1, 0 }, new double[] { 0, 0, 1, 1, 0, 0 }, new double[] { 0, 0, 1, 1, 1, 0 }, }; // DBNの生成 var network = new DeepBeliefNetwork( inputsCount: 6, hiddenNeurons: new int[] { 4, 2 }); // ネットワークの重みをガウス分布で初期化する new GaussianWeights(network).Randomize(); network.UpdateVisibleWeights(); // DBNの学習アルゴリズムの生成 5000回繰り返し入力 var teacher = new DeepBeliefNetworkLearning(network) { Algorithm = (h, v, i) => new ContrastiveDivergenceLearning(h, v) }; var layerData = teacher.GetLayerInput(inputs); for (int i = 0; i < 5000; i++) teacher.RunEpoch(layerData); // 重みの更新 network.UpdateVisibleWeights(); // 学習されたネットワークでテストデータが各クラスに属する確率を計算 double[] input = { 1, 1, 1, 1, 0, 0 }; var output = network.Compute(input); // 一番確率の高いクラスのインデックスを得る int imax; output.Max(out imax); // 結果出力 Console.WriteLine("class : {0}", imax); foreach (var o in output) { Console.Write("{0} ", o); }
実行結果
class : 1 0.529437183967883 0.554114047128916
Deep Neural Networks(DNNs)
// トレーニングデータ double[][] inputs = { new double[] { 1, 1, 1, 0, 0, 0 }, new double[] { 1, 0, 1, 0, 0, 0 }, new double[] { 1, 1, 1, 0, 0, 0 }, new double[] { 0, 0, 1, 1, 1, 0 }, new double[] { 0, 0, 1, 1, 0, 0 }, new double[] { 0, 0, 1, 1, 1, 0 }, }; double[][] outputs = { new double[] { 1, 0 }, new double[] { 1, 0 }, new double[] { 1, 0 }, new double[] { 0, 1 }, new double[] { 0, 1 }, new double[] { 0, 1 }, }; // ネットワークの生成 var network = new DeepBeliefNetwork( inputsCount: inputs.Length, // 入力層の次元 hiddenNeurons: new int[] { 4, 2 }); // 隠れ層と出力層の次元 // DNNの学習アルゴリズムの生成 var teacher = new DeepNeuralNetworkLearning(network) { Algorithm = (ann, i) => new ParallelResilientBackpropagationLearning(ann), LayerIndex = network.Machines.Count - 1, }; // 5000回繰り返し学習 var layerData = teacher.GetLayerInput(inputs); for (int i = 0; i < 5000; i++) teacher.RunEpoch(layerData, outputs); // 重みの更新 network.UpdateVisibleWeights(); // 学習されたネットワークでテストデータが各クラスに属する確率を計算 double[] input = { 1, 1, 1, 1, 0, 0 }; var output = network.Compute(input); // 一番確率の高いクラスのインデックスを得る int imax; output.Max(out imax); // 結果出力 Console.WriteLine("class : {0}", imax); foreach (var o in output) { Console.Write("{0} ", o); }
実行結果
class : 0 0.999680477117216 0.00120961077917418
Restricted Boltzmann Machine(RBM)
// トレーニングデータ double[][] inputs = { new double[] { 1, 1, 1, 0, 0, 0 }, new double[] { 1, 0, 1, 0, 0, 0 }, new double[] { 1, 1, 1, 0, 0, 0 }, new double[] { 0, 0, 1, 1, 1, 0 }, new double[] { 0, 0, 1, 1, 0, 0 }, new double[] { 0, 0, 1, 1, 1, 0 }, }; double[][] outputs = { new double[] { 1, 0 }, new double[] { 1, 0 }, new double[] { 1, 0 }, new double[] { 0, 1 }, new double[] { 0, 1 }, new double[] { 0, 1 }, }; // RBMの生成 var rbm = new RestrictedBoltzmannMachine( inputsCount: 6, hiddenNeurons: 2); // トレーニングデータで学習 var teacher = new ContrastiveDivergenceLearning(rbm); for (int i = 0; i < 5000; i++) teacher.RunEpoch(inputs); // テストデータ double[] input = { 1, 1, 1, 1, 0, 0 }; // 学習されたネットワークで各クラスに属する確率を計算 var output = rbm.Compute(input); // 一番確率の高いクラスのインデックスを得る int imax; output.Max(out imax); // 結果出力 Console.WriteLine("class : {0}", imax); foreach (var o in output) { Console.Write("{0} ", o); }
実行結果
class : 1 0.133832413712274 0.906343089146992