我在尝试使用DeepLearning4J 0.7训练一个受限玻尔兹曼机(RBM),但没有成功。我找到的所有示例要么没有实际用途,要么在DeepLearning4J 0.7中已经不再适用。
我需要使用对比散度(Contrastive Divergence)训练一个单一的RBM,然后计算重建误差。
这是我目前的代码:
import org.nd4j.linalg.factory.Nd4j;import org.deeplearning4j.datasets.fetchers.MnistDataFetcher;import org.deeplearning4j.nn.conf.layers.RBM;import org.deeplearning4j.nn.api.Layer;import static org.deeplearning4j.nn.conf.layers.RBM.VisibleUnit;import static org.deeplearning4j.nn.conf.layers.RBM.HiddenUnit;import org.deeplearning4j.optimize.api.IterationListener;import org.deeplearning4j.datasets.iterator.impl.MnistDataSetIterator;import org.deeplearning4j.eval.Evaluation;import org.deeplearning4j.nn.api.OptimizationAlgorithm;import org.deeplearning4j.nn.conf.MultiLayerConfiguration;import org.deeplearning4j.nn.conf.NeuralNetConfiguration;import org.deeplearning4j.nn.conf.Updater;import org.deeplearning4j.nn.multilayer.MultiLayerNetwork;import org.deeplearning4j.nn.weights.WeightInit;import org.deeplearning4j.optimize.listeners.ScoreIterationListener;import org.nd4j.linalg.dataset.DataSet;import org.nd4j.linalg.dataset.api.iterator.DataSetIterator;import org.nd4j.linalg.lossfunctions.LossFunctions;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.nd4j.linalg.api.ndarray.INDArray;public class experiment3 { private static final Logger log = LoggerFactory.getLogger(experiment3.class); public static void main(String[] args) throws Exception { DataSetIterator mnistTrain = new MnistDataSetIterator(100, 60000, true); MultiLayerConfiguration conf = new NeuralNetConfiguration.Builder() .regularization(false) .iterations(1) .optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT) .list() .layer(0, new RBM.Builder() .nIn(784).nOut(500) .weightInit(WeightInit.XAVIER) .lossFunction(LossFunctions.LossFunction.RECONSTRUCTION_CROSSENTROPY) .updater(Updater.NESTEROVS) .learningRate(0.1) .momentum(0.9) .k(1) .build()) .pretrain(true).backprop(false) .build(); MultiLayerNetwork model = new MultiLayerNetwork(conf); model.init(); model.setListeners(new ScoreIterationListener(600)); for(int i = 0; i < 50; i++) { model.fit(mnistTrain); } }}
代码可以编译并在每个epoch打印一些分数,但分数在应该减少时反而增加了,而且我没有找到任何重建的方法。
我尝试使用reconstruct函数并计算距离:
while(mnistTrain.hasNext()){ DataSet next = mnistTrain.next(); INDArray in = next.getFeatureMatrix(); INDArray out = model.reconstruct(in, 1); // 尝试过0但会出现数组索引越界 log.info("distance(1):" + in.distance1(out)); }
但即使模型没有经过一个epoch的训练,每个元素的距离总是0.0,这是不可能的。
这是训练RBM的正确方法吗?如何使用单个RBM重建输入?
回答:
我意识到这个问题已经有些旧了,但最近的活动让我重新注意到了它。我只想说我最近在DL4j中使用了RBM,包括单层和多层。虽然它们可能没有得到官方支持,但它们确实有效。我也遇到了reconstruct
。要测试模型,你应该使用output
,就像在前馈网络中一样。在你的情况下,我认为应该是这样的:
INDArray in = next.getFeatureMatrix();INDArray out = model.output(in);
补充几点:
我使用的是0.9.1版本