如何解决用于预测函数的 DeepLearning4j NN 不收敛
我正在尝试在 DL4j 中做一个简单的预测(稍后将它用于具有 n 个特征的大型数据集),但无论我做什么,我的网络都不想学习并且表现得很奇怪。当然,我研究了所有教程并执行了 dl4j 存储库中显示的相同步骤,但不知何故对我不起作用。
对于我使用的虚拟特征数据:
*double[val][x] 特征;其中 val = linspace(-10,10)...;并且 x= Math.sqrt(Math.abs(val)) * val;
我的y 是:double[y] 标签;其中 y = Math.sin(val) / val
DataSetIterator dataset_train_iter = getTrainingData(x_features,y_outputs_train,batchSize,rnd);
DataSetIterator dataset_test_iter = getTrainingData(x_features_test,y_outputs_test,rnd);
// normalize data,including labels (fitLabel=true)
normalizerMinMaxScaler normalizer = new normalizerMinMaxScaler(0,1);
normalizer.fitLabel(false);
normalizer.fit(dataset_train_iter);
normalizer.fit(dataset_test_iter);
// Use the .transform function only if you are working with a small dataset and no iterator
normalizer.transform(dataset_train_iter.next());
normalizer.transform(dataset_test_iter.next());
dataset_train_iter.setPreProcessor(normalizer);
dataset_test_iter.setPreProcessor(normalizer);
//DataSet setnormal = dataset.next();
//创建网络
MultiLayerConfiguration conf = new NeuralNetConfiguration.Builder()
.seed(seed)
.optimizationAlgo(OptimizationAlgorithm.stochastic_GRADIENT_DESCENT)
.weightinit(Weightinit.XAVIER)
//.miniBatch(true)
//.l2(1e-4)
//.activation(Activation.TANH)
.updater(new nesterovs(0.1,0.3))
.list()
.layer(new DenseLayer.Builder().nIn(numInputs).nOut(20).activation(Activation.TANH)
.build())
.layer(new DenseLayer.Builder().nIn(20).nOut(10).activation(Activation.TANH)
.build())
.layer( new DenseLayer.Builder().nIn(10).nOut(6).activation(Activation.TANH)
.build())
.layer(new OutputLayer.Builder(LossFunctions.LossFunction.MSE)
.activation(Activation.IDENTITY)
.nIn(6).nOut(1).build())
.build();
//训练和拟合网络
final MultiLayerNetwork net = new MultiLayerNetwork(conf);
net.init();
net.setListeners(new scoreIterationListener(100));
//Train the network on the full data set,and evaluate in periodically
final Indarray[] networkPredictions = new Indarray[nEpochs / plotFrequency];
for (int i = 0; i < nEpochs; i++) {
//in fit we have already Backpropagation. See Release deeplearning
// https://deeplearning4j.konduit.ai/release-notes/1.0.0-beta3
net.fit(dataset_train_iter);
dataset_train_iter.reset();
if((i+1) % plotFrequency == 0) networkPredictions[i/ plotFrequency] = net.output(x_features,false);
}
// 评估和绘图
dataset_test_iter.reset();
dataset_train_iter.reset();
Indarray predicted = net.output(dataset_test_iter,false);
System.out.println("PREDICTED ARRAY " + predicted);
Indarray output_train = net.output(dataset_train_iter,false);
//Revert data back to original values for plotting
// normalizer.revertLabels(predicted);
normalizer.revertLabels(output_train);
normalizer.revertLabels(predicted);
PlotUtil.plot(om,networkPredictions);
我的输出看起来很奇怪(见下图),即使我使用 miniBatch(1,20,100 个样本/批次)更改时期数或添加隐藏节点和隐藏层(尝试添加 1000 个节点和 5 层)。网络要么输出非常随机的值,要么输出一个常数 y。我只是无法识别,这里出了什么问题。为什么网络甚至不接近火车功能。
另一个问题:iter.reset() 到底做了什么。迭代器是否将指针返回到 DataSetIterator 中的 0-Batch?
解决方法
一个很常见的问题是人们做这样的玩具问题是 dl4j 对小批量的假设(99% 的问题都是这样)。您实际上并没有在进行小批量学习(这实际上违背了实际使用迭代器的意义,迭代器旨在遍历数据集的切片,而不是内存中的小数据集) - 一个小的建议是只使用普通的数据集 api (这是从 dataset.next() 返回的内容)
确保关闭 dl4j 分配给所有损失的小批量惩罚: .minibatch(false) - 您可以在此处看到该配置: https://github.com/eclipse/deeplearning4j/blob/master/deeplearning4j/deeplearning4j-nn/src/main/java/org/deeplearning4j/nn/conf/NeuralNetConfiguration.java#L434
为了后代,这里是相关的配置:
MultiLayerConfiguration conf = new NeuralNetConfiguration.Builder().miniBatch(false)
.dataType(DataType.DOUBLE)
.optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT).updater(new NoOp())
.list()
.layer(0,new DenseLayer.Builder().nIn(4).nOut(3)
.dist(new NormalDistribution(0,1))
.activation(Activation.TANH)
.build())
.layer(1,new OutputLayer.Builder(LossFunction.MCXENT)
.activation(Activation.SOFTMAX).nIn(3).nOut(3).build())
.build();
您会注意到两件事:1 是 minibatch 是假的,2 是数据类型 double 的配置。也欢迎您尝试解决您的问题。 为了节省内存,Dl4j 也倾向于假定默认数据类型为 float。
当处理更大的问题时,这是一个合理的假设,但可能不适用于玩具问题。
作为参考,您可以在此处找到 minibatch 数学的应用: https://github.com/eclipse/deeplearning4j/blob/fc735d30023981ebbb0fafa55ea9520ec44292e0/deeplearning4j/deeplearning4j-nn/src/main/java/org/deeplearning4j/nn/updater/BaseMultiLayerUpdater.java#L332
这会影响梯度更新。
本质上,这两者都会自动惩罚反映在损失和梯度更新中的数据集的损失更新。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。