DL4J输入尺寸错误:秩1向量无法匹配网络矩阵输入需求
问题原因分析
DeepLearning4J里的全连接层(DenseLayer)默认要求输入是秩2的矩阵,也就是形状为[批量大小, 特征数量]的张量——这是因为DL4J的设计天生面向批量数据处理,哪怕你只输入单个样本,也得把它包装成批量形式(批量大小设为1)。
你传入的是秩1的向量(形状[23]),完全不符合层的输入要求,所以才抛出了DL4JInvalidInputException这个异常。
两种解决方案
方案1:调用evaluate时手动转换输入维度
直接修改你的evaluate方法,把输入的秩1向量转成秩2的矩阵(批量大小为1),用INDArray的reshape方法就能实现:
public INDArray evaluate(INDArray vec){ // 将秩1向量转为[1, 23]的秩2矩阵 INDArray batchedInput = vec.reshape(1, this.inputSize); return this.network.output(batchedInput); }
或者用expandDims方法更直观:
INDArray batchedInput = vec.expandDims(0); // 在第0维添加一个维度,形状从[23]变为[1,23]
方案2:给网络加输入预处理器自动转换
在你的网络配置里,给第一个层添加ReshapePreProcessor,让它自动把秩1输入转换成秩2矩阵:
private MultiLayerConfiguration setConfig(){ return new NeuralNetConfiguration.Builder() .seed(12345) .weightInit(WeightInit.XAVIER) .updater(new AdaGrad(0.5)) .activation(Activation.RELU) .optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT) .l2(0.0001) .list() // 添加输入预处理器,自动将秩1输入转为[1, inputSize]的矩阵 .inputPreProcessor(0, new ReshapePreProcessor(1, this.inputSize)) .layer(0, new DenseLayer.Builder() .nIn(this.inputSize) .nOut(250) .weightInit(WeightInit.XAVIER) .activation(Activation.RELU) .build()) .layer(1, new OutputLayer.Builder() .nIn(250) .nOut(this.outputSize) .weightInit(WeightInit.XAVIER) .activation(Activation.SOFTMAX) .lossFunction(LossFunctions.LossFunction.NEGATIVELOGLIKELIHOOD) .build()) .build(); }
改完之后,你原来的evaluate方法不用动,传入秩1向量时预处理器会自动完成维度转换。
额外小建议
从DQN的常规应用场景来看,你当前输出层用SOFTMAX激活和NEGATIVELOGLIKELIHOOD损失函数可能不太合适——DQN一般用LINEAR(恒等)激活输出Q值,搭配MSE(均方误差)损失函数。如果你的场景是离散动作空间的Q值预测,可以调整输出层配置:
.layer(1, new OutputLayer.Builder() .nIn(250) .nOut(this.outputSize) .weightInit(WeightInit.XAVIER) .activation(Activation.IDENTITY) // 线性激活 .lossFunction(LossFunctions.LossFunction.MSE) // 均方误差损失 .build())
内容的提问来源于stack exchange,提问作者Will Maclean
相关产品推荐
相关产品推荐

