【问题标题】:SparkML MultilayerPerceptron error: java.lang.ArrayIndexOutOfBoundsExceptionSparkML MultilayerPerceptron 错误:java.lang.ArrayIndexOutOfBoundsException
【发布时间】:2023-03-18 02:08:01
【问题描述】:

我想使用 SparkML MultilayerPerceptronClassifier() 估计以下模型。

val formula = new RFormula()
  .setFormula("vtplus15predict~ vhisttplus15 + vhistt + vt + vtminus15 + Time + Length + Day")
  .setFeaturesCol("features")
  .setLabelCol("label")

formula.fit(data).transform(data)

注意:特征是向量,标签是Double

root
 |-- features: vector (nullable = true)
 |-- label: double (nullable = false)

我将 MLP 估计器定义如下:

val layers = Array[Int](6, 5, 8, 1) //I suspect this is where it went wrong

val mlp = new MultilayerPerceptronClassifier()
  .setLayers(layers)
  .setBlockSize(128)
  .setSeed(1234L)
  .setMaxIter(100)

// train the model
val model = mlp.fit(train)

很遗憾,我收到以下错误:

使用 Spark 的默认 log4j 配置文件:org/apache/spark/log4j-defaults.properties

线程“主”org.apache.spark.SparkException 中的异常:作业因阶段失败而中止:阶段 3.0 中的任务 0 失败 1 次,最近一次失败:阶段 3.0 中丢失任务 0.0(TID 3,本地主机,执行程序驱动程序):java.lang.ArrayIndexOutOfBoundsException:11 在 org.apache.spark.ml.classification.LabelConverter$.encodeLabeledPoint(MultilayerPerceptronClassifier.scala:121) 在 org.apache.spark.ml.classification.MultilayerPerceptronClassifier$$anonfun$3.apply(MultilayerPerceptronClassifier.scala:245) 在 org.apache.spark.ml.classification.MultilayerPerceptronClassifier$$anonfun$3.apply(MultilayerPerceptronClassifier.scala:245) 在 scala.collection.Iterator$$anon$11.next(Iterator.scala:363) 在 scala.collection.Iterator$GroupedIterator.takeDestructively(Iterator.scala:935) 在 scala.collection.Iterator$GroupedIterator.go(Iterator.scala:950) ...

【问题讨论】:

    标签: scala apache-spark neural-network apache-spark-mllib apache-spark-ml


    【解决方案1】:

    org.apache.spark.ml.classification.LabelConverter$.encodeLabeledPoint(MultilayerPerceptronClassifier.scala:121)

    这告诉我们MultilayerPerceptronClassifier.scala文件中有一个数组越界,让我们看看那里的代码:

    def encodeLabeledPoint(labeledPoint: LabeledPoint, labelCount: Int): (Vector, Vector) = {
      val output = Array.fill(labelCount)(0.0)
      output(labeledPoint.label.toInt) = 1.0
      (labeledPoint.features, Vectors.dense(output))
    }
    

    它对数据集中的标签执行 one-hot 编码。 ArrayIndexOutOfBoundsException 出现是因为 output 数组太短。

    回溯代码,可以发现labelCountlayers数组中的输出节点数相同。换句话说,输出节点的数量应该与类的数量相同。查看 MLP 的 documentation 有以下行:

    输出层的节点数N对应类数。

    因此,解决方案是:

    1. 改变网络最后一层的节点数(输出节点)

    2. 重构数据,使其具有与网络输出节点相同数量的类。

    注意:最终输出层应始终为 2 或更多,而不是 1,因为每个类应该有一个节点,单个类的问题没有意义。

    【讨论】:

      【解决方案2】:

      重新排列您的数据集,因为错误表明您的数组少于功能集中的数组,或者您的数据集包含提示错误的空集。我在处理 MLP 项目时遇到了这种类型的错误。希望我的答案可以帮助你。 感谢您与我们联系

      【讨论】:

        【解决方案3】:

        解决方案是首先找到允许一个人逃脱 ArrayIndexOutBound 的局部最优,然后使用蛮力搜索找到全局最优。 Shaido 建议找n

        例如,val layers = 数组[整数](6, 5, 8, n)。这假设特征向量的长度 是 6. – Shaido

        所以让n 成为一个大整数(n =100)然后手动使用暴力搜索来获得一个好的解决方案(n =50 然后尝试n =32 - 错误,n = 35 - 完美)。

        感谢 Shaido。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-03-27
          相关资源
          最近更新 更多