2014-12-05 88 views
1

我已經在Encog中創建並學習了autoencoder,並試圖將其解碼爲編碼器和解碼器部分。不幸的是,我無法得到它,我不斷收到奇怪的不正確的數據(比較一次淨數據和兩次數據 - > enc - > dec)的結果。編碼器/解碼器從encen中的自動編碼器抓取

我試圖用GetWeight和SetWeight來做,但結果不正確。在encog文檔中找到的解決方案 - 初始化扁平網絡對我來說不是很清楚(我無法得到它的工作)。

 public static BasicNetwork getEncoder(BasicNetwork net) 
     { 
      var enc = new BasicNetwork(); 
      enc.AddLayer(new BasicLayer(null, true, net.GetLayerNeuronCount(0))); 
      enc.AddLayer(new BasicLayer(new ActivationSigmoid(), true, net.GetLayerNeuronCount(1))); 
      enc.AddLayer(new BasicLayer(new ActivationSigmoid(), false, net.GetLayerNeuronCount(2))); 
      enc.Structure.FinalizeStructure(); 

      var weights1 = net.Structure.Flat.Weights; 
      var weights2 = enc.Structure.Flat.Weights; 
      var idx1 = net.Structure.Flat.WeightIndex; 
      var idx2 = enc.Structure.Flat.WeightIndex; 

      for(var i = 0; i < 1; i++) 
      { 
       int n = net.GetLayerNeuronCount(i); 
       int m = net.GetLayerNeuronCount(i + 1); 

       Console.WriteLine("Decoder: {0} - {1}", n, m); 

       for(var j = 0; j < n; j++) 
       { 
        for(var k = 0; k < m; k++) 
        { 
         weights1 [idx1[i] + j * m + k] = weights2 [idx2[i] + j * m * k]; 
        } 
       } 
      } 


      return enc; 
     } 

全部舊樣(設置/獲取重量)的自動編碼器的代碼:

using System; 
using Encog.Engine.Network.Activation; 
using Encog.ML.Data; 
using Encog.ML.Data.Basic; 
using Encog.ML.Train; 
using Encog.Neural.Networks; 
using Encog.Neural.Networks.Layers; 
using Encog.Neural.Networks.Training.Propagation.Resilient; 

namespace engine 
{ 
    public class AutoEncoder 
    { 
     private int k = 0; 
     public IMLDataSet trainingSet 
     { 
      get; 
      set; 
     } 

     public AutoEncoder(int k) 
     { 
      this.k = k; 
     } 

     public static BasicNetwork getDecoder(BasicNetwork net) 
     { 
      var dec = new BasicNetwork(); 
      dec.AddLayer(new BasicLayer(null, true, net.GetLayerNeuronCount(1))); 
      dec.AddLayer(new BasicLayer(new ActivationSigmoid(), true, net.GetLayerNeuronCount(2))); 

      dec.Structure.FinalizeStructure(); 

      for(var i = 1; i < 2; i++) 
      { 
       int n = net.GetLayerNeuronCount(i); 
       int m = net.GetLayerNeuronCount(i + 1); 

       Console.WriteLine("Decoder: {0} - {1}", n, m); 

       for(var j = 0; j < n; j++) 
       { 
        for(var k = 0; k < m; k++) 
        { 
         dec.SetWeight(i - 1, j, k, net.GetWeight(i, j, k)); 
        } 
       } 
      } 

      return dec; 
     } 

     public static BasicNetwork getEncoder(BasicNetwork net) 
     { 
      var enc = new BasicNetwork(); 
      enc.AddLayer(new BasicLayer(null, true, net.GetLayerNeuronCount(0))); 
      enc.AddLayer(new BasicLayer(new ActivationSigmoid(), true, net.GetLayerNeuronCount(1))); 

      enc.Structure.FinalizeStructure(); 

      for(var i = 0; i < 1; i++) 
      { 
       int n = net.GetLayerNeuronCount(i); 
       int m = net.GetLayerNeuronCount(i + 1); 

       Console.WriteLine("Encoder: {0} - {1}", n, m); 

       for(var j = 0; j < n; j++) 
       { 
        for(var k = 0; k < m; k++) 
        { 
         enc.SetWeight(i, j, k, net.GetWeight(i, j, k)); 
        } 
       } 
      } 

      return enc; 
     } 

     public BasicNetwork learn(double[][] data, 
      double eps = 1e-6, 
      long trainMaxIter = 10000) 
     { 
      int n = data.Length; 
      int m = data[0].Length; 
      double[][] output = new double[n][]; 
      for(var i = 0; i < n; i++) 
      { 
       output[i] = new double[m]; 
       data[i].CopyTo(output[i], 0); 
      } 

      var network = new BasicNetwork(); 
      network.AddLayer(new BasicLayer(null, true, m)); 
      network.AddLayer(new BasicLayer(new ActivationSigmoid(), true, k)); 
      network.AddLayer(new BasicLayer(new ActivationSigmoid(), true, m)); 
      network.Structure.FinalizeStructure(); 
      network.Reset(); 

      trainingSet = new BasicMLDataSet(data, output); 
      IMLTrain train = new ResilientPropagation(network, trainingSet); 

      int epoch = 1; 
      do 
      { 
       train.Iteration(); 
       Console.WriteLine(@"Epoch #" + epoch + @" Error:" + train.Error); 
       epoch++; 
      } while(train.Error > eps && epoch < trainMaxIter); 

      train.FinishTraining(); 

      return network; 
     } 
    } 
} 

我該如何正確撕裂只有兩個從自動編碼器的第一層用於編碼器和一個解碼器的最後兩個層?

回答

1

如果您需要直接訪問權重,最好的方法是使用BasicNetwork.GetWeight()。下面是一個示例,顯示如何使用GetWeight獲取神經網絡中的所有權重。通過單元測試,證明GetWeight確實能夠工作,它使用BasicNetwork.Compute計算一個簡單的神經網絡的輸出,也可以通過將加權輸入求和並應用TanH來手動計算。兩者都產生相同的輸出。

更多信息這裏也一樣,如果你要訪問的重量陣列直接:http://www.heatonresearch.com/wiki/Weight

 var network = new BasicNetwork(); 
     network.AddLayer(new BasicLayer(null, true, 2)); 
     network.AddLayer(new BasicLayer(new ActivationTANH(), true, 2)); 
     network.AddLayer(new BasicLayer(new ActivationTANH(), false, 1)); 
     network.Structure.FinalizeStructure(); 
     network.Reset(100); 

     BasicMLData input = new BasicMLData(2); 
     input[0] = 0.1; 
     input[1] = 0.2; 

     Console.WriteLine("Using network: " + network.Compute(input)); 

     // now manually 
     double sum1 = (input[0]*network.GetWeight(0, 0, 0)) 
         + (input[1]*network.GetWeight(0, 1, 0)) 
         + (1.0*network.GetWeight(0,2,0)); 

     double sum2 = (input[0]*network.GetWeight(0, 0, 1)) 
         + (input[1]*network.GetWeight(0, 1, 1)) 
         + (1.0*network.GetWeight(0,2,1)); 

     double hidden1 = Math.Tanh(sum1); 
     double hidden2 = Math.Tanh(sum2); 

     double sum3 = (hidden1 * network.GetWeight(1, 0, 0)) 
         + (hidden2 * network.GetWeight(1, 1, 0)) 
         + (1.0 * network.GetWeight(1, 2, 0)); 

     double output = Math.Tanh(sum3); 

     Console.WriteLine("Using manual: " + network.Compute(input));