我有一堆传感器,我真的只想重建输入。
我想要的是:
- 在我训练了我的模型之后,我将传入我的特征矩阵
- 得到重构后的特征矩阵
- 我想研究哪些传感器值与重建值完全不同
因此,我认为RBM将是正确的选择,因为我习惯了Java,我已经尝试使用deeplearning4j。但我很早就被困住了。如果你运行下面的代码,我将面临两个问题。
-
结果与正确的预测相差甚远,多数为简单的[1.00,1.00,1.00].
-
我希望得到4个值(这是预期要重建的输入的数量)
那么我需要调整什么来得到a)一个更好的结果和b)得到重建的输入?
public static void main(String[] args) {
// Customizing params
Nd4j.MAX_SLICES_TO_PRINT = -1;
Nd4j.MAX_ELEMENTS_PER_SLICE = -1;
Nd4j.ENFORCE_NUMERICAL_STABILITY = true;
final int numRows = 4;
final int numColumns = 1;
int outputNum = 3;
int numSamples = 150;
int batchSize = 150;
int iterations = 100;
int seed = 123;
int listenerFreq = iterations/5;
DataSetIterator iter = new IrisDataSetIterator(batchSize, numSamples);
// Loads data into generator and format consumable for NN
DataSet iris = iter.next();
iris.normalize();
//iris.scale();
System.out.println(iris.getFeatureMatrix());
NeuralNetConfiguration conf = new NeuralNetConfiguration.Builder()
// Gaussian for visible; Rectified for hidden
// Set contrastive divergence to 1
.layer(new RBM.Builder()
.nIn(numRows * numColumns) // Input nodes
.nOut(outputNum) // Output nodes
.activation("tanh") // Activation function type
.weightInit(WeightInit.XAVIER) // Weight initialization
.lossFunction(LossFunctions.LossFunction.XENT)
.updater(Updater.NESTEROVS)
.build())
.seed(seed) // Locks in weight initialization for tuning
.iterations(iterations)
.learningRate(1e-1f) // Backprop step size
.momentum(0.5) // Speed of modifying learning rate
.optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT) // ^^ Calculates gradients
.build();
Layer model = LayerFactories.getFactory(conf.getLayer()).create(conf);
model.setListeners(Arrays.asList((IterationListener) new ScoreIterationListener(listenerFreq)));
model.fit(iris.getFeatureMatrix());
System.out.println(model.activate(iris.getFeatureMatrix(), false));
}
对于b),当您调用activate()时,您将获得一个"nlayers"数组列表。列表中的每个数组都是一个层的激活。数组本身由行组成:每个输入向量1行;每一列都包含了这一层中每个神经元的激活和这个观察(输入)。使用一些输入激活所有层之后,您可以使用RBM.propDown()方法获得重建。
对于a),我担心正确训练RBM是非常棘手的。所以你真的想使用每一个参数,更重要的是,在训练过程中监测各种指标,这些指标会给你一些提示,告诉你训练是否正确。就我个人而言,我喜欢:
- 训练语料库上的分数(),表示每次梯度更新后的重构误差;
- 在另一个开发语料库上的score():在发生过拟合时警告有用;
- 参数向量的范数:对得分影响较大
- 初始化后和N步后的两个激活图(一层激活神经元在语料库上的XY矩形图):这有助于检测不可靠的训练(例如:当所有神经元都是黑/白时,当大部分神经元从未被激活时,等等)