Small fixes to subsampling layer (#158)

Signed-off-by: AlexDBlack <blacka101@gmail.com>
master
Alex Black 2019-08-23 22:50:07 +10:00 committed by GitHub
parent 614c687e4b
commit 8e3d569f18
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 59 additions and 47 deletions

View File

@ -190,7 +190,7 @@ public class LayerHelperValidationUtil {
} else {
System.out.println("OK: " + p);
}
assertTrue("Gradients are not equal: " + p + " - highest relative error = " + maxRE + " > max relative error = " + t.getMaxRelError(),
assertTrue(t.getTestName() + " - Gradients are not equal: " + p + " - highest relative error = " + maxRE + " > max relative error = " + t.getMaxRelError(),
maxRE < t.getMaxRelError());
}
}

View File

@ -57,56 +57,62 @@ public class ValidateMKLDNN extends BaseDL4JTest {
for (ConvolutionMode cm : new ConvolutionMode[]{ConvolutionMode.Same, ConvolutionMode.Truncate}) {
for (int[] kernel : new int[][]{{2, 2}, {2, 3}}) {
for (int[] stride : new int[][]{{1, 1}, {2, 2}}) {
for (PoolingType pt : new PoolingType[]{PoolingType.MAX, PoolingType.AVG}) {
inputSize[0] = minibatch;
INDArray f = Nd4j.rand(DataType.FLOAT, inputSize);
INDArray l = TestUtils.randomOneHot(minibatch, 10).castTo(DataType.FLOAT);
inputSize[0] = minibatch;
INDArray f = Nd4j.rand(DataType.FLOAT, inputSize);
INDArray l = TestUtils.randomOneHot(minibatch, 10).castTo(DataType.FLOAT);
MultiLayerConfiguration conf = new NeuralNetConfiguration.Builder()
.updater(new Adam(0.01))
.convolutionMode(cm)
.seed(12345)
.list()
.layer(new ConvolutionLayer.Builder().activation(Activation.TANH)
.kernelSize(kernel)
.stride(stride)
.padding(0,0)
.nOut(3)
.build())
.layer(new SubsamplingLayer.Builder()
.kernelSize(kernel)
.stride(stride)
.padding(0,0)
.build())
.layer(new ConvolutionLayer.Builder().activation(Activation.TANH)
.kernelSize(kernel)
.stride(stride)
.padding(0,0)
.nOut(3)
.build())
.layer(new OutputLayer.Builder().nOut(10).activation(Activation.SOFTMAX).lossFunction(LossFunctions.LossFunction.MCXENT).build())
.setInputType(InputType.convolutional(inputSize[2], inputSize[3], inputSize[1]))
.build();
MultiLayerConfiguration conf = new NeuralNetConfiguration.Builder()
.updater(new Adam(0.01))
.convolutionMode(cm)
.seed(12345)
.list()
.layer(new ConvolutionLayer.Builder().activation(Activation.TANH)
.kernelSize(kernel)
.stride(stride)
.padding(0, 0)
.nOut(3)
.build())
.layer(new SubsamplingLayer.Builder()
.poolingType(pt)
.kernelSize(kernel)
.stride(stride)
.padding(0, 0)
.build())
.layer(new ConvolutionLayer.Builder().activation(Activation.TANH)
.kernelSize(kernel)
.stride(stride)
.padding(0, 0)
.nOut(3)
.build())
.layer(new OutputLayer.Builder().nOut(10).activation(Activation.SOFTMAX).lossFunction(LossFunctions.LossFunction.MCXENT).build())
.setInputType(InputType.convolutional(inputSize[2], inputSize[3], inputSize[1]))
.build();
MultiLayerNetwork netWith = new MultiLayerNetwork(conf.clone());
netWith.init();
MultiLayerNetwork netWith = new MultiLayerNetwork(conf.clone());
netWith.init();
MultiLayerNetwork netWithout = new MultiLayerNetwork(conf.clone());
netWithout.init();
MultiLayerNetwork netWithout = new MultiLayerNetwork(conf.clone());
netWithout.init();
LayerHelperValidationUtil.TestCase tc = LayerHelperValidationUtil.TestCase.builder()
.allowHelpersForClasses(Arrays.<Class<?>>asList(org.deeplearning4j.nn.layers.convolution.subsampling.SubsamplingLayer.class,
org.deeplearning4j.nn.layers.convolution.ConvolutionLayer.class))
.testForward(true)
.testScore(true)
.testBackward(true)
.testTraining(true)
.features(f)
.labels(l)
.data(new SingletonDataSetIterator(new DataSet(f,l)))
.build();
String name = pt + ", mb=" + minibatch + ", cm=" + cm + ", kernel=" + Arrays.toString(kernel) + ", stride=" + Arrays.toString(stride);
LayerHelperValidationUtil.TestCase tc = LayerHelperValidationUtil.TestCase.builder()
.testName(name)
.allowHelpersForClasses(Arrays.<Class<?>>asList(org.deeplearning4j.nn.layers.convolution.subsampling.SubsamplingLayer.class,
org.deeplearning4j.nn.layers.convolution.ConvolutionLayer.class))
.testForward(true)
.testScore(true)
.testBackward(true)
.testTraining(true)
.features(f)
.labels(l)
.data(new SingletonDataSetIterator(new DataSet(f, l)))
.build();
LayerHelperValidationUtil.validateMLN(netWith, tc);
System.out.println("Starting test: " + name);
LayerHelperValidationUtil.validateMLN(netWith, tc);
}
}
}
}

View File

@ -289,8 +289,14 @@ public class SubsamplingLayer extends AbstractLayer<org.deeplearning4j.nn.conf.l
b = DynamicCustomOp.builder("maxpool2d");
break;
case AVG:
b = DynamicCustomOp.builder("maxpool2d");
extra = 1; //Divide by kH*kW not "number present" to match backward pass -- TODO change this to support both legacy behaviour (deserialized nets) and "exclude" by default for new nets
b = DynamicCustomOp.builder("avgpool2d");
if(layerConf().isAvgPoolIncludePadInDivisor()){
//Mostly this is a legacy case - beta4 and earlier models.
extra = 1; //Divide by "number present" excluding padding
} else {
//Default behaviour
extra = 0; //Divide by kH*kW not "number present"
}
break;
case PNORM:
b = DynamicCustomOp.builder("pnormpool2d");