You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@systemml.apache.org by mb...@apache.org on 2017/12/02 02:40:16 UTC
systemml git commit: [SYSTEMML-2035] Fix result correctness sparse
maxpooling_backward
Repository: systemml
Updated Branches:
refs/heads/master f53fcc8af -> 4d7606574
[SYSTEMML-2035] Fix result correctness sparse maxpooling_backward
So far all maxpooling backward tests ran exclusively against dense data,
which has hidden result correctness issues of sparse-dense maxpooling
backward operations and incorrect R comparison results in the presence
of duplicate values. This patch addresses these correctness issues by
explicitly correcting for unseen zero values.
Project: http://git-wip-us.apache.org/repos/asf/systemml/repo
Commit: http://git-wip-us.apache.org/repos/asf/systemml/commit/4d760657
Tree: http://git-wip-us.apache.org/repos/asf/systemml/tree/4d760657
Diff: http://git-wip-us.apache.org/repos/asf/systemml/diff/4d760657
Branch: refs/heads/master
Commit: 4d760657456cc06450ce9fc3d01ccf1e63b124eb
Parents: f53fcc8
Author: Matthias Boehm <mb...@gmail.com>
Authored: Fri Dec 1 18:35:43 2017 -0800
Committer: Matthias Boehm <mb...@gmail.com>
Committed: Fri Dec 1 18:35:43 2017 -0800
----------------------------------------------------------------------
.../runtime/matrix/data/LibMatrixDNNHelper.java | 24 ++--
.../functions/tensor/PoolBackwardTest.java | 119 ++++++++-----------
.../scripts/functions/tensor/PoolBackwardTest.R | 18 +--
.../functions/tensor/PoolBackwardTest.dml | 16 ++-
4 files changed, 84 insertions(+), 93 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/systemml/blob/4d760657/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixDNNHelper.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixDNNHelper.java b/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixDNNHelper.java
index be8a833..7b749dd 100644
--- a/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixDNNHelper.java
+++ b/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixDNNHelper.java
@@ -20,6 +20,7 @@ package org.apache.sysml.runtime.matrix.data;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.BitSet;
import java.util.concurrent.Callable;
import org.apache.sysml.hops.OptimizerUtils;
@@ -421,10 +422,12 @@ public class LibMatrixDNNHelper {
int [] tensorIndexes = new int[3];
- int start_index_h = params.start_indexes_h[p];
- int end_index_h = params.end_indexes_h[p];
- int start_index_w = params.start_indexes_w[q];
- int end_index_w = params.end_indexes_w[q];
+ int start_h = params.start_indexes_h[p];
+ int end_h = params.end_indexes_h[p];
+ int start_w = params.start_indexes_w[q];
+ int end_w = params.end_indexes_w[q];
+ int numVals = (end_h-start_h)*(end_w-start_w);
+ BitSet bmap = new BitSet(numVals);
int maxIndex = -1;
double maxVal = -Double.MAX_VALUE;
@@ -446,17 +449,24 @@ public class LibMatrixDNNHelper {
continue;
int h = tensorIndexes[1];
int w = tensorIndexes[2];
- if(h >= start_index_h && h < end_index_h && w >= start_index_w && w < end_index_w) {
+ if(h >= start_h && h < end_h && w >= start_w && w < end_w) {
double val = performReluBackward && avals[j] < 0 ? 0 : avals[j];
if(maxVal < val) {
maxIndex = inputOffset + h*params.W + w;
maxVal = val;
}
+ bmap.set((h-start_h)*(end_w-start_w) + (w-start_w));
}
}
}
- else {
- maxIndex = inputOffset;
+
+ //correction for 0 maximum and subset of evaluated entries
+ int firstMiss = bmap.nextClearBit(0);
+ if( firstMiss < numVals && maxVal<0 ) {
+ int lh = firstMiss/(end_w-start_w)+start_h;
+ int lw = firstMiss%(end_w-start_w)+start_w;
+ maxIndex = inputOffset + lh * params.W + lw;
+ maxVal = 0;
}
return maxIndex;
}
http://git-wip-us.apache.org/repos/asf/systemml/blob/4d760657/src/test/java/org/apache/sysml/test/integration/functions/tensor/PoolBackwardTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/sysml/test/integration/functions/tensor/PoolBackwardTest.java b/src/test/java/org/apache/sysml/test/integration/functions/tensor/PoolBackwardTest.java
index 54fda03..ca3a19a 100644
--- a/src/test/java/org/apache/sysml/test/integration/functions/tensor/PoolBackwardTest.java
+++ b/src/test/java/org/apache/sysml/test/integration/functions/tensor/PoolBackwardTest.java
@@ -32,7 +32,6 @@ import org.junit.Test;
public class PoolBackwardTest extends AutomatedTestBase
{
-
private final static String TEST_NAME = "PoolBackwardTest";
private final static String TEST_DIR = "functions/tensor/";
private final static String TEST_CLASS_DIR = TEST_DIR + PoolBackwardTest.class.getSimpleName() + "/";
@@ -40,157 +39,133 @@ public class PoolBackwardTest extends AutomatedTestBase
@Override
public void setUp() {
- addTestConfiguration(TEST_NAME, new TestConfiguration(TEST_CLASS_DIR, TEST_NAME,
- new String[] {"B"}));
+ addTestConfiguration(TEST_NAME, new TestConfiguration(TEST_CLASS_DIR, TEST_NAME, new String[] {"B"}));
}
@Test
- public void testMaxPool2DBackwardDense1()
- {
+ public void testMaxPool2DBackwardDense1() {
int numImg = 1; int imgSize = 4; int numChannels = 1; int stride = 2; int pad = 0; int poolSize1 = 2; int poolSize2 = 2;
runPoolTest(ExecType.CP, imgSize, numImg, numChannels, stride, pad, poolSize1, poolSize2, "max", false, false);
}
@Test
- public void testMaxPool2DBackwardDense2()
- {
+ public void testMaxPool2DBackwardDense2() {
int numImg = 3; int imgSize = 6; int numChannels = 3; int stride = 1; int pad = 0; int poolSize1 = 2; int poolSize2 = 2;
runPoolTest(ExecType.CP, imgSize, numImg, numChannels, stride, pad, poolSize1, poolSize2, "max", false, false);
}
@Test
- public void testMaxPool2DBackwardDense3()
- {
+ public void testMaxPool2DBackwardDense3() {
int numImg = 2; int imgSize = 7; int numChannels = 2; int stride = 2; int pad = 0; int poolSize1 = 3; int poolSize2 = 3;
runPoolTest(ExecType.CP, imgSize, numImg, numChannels, stride, pad, poolSize1, poolSize2, "max", false, false);
}
@Test
- public void testMaxPool2DBackwardSparse1()
- {
+ public void testMaxPool2DBackwardSparse1() {
int numImg = 1; int imgSize = 4; int numChannels = 1; int stride = 2; int pad = 0; int poolSize1 = 2; int poolSize2 = 2;
runPoolTest(ExecType.CP, imgSize, numImg, numChannels, stride, pad, poolSize1, poolSize2, "max", true, false);
}
@Test
- public void testMaxPool2DBackwardSparse2()
- {
+ public void testMaxPool2DBackwardSparse2() {
int numImg = 3; int imgSize = 6; int numChannels = 3; int stride = 1; int pad = 0; int poolSize1 = 2; int poolSize2 = 2;
runPoolTest(ExecType.CP, imgSize, numImg, numChannels, stride, pad, poolSize1, poolSize2, "max", true, false);
}
@Test
- public void testMaxPool2DBackwardSparse3()
- {
+ public void testMaxPool2DBackwardSparse3() {
int numImg = 2; int imgSize = 7; int numChannels = 2; int stride = 2; int pad = 0; int poolSize1 = 3; int poolSize2 = 3;
runPoolTest(ExecType.CP, imgSize, numImg, numChannels, stride, pad, poolSize1, poolSize2, "max", true, false);
}
@Test
- public void testMaxPool2DBackwardSparse4()
- {
+ public void testMaxPool2DBackwardSparse4() {
int numImg = 1; int imgSize = 4; int numChannels = 1; int stride = 2; int pad = 0; int poolSize1 = 2; int poolSize2 = 2;
runPoolTest(ExecType.CP, imgSize, numImg, numChannels, stride, pad, poolSize1, poolSize2, "max", true, true);
}
@Test
- public void testMaxPool2DBackwardSparse5()
- {
+ public void testMaxPool2DBackwardSparse5() {
int numImg = 3; int imgSize = 6; int numChannels = 3; int stride = 1; int pad = 0; int poolSize1 = 2; int poolSize2 = 2;
runPoolTest(ExecType.CP, imgSize, numImg, numChannels, stride, pad, poolSize1, poolSize2, "max", true, true);
}
@Test
- public void testMaxPool2DBackwardSparse6()
- {
+ public void testMaxPool2DBackwardSparse6() {
int numImg = 2; int imgSize = 7; int numChannels = 2; int stride = 2; int pad = 0; int poolSize1 = 3; int poolSize2 = 3;
runPoolTest(ExecType.CP, imgSize, numImg, numChannels, stride, pad, poolSize1, poolSize2, "max", true, true);
}
@Test
- public void testMaxPool2DBackwardSparse7()
- {
+ public void testMaxPool2DBackwardSparse7() {
int numImg = 1; int imgSize = 4; int numChannels = 1; int stride = 2; int pad = 0; int poolSize1 = 2; int poolSize2 = 2;
runPoolTest(ExecType.CP, imgSize, numImg, numChannels, stride, pad, poolSize1, poolSize2, "max", false, true);
}
@Test
- public void testMaxPool2DBackwardSparse8()
- {
+ public void testMaxPool2DBackwardSparse8() {
int numImg = 3; int imgSize = 6; int numChannels = 3; int stride = 1; int pad = 0; int poolSize1 = 2; int poolSize2 = 2;
runPoolTest(ExecType.CP, imgSize, numImg, numChannels, stride, pad, poolSize1, poolSize2, "max", false, true);
}
@Test
- public void testMaxPool2DBackwardSparse9()
- {
+ public void testMaxPool2DBackwardSparse9() {
int numImg = 2; int imgSize = 7; int numChannels = 2; int stride = 2; int pad = 0; int poolSize1 = 3; int poolSize2 = 3;
runPoolTest(ExecType.CP, imgSize, numImg, numChannels, stride, pad, poolSize1, poolSize2, "max", false, true);
}
- /**
- *
- * @param et
- * @param sparse
- */
+ @Test
+ public void testMaxPool2DBackwardSparse10() {
+ int numImg = 10; int imgSize = 28; int numChannels = 1; int stride = 1; int pad = 0; int poolSize1 = 5; int poolSize2 = 5;
+ runPoolTest(ExecType.CP, imgSize, numImg, numChannels, stride, pad, poolSize1, poolSize2, "max", true, false);
+ }
+
public void runPoolTest( ExecType et, int imgSize, int numImg, int numChannels, int stride,
int pad, int poolSize1, int poolSize2, String poolMode, boolean sparse1, boolean sparse2)
{
- RUNTIME_PLATFORM oldRTP = rtplatform;
-
+ RUNTIME_PLATFORM platformOld = rtplatform;
+ switch( et ){
+ case MR: rtplatform = RUNTIME_PLATFORM.HADOOP; break;
+ case SPARK: rtplatform = RUNTIME_PLATFORM.SPARK; break;
+ default: rtplatform = RUNTIME_PLATFORM.HYBRID; break;
+ }
boolean sparkConfigOld = DMLScript.USE_LOCAL_SPARK_CONFIG;
-
+ if( rtplatform == RUNTIME_PLATFORM.SPARK )
+ DMLScript.USE_LOCAL_SPARK_CONFIG = true;
+
try
{
- String sparseVal1 = (""+sparse1).toUpperCase();
- String sparseVal2 = (""+sparse2).toUpperCase();
+ String sparseVal1 = String.valueOf(sparse1).toUpperCase();
+ String sparseVal2 = String.valueOf(sparse2).toUpperCase();
TestConfiguration config = getTestConfiguration(TEST_NAME);
- if(et == ExecType.SPARK) {
- rtplatform = RUNTIME_PLATFORM.SPARK;
- }
- else {
- rtplatform = (et==ExecType.MR)? RUNTIME_PLATFORM.HADOOP : RUNTIME_PLATFORM.SINGLE_NODE;
- }
- if( rtplatform == RUNTIME_PLATFORM.SPARK )
- DMLScript.USE_LOCAL_SPARK_CONFIG = true;
-
loadTestConfiguration(config);
-
- /* This is for running the junit test the new way, i.e., construct the arguments directly */
- String RI_HOME = SCRIPT_DIR + TEST_DIR;
- fullDMLScriptName = RI_HOME + TEST_NAME + ".dml";
long P = ConvolutionUtils.getP(imgSize, poolSize1, stride, pad);
- programArgs = new String[]{"-explain", "-args", "" + imgSize, "" + numImg,
- "" + numChannels, "" + poolSize1, "" + poolSize2,
- "" + stride, "" + pad, poolMode,
- "" + P, "" + P,
- output("B"), sparseVal1, sparseVal2};
-
- boolean exceptionExpected = false;
- int expectedNumberOfJobs = -1;
- runTest(true, exceptionExpected, null, expectedNumberOfJobs);
+
+ String RI_HOME = SCRIPT_DIR + TEST_DIR;
+ fullDMLScriptName = RI_HOME + TEST_NAME + ".dml";
+ programArgs = new String[]{"-explain", "-args", String.valueOf(imgSize), String.valueOf(numImg),
+ String.valueOf(numChannels), String.valueOf(poolSize1), String.valueOf(poolSize2),
+ String.valueOf(stride), String.valueOf(pad), String.valueOf(poolMode),
+ String.valueOf(P), String.valueOf(P), output("B"), sparseVal1, sparseVal2};
fullRScriptName = RI_HOME + TEST_NAME + ".R";
- rCmd = "Rscript" + " " + fullRScriptName + " " + imgSize + " " + numImg +
- " " + numChannels + " " + poolSize1 +
- " " + poolSize2 + " " + stride + " " + pad + " " + P + " " + P + " " + expectedDir() +
- " " + sparseVal1 + " " + sparseVal2;
+ rCmd = "Rscript" + " " + fullRScriptName + " " + imgSize + " " + numImg + " " + numChannels +
+ " " + poolSize1 + " " + poolSize2 + " " + stride + " " + pad + " " + P + " " + P +
+ " " + expectedDir() + " " + sparseVal1 + " " + sparseVal2;
- // Run comparison R script
+ // run dml and r scripts
+ runTest(true, false, null, -1);
runRScript(true);
- HashMap<CellIndex, Double> bHM = readRMatrixFromFS("B");
+ // compare results
+ HashMap<CellIndex, Double> bHM = readRMatrixFromFS("B");
HashMap<CellIndex, Double> dmlfile = readDMLMatrixFromHDFS("B");
- TestUtils.compareMatrices(dmlfile, bHM, epsilon, "B-DML", "NumPy");
-
+ TestUtils.compareMatrices(dmlfile, bHM, epsilon, "B-DML", "R");
}
- finally
- {
- rtplatform = oldRTP;
+ finally {
+ rtplatform = platformOld;
DMLScript.USE_LOCAL_SPARK_CONFIG = sparkConfigOld;
}
-
}
-
}
http://git-wip-us.apache.org/repos/asf/systemml/blob/4d760657/src/test/scripts/functions/tensor/PoolBackwardTest.R
----------------------------------------------------------------------
diff --git a/src/test/scripts/functions/tensor/PoolBackwardTest.R b/src/test/scripts/functions/tensor/PoolBackwardTest.R
index f3133a7..b56331e 100644
--- a/src/test/scripts/functions/tensor/PoolBackwardTest.R
+++ b/src/test/scripts/functions/tensor/PoolBackwardTest.R
@@ -35,15 +35,17 @@ Q=as.integer(args[9])
x=matrix(seq(1, numImg*numChannels*imgSize*imgSize), numImg, numChannels*imgSize*imgSize, byrow=TRUE)
dout=matrix(seq(1, numImg*numChannels*P*Q), numImg, numChannels*P*Q, byrow=TRUE)
if(as.logical(args[11])) {
- # zero_mask = (x - mean(x)) > 0
- # x = x * zero_mask
+ zero_mask = (x - mean(x)*1.5) > 0
+ x = x * zero_mask
+} else {
+ x = x - mean(x)
}
if(as.logical(args[12])) {
- # zero_mask = (dout - mean(dout)) > 0
- # dout = dout * zero_mask
+ zero_mask = (dout - mean(dout)*1.5) > 0
+ dout = dout * zero_mask
+} else {
+ dout = dout - mean(dout)
}
-x = x - mean(x)
-dout = dout - mean(dout)
max_pool_backward <- function(dout, Hout, Wout, X, C,
Hin, Win, Hf, Wf, strideh, stridew)
{
@@ -65,7 +67,8 @@ max_pool_backward <- function(dout, Hout, Wout, X, C,
win = (wout-1) * stridew + 1
img_slice_patch = img_slice[hin:(hin+Hf-1), win:(win+Wf-1)]
max_val = max(img_slice_patch)
- max_val_ind = (img_slice_patch == max_val) # max value indicator
+ max_val_ind = matrix(0, nrow(img_slice_patch), ncol(img_slice_patch))
+ max_val_ind[which.max(img_slice_patch)] = 1 # first max value indicator
# gradient passes through only for the max value in this patch
dimg_slice_patch = max_val_ind * dout[n, (c-1)*Hout*Wout + (hout-1)*Wout + wout]
dimg_slice[hin:(hin+Hf-1), win:(win+Wf-1)] =
@@ -82,4 +85,3 @@ max_pool_backward <- function(dout, Hout, Wout, X, C,
output = max_pool_backward(dout, P, Q, x, numChannels, imgSize, imgSize, poolSize1, poolSize2, stride, stride)
writeMM(as(output,"CsparseMatrix"), paste(args[10], "B", sep=""))
-
http://git-wip-us.apache.org/repos/asf/systemml/blob/4d760657/src/test/scripts/functions/tensor/PoolBackwardTest.dml
----------------------------------------------------------------------
diff --git a/src/test/scripts/functions/tensor/PoolBackwardTest.dml b/src/test/scripts/functions/tensor/PoolBackwardTest.dml
index 22f778f..ea0f970 100644
--- a/src/test/scripts/functions/tensor/PoolBackwardTest.dml
+++ b/src/test/scripts/functions/tensor/PoolBackwardTest.dml
@@ -34,15 +34,19 @@ Q = $10
x=matrix(seq(1, numImg*numChannels*imgSize*imgSize), rows=numImg, cols=numChannels*imgSize*imgSize)
dout=matrix(seq(1, numImg*numChannels*P*Q), rows=numImg, cols=numChannels*P*Q)
if($12) {
- # zero_mask = (x - mean(x)) > 0
- # x = x * zero_mask
+ zero_mask = (x - mean(x)*1.5) > 0
+ x = x * zero_mask
+}
+else {
+ x = x - mean(x)
}
if($13) {
- # zero_mask = (dout - mean(dout)) > 0
- # dout = dout * zero_mask
+ zero_mask = (dout - mean(dout)*1.5) > 0
+ dout = dout * zero_mask
+}
+else {
+ dout = dout - mean(dout)
}
-x = x - mean(x)
-dout = dout - mean(dout)
if(poolMode == "max") {
output = max_pool_backward(x, dout, stride=[stride, stride], padding=[pad, pad], input_shape=[numImg, numChannels, imgSize, imgSize], pool_size=[poolSize1, poolSize2])
}