Skip to content

Commit

Permalink
upsampling 1D layer
Browse files Browse the repository at this point in the history
  • Loading branch information
maxpumperla committed Sep 12, 2017
1 parent faf2c73 commit fd6e39f
Show file tree
Hide file tree
Showing 6 changed files with 298 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package org.deeplearning4j.nn.layers.convolution;

import org.deeplearning4j.datasets.iterator.impl.MnistDataSetIterator;
import org.deeplearning4j.nn.api.Layer;
import org.deeplearning4j.nn.conf.GradientNormalization;
import org.deeplearning4j.nn.conf.NeuralNetConfiguration;
import org.deeplearning4j.nn.conf.layers.Upsampling2D;
import org.deeplearning4j.nn.gradient.Gradient;
import org.junit.Test;
import org.nd4j.linalg.api.ndarray.INDArray;
import org.nd4j.linalg.dataset.DataSet;
import org.nd4j.linalg.dataset.api.iterator.DataSetIterator;
import org.nd4j.linalg.factory.Nd4j;
import org.nd4j.linalg.primitives.Pair;

import java.util.Arrays;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

/**
* @author Max Pumperla
*/
public class Upsampling1DTest {

private int nExamples = 1;
private int depth = 20;
private int nChannelsIn = 1;
private int inputWidth = 28;
private int inputHeight = 28;

private int size = 2;
private int outputWidth = inputWidth * size;
private int outputHeight = inputHeight * size;

private INDArray epsilon = Nd4j.ones(nExamples, depth, outputHeight, outputWidth);


@Test
public void testUpsampling() throws Exception {

double[] outArray = new double[] {1., 1., 2., 2., 1., 1., 2., 2., 3., 3., 4., 4., 3., 3., 4., 4.};
INDArray containedExpectedOut = Nd4j.create(outArray, new int[] {1, 1, 4, 4});
INDArray containedInput = getContainedData();
INDArray input = getData();
Layer layer = getUpsamplingLayer();

INDArray containedOutput = layer.activate(containedInput);
assertTrue(Arrays.equals(containedExpectedOut.shape(), containedOutput.shape()));
assertEquals(containedExpectedOut, containedOutput);

INDArray output = layer.activate(input);
assertTrue(Arrays.equals(new int[] {nExamples, nChannelsIn, outputWidth, outputHeight},
output.shape()));
assertEquals(nChannelsIn, output.size(1), 1e-4);
}


@Test
public void testUpsampling2DBackprop() throws Exception {
INDArray expectedContainedEpsilonInput =
Nd4j.create(new double[] {1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.},
new int[] {1, 1, 4, 4});

INDArray expectedContainedEpsilonResult = Nd4j.create(new double[] {4., 4., 4., 4.},
new int[] {1, 1, 2, 2});

INDArray input = getContainedData();

Layer layer = getUpsamplingLayer();
layer.activate(input);

Pair<Gradient, INDArray> containedOutput = layer.backpropGradient(expectedContainedEpsilonInput);

assertEquals(expectedContainedEpsilonResult, containedOutput.getSecond());
assertEquals(null, containedOutput.getFirst().getGradientFor("W"));
assertEquals(expectedContainedEpsilonResult.shape().length, containedOutput.getSecond().shape().length);

INDArray input2 = getData();
layer.activate(input2);
int depth = input2.size(1);

epsilon = Nd4j.ones(5, depth, outputHeight, outputWidth);

Pair<Gradient, INDArray> out = layer.backpropGradient(epsilon);
assertEquals(input.shape().length, out.getSecond().shape().length);
assertEquals(depth, out.getSecond().size(1));
}


private Layer getUpsamplingLayer() {
NeuralNetConfiguration conf = new NeuralNetConfiguration.Builder()
.gradientNormalization(GradientNormalization.RenormalizeL2PerLayer).seed(123)
.layer(new Upsampling2D.Builder(size).build()).build();
return conf.getLayer().instantiate(conf, null, 0, null, true);
}

public INDArray getData() throws Exception {
DataSetIterator data = new MnistDataSetIterator(5, 5);
DataSet mnist = data.next();
nExamples = mnist.numExamples();
return mnist.getFeatureMatrix().reshape(nExamples, nChannelsIn, inputWidth, inputHeight);
}

private INDArray getContainedData() {
INDArray ret = Nd4j.create
(new double[] {1., 2., 3., 4.},
new int[] {1, 1, 2, 2});
return ret;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,10 @@
import org.deeplearning4j.datasets.iterator.impl.MnistDataSetIterator;
import org.deeplearning4j.nn.api.Layer;
import org.deeplearning4j.nn.conf.GradientNormalization;
import org.deeplearning4j.nn.conf.MultiLayerConfiguration;
import org.deeplearning4j.nn.conf.NeuralNetConfiguration;
import org.deeplearning4j.nn.conf.inputs.InputType;
import org.deeplearning4j.nn.conf.layers.OutputLayer;
import org.deeplearning4j.nn.conf.layers.SubsamplingLayer;
import org.deeplearning4j.nn.conf.layers.Upsampling2D;
import org.deeplearning4j.nn.gradient.Gradient;
import org.deeplearning4j.nn.multilayer.MultiLayerNetwork;
import org.deeplearning4j.nn.weights.WeightInit;
import org.junit.Test;
import org.nd4j.linalg.activations.Activation;
import org.nd4j.linalg.api.ndarray.INDArray;
import org.nd4j.linalg.dataset.DataSet;
import org.nd4j.linalg.dataset.api.iterator.DataSetIterator;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.deeplearning4j.nn.api.ParamInitializer;
import org.deeplearning4j.nn.conf.InputPreProcessor;
import org.deeplearning4j.nn.conf.NeuralNetConfiguration;
import org.deeplearning4j.nn.conf.inputs.InputType;
import org.deeplearning4j.nn.params.ConvolutionParamInitializer;
import org.deeplearning4j.optimize.api.IterationListener;
import org.deeplearning4j.util.ConvolutionUtils;
import org.nd4j.linalg.api.ndarray.INDArray;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*-
*
* * Copyright 2017 Skymind,Inc.
* *
* * Licensed 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.deeplearning4j.nn.conf.layers;

import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.deeplearning4j.nn.api.ParamInitializer;
import org.deeplearning4j.nn.conf.InputPreProcessor;
import org.deeplearning4j.nn.conf.NeuralNetConfiguration;
import org.deeplearning4j.nn.conf.inputs.InputType;
import org.deeplearning4j.nn.conf.memory.LayerMemoryReport;
import org.deeplearning4j.nn.conf.memory.MemoryReport;
import org.deeplearning4j.nn.params.EmptyParamInitializer;
import org.deeplearning4j.optimize.api.IterationListener;
import org.nd4j.linalg.api.ndarray.INDArray;

import java.util.Collection;
import java.util.Map;

/**
* Upsampling 1D layer
*
* @author Max Pumperla
*/

@Data
@NoArgsConstructor
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class Upsampling1D extends Upsampling2D {

protected int size;

protected Upsampling1D(Builder builder) {
super(builder);
this.size = builder.size;
}

@Override
public Upsampling1D clone() {
Upsampling1D clone = (Upsampling1D) super.clone();
return clone;
}

@NoArgsConstructor
public static class Builder extends Upsampling2D.Upsampling2DBuilder {

public Builder(int size) {
super(size);
}

/**
* Upsampling size
*
* @param size upsampling size in height and width dimensions
*/
public Builder size(int size) {

this.size = size;
return this;
}

@Override
@SuppressWarnings("unchecked")
public Upsampling1D build() {
return new Upsampling1D(this);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
import java.util.Map;

/**
* Upsampling layer
* Upsampling 2D layer
*
* @author Max Pumperla
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*-
*
* * Copyright 2015 Skymind,Inc.
* *
* * Licensed 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.deeplearning4j.nn.layers.convolution.upsampling;

import lombok.extern.slf4j.Slf4j;
import org.deeplearning4j.exception.DL4JInvalidInputException;
import org.deeplearning4j.nn.api.Layer;
import org.deeplearning4j.nn.conf.CacheMode;
import org.deeplearning4j.nn.conf.NeuralNetConfiguration;
import org.deeplearning4j.nn.gradient.DefaultGradient;
import org.deeplearning4j.nn.gradient.Gradient;
import org.deeplearning4j.nn.graph.ComputationGraph;
import org.deeplearning4j.nn.layers.AbstractLayer;
import org.deeplearning4j.util.Dropout;
import org.nd4j.linalg.api.memory.MemoryWorkspace;
import org.nd4j.linalg.api.ndarray.INDArray;
import org.nd4j.linalg.api.ops.CustomOp;
import org.nd4j.linalg.api.ops.DynamicCustomOp;
import org.nd4j.linalg.factory.Nd4j;
import org.nd4j.linalg.primitives.Pair;

import java.util.Arrays;


/**
* 1D Upsampling layer.
* <p>
* Used for upsampling a 1D convolution. Currently derived from 2D version.
* For forward and backward pass we add a dummy dimension, apply the 2D version
* and strip the extra dimension again. Eventually, we will want to migrate to a
* proper 1D version without this overhead.
*
* @author Max Pumperla
*/
@Slf4j
public class Upsampling1D extends Upsampling2D {


public Upsampling1D(NeuralNetConfiguration conf) {
super(conf);
}

public Upsampling1D(NeuralNetConfiguration conf, INDArray input) {
super(conf, input);
}


@Override
public Pair<Gradient, INDArray> backpropGradient(INDArray epsilon) {
epsilon = epsilon.reshape(epsilon.size(0), epsilon.size(1), epsilon.size(2), 1);
INDArray originalInput = input;
input = input.reshape(input.size(0), input.size(1), input.size(2), 1);

Pair<Gradient, INDArray> gradientEpsNext = super.backpropGradient(epsilon);
INDArray epsNext = gradientEpsNext.getSecond();
Gradient gradient = gradientEpsNext.getFirst();

epsNext = epsNext.reshape(epsNext.size(0), epsNext.size(1), epsNext.size(2));
input = originalInput;

return new Pair<>(gradient, epsNext);
}

@Override
public INDArray preOutput(boolean training) {
return preOutput(training, false);
}

public INDArray preOutput(boolean training, boolean forBackprop) {
INDArray originalInput = input;
input = input.reshape(input.size(0), input.size(1), input.size(2), 1);

INDArray preOutput = super.preOutput(training, forBackprop);

input = originalInput;
preOutput = preOutput.reshape(preOutput.size(0), preOutput.size(1), preOutput.size(2));

return preOutput;
}


}

0 comments on commit fd6e39f

Please sign in to comment.