我在Encog中创建并学习了自动编码器,我尝试将其分成几部分:编码器和解码器部分。不幸的是我无法得到它并且我一直得到奇怪的不正确的数据(比较从一次网络应用到数据和两次数据的结果 - > enc - > dec)。
我试图用简单的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;
}
AutoEncoder的完全旧的(设置/获取权重)代码:
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;
}
}
}
如何才能正确地从编码器的自动编码器中剥离两个第一层,从一个解码器中另外两个最后一层?
答案 0 :(得分: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));