2014-12-05 108 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));