2014-12-05 5 views
1

Encog에서 자동 인코딩을 생성하고 학습했으며 필자는이를 인코더 및 디코더 부분으로 추출하려고합니다. 불행히도 나는 그것을 얻을 수 없으며 나는 부적절한 부적절한 데이터를 얻는다. (한 번 그물을 데이터에 적용한 결과와 두 번 데이터 -> enc -> dec을 비교 한 결과)encog에서 autoencoder에서 인코더/디코더 리핑

간단히 GetWeight 및 SetWeight로 만들려고했지만 잘못된 결과가 있습니다. encog 문서 - 초기화 플랫 네트워크에서 발견 된 해결책은 분명하지 않습니다 (제대로 작동하지 않습니다). AutoEncoder의

 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; 
     } 
    } 
} 

가 어떻게 제대로 인코더 autoencoder에서 두 첫번째 층 및 디코더에 대한 하나의 마지막 두 층을 추출 할 수 있습니까?

답변

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));