You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mxnet.apache.org by ns...@apache.org on 2018/07/22 05:57:09 UTC
[incubator-mxnet] branch master updated: Updating MultiTask example
to use new infer api and adding test for CI (#11605)
This is an automated email from the ASF dual-hosted git repository.
nswamy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-mxnet.git
The following commit(s) were added to refs/heads/master by this push:
new 7c1a49b Updating MultiTask example to use new infer api and adding test for CI (#11605)
7c1a49b is described below
commit 7c1a49b588d5bfad948c6cb3a667bcc91ff69f9f
Author: Andrew Ayres <an...@gmail.com>
AuthorDate: Sat Jul 21 22:57:03 2018 -0700
Updating MultiTask example to use new infer api and adding test for CI (#11605)
* Updating MultiTask example to use new infer api and adding test for CI
* Moved common multitask code into methods. Changed multitask test to scala suite convention
---
.../mxnetexamples/multitask/ExampleMultiTask.scala | 262 ++++++++++++---------
.../mxnetexamples/multitask/MultiTaskSuite.scala | 64 +++++
2 files changed, 211 insertions(+), 115 deletions(-)
diff --git a/scala-package/examples/src/main/scala/org/apache/mxnetexamples/multitask/ExampleMultiTask.scala b/scala-package/examples/src/main/scala/org/apache/mxnetexamples/multitask/ExampleMultiTask.scala
index c9722a2..1270af3 100644
--- a/scala-package/examples/src/main/scala/org/apache/mxnetexamples/multitask/ExampleMultiTask.scala
+++ b/scala-package/examples/src/main/scala/org/apache/mxnetexamples/multitask/ExampleMultiTask.scala
@@ -17,9 +17,16 @@
package org.apache.mxnetexamples.multitask
+import java.io.File
+import java.net.URL
+
import org.kohsuke.args4j.{CmdLineParser, Option}
import org.slf4j.LoggerFactory
+
import scala.collection.JavaConverters._
+
+import org.apache.commons.io.FileUtils
+
import org.apache.mxnet.Symbol
import org.apache.mxnet.DataIter
import org.apache.mxnet.DataBatch
@@ -29,8 +36,10 @@ import org.apache.mxnet.EvalMetric
import org.apache.mxnet.Context
import org.apache.mxnet.Xavier
import org.apache.mxnet.optimizer.RMSProp
+import org.apache.mxnet.Executor
import scala.collection.immutable.ListMap
+import scala.sys.process.Process
/**
* Example of multi-task
@@ -41,13 +50,13 @@ object ExampleMultiTask {
def buildNetwork(): Symbol = {
val data = Symbol.Variable("data")
- val fc1 = Symbol.FullyConnected("fc1")()(Map("data" -> data, "num_hidden" -> 128))
- val act1 = Symbol.Activation("relu1")()(Map("data" -> fc1, "act_type" -> "relu"))
- val fc2 = Symbol.FullyConnected("fc2")()(Map("data" -> act1, "num_hidden" -> 64))
- val act2 = Symbol.Activation("relu2")()(Map("data" -> fc2, "act_type" -> "relu"))
- val fc3 = Symbol.FullyConnected("fc3")()(Map("data" -> act2, "num_hidden" -> 10))
- val sm1 = Symbol.SoftmaxOutput("softmax1")()(Map("data" -> fc3))
- val sm2 = Symbol.SoftmaxOutput("softmax2")()(Map("data" -> fc3))
+ val fc1 = Symbol.api.FullyConnected(data = Some(data), num_hidden = 128)
+ val act1 = Symbol.api.Activation(data = Some(fc1), act_type = "relu")
+ val fc2 = Symbol.api.FullyConnected(data = Some(act1), num_hidden = 64)
+ val act2 = Symbol.api.Activation(data = Some(fc2), act_type = "relu")
+ val fc3 = Symbol.api.FullyConnected(data = Some(act2), num_hidden = 10)
+ val sm1 = Symbol.api.SoftmaxOutput(data = Some(fc3))
+ val sm2 = Symbol.api.SoftmaxOutput(data = Some(fc3))
val softmax = Symbol.Group(sm1, sm2)
@@ -133,7 +142,7 @@ object ExampleMultiTask {
for (i <- labels.indices) {
val (pred, label) = (preds(i), labels(i))
- val predLabel = NDArray.argmax_channel(pred)
+ val predLabel = NDArray.api.argmax_channel(data = pred)
require(label.shape == predLabel.shape,
s"label ${label.shape} and prediction ${predLabel.shape}" +
s"should have the same length.")
@@ -191,131 +200,154 @@ object ExampleMultiTask {
}
}
- def main(args: Array[String]): Unit = {
- val lesk = new ExampleMultiTask
- val parser: CmdLineParser = new CmdLineParser(lesk)
- try {
- parser.parseArgument(args.toList.asJava)
- assert(lesk.dataPath != null)
+ def getTrainingData: String = {
+ val baseUrl = "https://s3.us-east-2.amazonaws.com/mxnet-scala/scala-example-ci"
+ val tempDirPath = System.getProperty("java.io.tmpdir")
+ val modelDirPath = tempDirPath + File.separator + "multitask/"
+ val tmpFile = new File(tempDirPath + "/multitask/mnist.zip")
+ if (!tmpFile.exists()) {
+ FileUtils.copyURLToFile(new URL(baseUrl + "/mnist/mnist.zip"),
+ tmpFile)
+ }
- val batchSize = 100
- val numEpoch = 100
- val ctx = if (lesk.gpu != -1) Context.gpu(lesk.gpu) else Context.cpu()
- val lr = 0.001f
- val network = buildNetwork()
- val (trainIter, valIter) =
- Data.mnistIterator(lesk.dataPath, batchSize = batchSize, inputShape = Shape(784))
- val trainMultiIter = new MultiMnistIterator(trainIter)
- val valMultiIter = new MultiMnistIterator(valIter)
-
- val datasAndLabels = trainMultiIter.provideData ++ trainMultiIter.provideLabel
- val (argShapes, outputShapes, auxShapes) = network.inferShape(datasAndLabels)
-
- val initializer = new Xavier(factorType = "in", magnitude = 2.34f)
-
- val argNames = network.listArguments()
- val argDict = argNames.zip(argShapes.map(NDArray.empty(_, ctx))).toMap
- val auxNames = network.listAuxiliaryStates()
- val auxDict = auxNames.zip(auxShapes.map(NDArray.empty(_, ctx))).toMap
-
- val gradDict = argNames.zip(argShapes).filter { case (name, shape) =>
- !datasAndLabels.contains(name)
- }.map(x => x._1 -> NDArray.empty(x._2, ctx) ).toMap
-
- argDict.foreach { case (name, ndArray) =>
- if (!datasAndLabels.contains(name)) {
- initializer.initWeight(name, ndArray)
- }
- }
+ // TODO: Need to confirm with Windows
+ Process("unzip " + tempDirPath + "/multitask/mnist.zip -d "
+ + tempDirPath + "/multitask/") !
+
+ modelDirPath
+ }
- val data = argDict("data")
- val label1 = argDict("softmax1_label")
- val label2 = argDict("softmax2_label")
+ def train(batchSize: Int, numEpoch: Int, ctx: Context, modelDirPath: String):
+ (Executor, MultiAccuracy) = {
+ val lr = 0.001f
+ val network = ExampleMultiTask.buildNetwork()
+ val (trainIter, valIter) =
+ Data.mnistIterator(modelDirPath, batchSize = batchSize, inputShape = Shape(784))
+ val trainMultiIt = new MultiMnistIterator(trainIter)
+ val valMultiIter = new MultiMnistIterator(valIter)
- val maxGradNorm = 0.5f
- val executor = network.bind(ctx, argDict, gradDict)
+ val datasAndLabels = trainMultiIt.provideData ++ trainMultiIt.provideLabel
- val opt = new RMSProp(learningRate = lr, wd = 0.00001f)
+ val (argShapes, outputShapes, auxShapes) = network.inferShape(trainMultiIt.provideData("data"))
+ val initializer = new Xavier(factorType = "in", magnitude = 2.34f)
- val paramsGrads = gradDict.toList.zipWithIndex.map { case ((name, grad), idx) =>
- (idx, name, grad, opt.createState(idx, argDict(name)))
+ val argNames = network.listArguments
+ val argDict = argNames.zip(argShapes.map(NDArray.empty(_, ctx))).toMap
+
+ val gradDict = argNames.zip(argShapes).filter { case (name, shape) =>
+ !datasAndLabels.contains(name)
+ }.map(x => x._1 -> NDArray.empty(x._2, ctx)).toMap
+
+ argDict.foreach { case (name, ndArray) =>
+ if (!datasAndLabels.contains(name)) {
+ initializer.initWeight(name, ndArray)
}
+ }
- val evalMetric = new MultiAccuracy(num = 2, name = "multi_accuracy")
- val batchEndCallback = new Speedometer(batchSize, 50)
-
- for (epoch <- 0 until numEpoch) {
- // Training phase
- val tic = System.currentTimeMillis
- evalMetric.reset()
- var nBatch = 0
- var epochDone = false
- // Iterate over training data.
- trainMultiIter.reset()
-
- while (!epochDone) {
- var doReset = true
- while (doReset && trainMultiIter.hasNext) {
- val dataBatch = trainMultiIter.next()
-
- data.set(dataBatch.data(0))
- label1.set(dataBatch.label(0))
- label2.set(dataBatch.label(1))
-
- executor.forward(isTrain = true)
- executor.backward()
-
- val norm = Math.sqrt(paramsGrads.map { case (idx, name, grad, optimState) =>
- val l2Norm = NDArray.norm(grad / batchSize).toScalar
- l2Norm * l2Norm
- }.sum).toFloat
-
- paramsGrads.foreach { case (idx, name, grad, optimState) =>
- if (norm > maxGradNorm) {
- grad.set(grad.toArray.map(_ * (maxGradNorm / norm)))
- opt.update(idx, argDict(name), grad, optimState)
- } else opt.update(idx, argDict(name), grad, optimState)
- }
+ val data = argDict("data")
+ val label1 = argDict("softmaxoutput0_label")
+ val label2 = argDict("softmaxoutput1_label")
+ val maxGradNorm = 0.5f
+ val executor = network.bind(ctx, argDict, gradDict)
- // evaluate at end, so out_cpu_array can lazy copy
- evalMetric.update(dataBatch.label, executor.outputs)
+ val opt = new RMSProp(learningRate = lr, wd = 0.00001f)
- nBatch += 1
- batchEndCallback.invoke(epoch, nBatch, evalMetric)
- }
- if (doReset) {
- trainMultiIter.reset()
+ val paramsGrads = gradDict.toList.zipWithIndex.map { case ((name, grad), idx) =>
+ (idx, name, grad, opt.createState(idx, argDict(name)))
+ }
+
+ val evalMetric = new ExampleMultiTask.MultiAccuracy(num = 2, name = "multi_accuracy")
+ val batchEndCallback = new ExampleMultiTask.Speedometer(batchSize, 50)
+
+ for (epoch <- 0 until numEpoch) {
+ // Training phase
+ val tic = System.currentTimeMillis
+ evalMetric.reset()
+ var nBatch = 0
+ var epochDone = false
+ // Iterate over training data.
+ trainMultiIt.reset()
+
+ while (!epochDone) {
+ var doReset = true
+ while (doReset && trainMultiIt.hasNext) {
+ val dataBatch = trainMultiIt.next()
+
+ data.set(dataBatch.data(0))
+ label1.set(dataBatch.label(0))
+ label2.set(dataBatch.label(1))
+
+ executor.forward(isTrain = true)
+ executor.backward()
+
+ val norm = Math.sqrt(paramsGrads.map { case (idx, name, grad, optimState) =>
+ val l2Norm = NDArray.api.norm(data = (grad / batchSize)).toScalar
+ l2Norm * l2Norm
+ }.sum).toFloat
+
+ paramsGrads.foreach { case (idx, name, grad, optimState) =>
+ if (norm > maxGradNorm) {
+ grad.set(grad.toArray.map(_ * (maxGradNorm / norm)))
+ opt.update(idx, argDict(name), grad, optimState)
+ } else opt.update(idx, argDict(name), grad, optimState)
}
- // this epoch is done
- epochDone = true
+
+ // evaluate at end, so out_cpu_array can lazy copy
+ evalMetric.update(dataBatch.label, executor.outputs)
+
+ nBatch += 1
+ batchEndCallback.invoke(epoch, nBatch, evalMetric)
}
- var nameVals = evalMetric.get
- nameVals.foreach { case (name, value) =>
- logger.info(s"Epoch[$epoch] Train-$name=$value")
+ if (doReset) {
+ trainMultiIt.reset()
}
- val toc = System.currentTimeMillis
- logger.info(s"Epoch[$epoch] Time cost=${toc - tic}")
+ // this epoch is done
+ epochDone = true
+ }
+ var nameVals = evalMetric.get
+ nameVals.foreach { case (name, value) =>
+ logger.info(s"Epoch[$epoch] Train-$name=$value")
+ }
+ val toc = System.currentTimeMillis
+ logger.info(s"Epoch[$epoch] Time cost=${toc - tic}")
- evalMetric.reset()
- valMultiIter.reset()
- while (valMultiIter.hasNext) {
- val evalBatch = valMultiIter.next()
+ evalMetric.reset()
+ valMultiIter.reset()
+ while (valMultiIter.hasNext) {
+ val evalBatch = valMultiIter.next()
- data.set(evalBatch.data(0))
- label1.set(evalBatch.label(0))
- label2.set(evalBatch.label(1))
+ data.set(evalBatch.data(0))
+ label1.set(evalBatch.label(0))
+ label2.set(evalBatch.label(1))
- executor.forward(isTrain = true)
+ executor.forward(isTrain = true)
- evalMetric.update(evalBatch.label, executor.outputs)
- evalBatch.dispose()
- }
+ evalMetric.update(evalBatch.label, executor.outputs)
+ evalBatch.dispose()
+ }
- nameVals = evalMetric.get
- nameVals.foreach { case (name, value) =>
- logger.info(s"Epoch[$epoch] Validation-$name=$value")
- }
+ nameVals = evalMetric.get
+ nameVals.foreach { case (name, value) =>
+ logger.info(s"Epoch[$epoch] Validation-$name=$value")
}
+ }
+
+ (executor, evalMetric)
+ }
+
+ def main(args: Array[String]): Unit = {
+ val lesk = new ExampleMultiTask
+ val parser: CmdLineParser = new CmdLineParser(lesk)
+ try {
+ parser.parseArgument(args.toList.asJava)
+
+ val batchSize = 100
+ val numEpoch = 5
+ val ctx = if (lesk.gpu != -1) Context.gpu(lesk.gpu) else Context.cpu()
+
+ val modelPath = if (lesk.dataPath == null) lesk.dataPath else getTrainingData
+
+ val (executor, evalMetric) = train(batchSize, numEpoch, ctx, modelPath)
executor.dispose()
} catch {
diff --git a/scala-package/examples/src/test/scala/org/apache/mxnetexamples/multitask/MultiTaskSuite.scala b/scala-package/examples/src/test/scala/org/apache/mxnetexamples/multitask/MultiTaskSuite.scala
new file mode 100644
index 0000000..dab9770
--- /dev/null
+++ b/scala-package/examples/src/test/scala/org/apache/mxnetexamples/multitask/MultiTaskSuite.scala
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.mxnetexamples.multitask
+
+import org.apache.commons.io.FileUtils
+import org.apache.mxnet.Context
+import org.scalatest.FunSuite
+import org.slf4j.LoggerFactory
+import org.apache.mxnet.Symbol
+import org.apache.mxnet.DataIter
+import org.apache.mxnet.DataBatch
+import org.apache.mxnet.NDArray
+import org.apache.mxnet.Shape
+import org.apache.mxnet.EvalMetric
+import org.apache.mxnet.Context
+import org.apache.mxnet.Xavier
+import org.apache.mxnet.optimizer.RMSProp
+import java.io.File
+import java.net.URL
+
+import scala.sys.process.Process
+import scala.collection.immutable.ListMap
+import scala.collection.immutable.IndexedSeq
+import scala.collection.mutable.{ArrayBuffer, ListBuffer}
+
+
+/**
+ * Integration test for imageClassifier example.
+ * This will run as a part of "make scalatest"
+ */
+class MultiTaskSuite extends FunSuite {
+
+ test("Multitask Test") {
+ val logger = LoggerFactory.getLogger(classOf[MultiTaskSuite])
+ logger.info("Multitask Test...")
+
+ val batchSize = 100
+ val numEpoch = 10
+ val ctx = Context.cpu()
+
+ val modelPath = ExampleMultiTask.getTrainingData
+ val (executor, evalMetric) = ExampleMultiTask.train(batchSize, numEpoch, ctx, modelPath)
+ evalMetric.get.foreach { case (name, value) =>
+ assert(value >= 0.95f)
+ }
+ executor.dispose()
+ }
+
+}