Repository: systemml
Updated Branches:
  refs/heads/master b5ef21fdc -> 61dcc85e4


http://git-wip-us.apache.org/repos/asf/systemml/blob/61dcc85e/src/main/scala/org/apache/sysml/api/dl/CaffeLayer.scala
----------------------------------------------------------------------
diff --git a/src/main/scala/org/apache/sysml/api/dl/CaffeLayer.scala 
b/src/main/scala/org/apache/sysml/api/dl/CaffeLayer.scala
index c8159be..1466f4f 100644
--- a/src/main/scala/org/apache/sysml/api/dl/CaffeLayer.scala
+++ b/src/main/scala/org/apache/sysml/api/dl/CaffeLayer.scala
@@ -135,6 +135,28 @@ trait CaffeLayer extends BaseDMLGenerator {
 
 trait IsLossLayer extends CaffeLayer {
   def computeLoss(dmlScript: StringBuilder, numTabs: Int): Unit
+  override def init(dmlScript: StringBuilder) = { }
+  def scores(): String = {
+    val ret = net.getBottomLayers(param.getName).map(l => 
net.getCaffeLayer(l)).toList
+    ret.size.toLong match {
+      case 0L => throw new LanguageException("Expected atleast 1 bottom layer")
+      case 1L => ret.get(0).out
+      case _ => {
+        val ret1 = ret.filter(!_.out.equals("Xb")).toList
+        ret1.size.toLong match {
+          case 0L => throw new LanguageException("Atleast one of the output of 
previous layer should be Xb")
+          case 1L => ret1.get(0).out
+          case _ => throw new LanguageException("More than 2 bottom layers is 
not supported")
+        }
+      }
+    }
+  }
+  def isSegmentationProblem(): Boolean =
+    try {
+      return outputShape._2.toInt != 1 && outputShape._3.toInt != 1
+    } catch {
+      case _: Throwable => throw new RuntimeException("Cannot infer the output 
dimensions:" + outputShape)
+    }
 }
 
 trait HasWeight extends CaffeLayer {
@@ -508,16 +530,35 @@ class Concat(val param: LayerParameter, val id: Int, val 
net: CaffeNetwork) exte
   override def biasShape(): Array[Int]   = null
 }
 
+// L2 loss function.
+class EuclideanLoss(val param: LayerParameter, val id: Int, val net: 
CaffeNetwork) extends CaffeLayer with IsLossLayer {
+  override def sourceFileName: String = if (!isSegmentationProblem()) 
"l2_loss" else throw new DMLRuntimeException("Segmentation is not supported for 
EuclideanLoss in Caffe2DML yet")
+  override def weightShape(): Array[Int] = null
+  override def biasShape(): Array[Int]   = null
+  
+  override def forward(dmlScript: StringBuilder, isPrediction: Boolean) =
+    invokeForward(dmlScript, List[String](out), scores, "yb")
+  
+  override def backward(dmlScript: StringBuilder,outSuffix: String): Unit = 
+      invokeBackward(dmlScript, outSuffix, List[String]("dOut" + id + 
outSuffix), scores, "yb")
+  
+  override def computeLoss(dmlScript: StringBuilder,numTabs: Int): Unit =
+    if (!isSegmentationProblem()) {
+      val tabBuilder = new StringBuilder
+      for (i <- 0 until numTabs) tabBuilder.append("\t")
+      val tabs = tabBuilder.toString
+      dmlScript.append("tmp_loss = l2_loss::forward(" + commaSep(out, "yb") + 
")\n")
+      dmlScript.append(tabs).append("loss = loss + tmp_loss\n")
+      dmlScript.append(tabs).append("accuracy = -1\n")
+    } else {
+      throw new RuntimeException("Computation of loss for SoftmaxWithLoss is 
not implemented for segmentation problem")
+    }
+}
+
 class SoftmaxWithLoss(val param: LayerParameter, val id: Int, val net: 
CaffeNetwork) extends CaffeLayer with IsLossLayer {
   // -------------------------------------------------
   override def sourceFileName                 = if (!isSegmentationProblem()) 
"softmax" else "softmax2d"
   override def init(dmlScript: StringBuilder) = {}
-  def isSegmentationProblem(): Boolean =
-    try {
-      return outputShape._2.toInt != 1 && outputShape._3.toInt != 1
-    } catch {
-      case _: Throwable => throw new RuntimeException("Cannot infer the output 
dimensions:" + outputShape)
-    }
   override def forward(dmlScript: StringBuilder, isPrediction: Boolean) =
     if (!isSegmentationProblem()) {
       invokeForward(dmlScript, List[String](out), scores)
@@ -549,18 +590,6 @@ class SoftmaxWithLoss(val param: LayerParameter, val id: 
Int, val net: CaffeNetw
     } else {
       throw new RuntimeException("Computation of loss for SoftmaxWithLoss is 
not implemented for segmentation problem")
     }
-  def scores(): String = {
-    val ret = net.getBottomLayers(param.getName).map(l => 
net.getCaffeLayer(l)).toList
-    if (ret.size == 1) return ret.get(0).out
-    else if (ret.size == 2) {
-      val ret1 = if (!ret.get(0).out.equals("Xb")) ret.get(0).out else "";
-      val ret2 = if (!ret.get(1).out.equals("Xb")) ret.get(1).out else "";
-      if (!ret1.equals("") && !ret2.equals("")) throw new 
LanguageException("Atleast one of the output of previous layer should be Xb")
-      else if (!ret1.equals("")) return ret1
-      else return ret2
-    } else
-      throw new LanguageException("More than 2 bottom layers is not supported")
-  }
   override def weightShape(): Array[Int] = null
   override def biasShape(): Array[Int]   = null
   // -------------------------------------------------
@@ -574,6 +603,72 @@ class SoftmaxWithLoss(val param: LayerParameter, val id: 
Int, val net: CaffeNetw
   }
 }
 
+class Sigmoid(val param: LayerParameter, val id: Int, val net: CaffeNetwork) 
extends CaffeLayer {
+  override def sourceFileName                 = "sigmoid"
+  override def init(dmlScript: StringBuilder) = {}
+  /*
+   * Computes the forward pass for a sigmoid nonlinearity layer.
+   *
+   *   `sigmoid(x) = 1 / (1 + e^-x)`
+   *
+   * If `X` contains a single feature column, the output of a sigmoid
+   * layer can be interpreted as a predicted probability of a true
+   * class when paired with a log loss function in a binary
+   * classification problem.
+   *
+   * Inputs:
+   *  - X: Inputs, of shape (any, any).
+   *
+   * Outputs:
+   *  - out: Outputs, of same shape as `X`.
+   */
+  override def forward(dmlScript: StringBuilder, isPrediction: Boolean) = 
invokeForward(dmlScript, List[String](out), X)
+  /*
+   * Computes the backward pass for a sigmoid nonlinearity layer.
+   *
+   * Inputs:
+   *  - dout: Gradient wrt `out` from upstream, of same shape as `X`.
+   *  - X: Inputs, of shape (any, any).
+   *
+   * Outputs:
+   *  - dX: Gradient wrt `X`, of same shape as `X`.
+   */
+  override def backward(dmlScript: StringBuilder, outSuffix: String) = 
invokeBackward(dmlScript, outSuffix, List[String]("dOut" + id), dout, X)
+  override def weightShape(): Array[Int]                             = null
+  override def biasShape(): Array[Int]                               = null
+  // -------------------------------------------------
+}
+
+
+class TanH(val param: LayerParameter, val id: Int, val net: CaffeNetwork) 
extends CaffeLayer {
+  override def sourceFileName                 = "tanh"
+  override def init(dmlScript: StringBuilder) = {}
+  /*
+   * Computes the forward pass for a tanh nonlinearity layer.
+   *
+   * Inputs:
+   *  - X: Inputs, of shape (any, any).
+   *
+   * Outputs:
+   *  - out: Outputs, of same shape as `X`.
+   */
+  override def forward(dmlScript: StringBuilder, isPrediction: Boolean) = 
invokeForward(dmlScript, List[String](out), X)
+  /*
+   * Computes the backward pass for a tanh nonlinearity layer.
+   *
+   * Inputs:
+   *  - dout: Gradient wrt `out` from upstream, of same shape as `X`.
+   *  - X: Inputs, of shape (any, any).
+   *
+   * Outputs:
+   *  - dX: Gradient wrt `X`, of same shape as `X`.
+   */
+  override def backward(dmlScript: StringBuilder, outSuffix: String) = 
invokeBackward(dmlScript, outSuffix, List[String]("dOut" + id), dout, X)
+  override def weightShape(): Array[Int]                             = null
+  override def biasShape(): Array[Int]                               = null
+  // -------------------------------------------------
+}
+
 class ReLU(val param: LayerParameter, val id: Int, val net: CaffeNetwork) 
extends CaffeLayer {
   // TODO: Leaky ReLU: negative_slope [default 0]: specifies whether to leak 
the negative part by multiplying it with the slope value rather than setting it 
to 0.
   // -------------------------------------------------

http://git-wip-us.apache.org/repos/asf/systemml/blob/61dcc85e/src/main/scala/org/apache/sysml/api/dl/CaffeNetwork.scala
----------------------------------------------------------------------
diff --git a/src/main/scala/org/apache/sysml/api/dl/CaffeNetwork.scala 
b/src/main/scala/org/apache/sysml/api/dl/CaffeNetwork.scala
index 2b07788..93afbc0 100644
--- a/src/main/scala/org/apache/sysml/api/dl/CaffeNetwork.scala
+++ b/src/main/scala/org/apache/sysml/api/dl/CaffeNetwork.scala
@@ -212,7 +212,10 @@ class CaffeNetwork(netFilePath: String, val currentPhase: 
Phase, var numChannels
         else throw new LanguageException("Only maxpooling is supported:" + 
param.getPoolingParam.getPool.name)
       case "innerproduct"    => new InnerProduct(param, id, this)
       case "relu"            => new ReLU(param, id, this)
+      case "tanh"            => new TanH(param, id, this)
+      case "sigmoid"         => new Sigmoid(param, id, this)
       case "softmaxwithloss" => new SoftmaxWithLoss(param, id, this)
+      case "euclideanloss"   => new EuclideanLoss(param, id, this)
       case "dropout"         => new Dropout(param, id, this)
       case "data"            => new Data(param, id, this, numChannels, height, 
width)
       case "input"           => new Data(param, id, this, numChannels, height, 
width)

Reply via email to