Skip to content

Commit

Permalink
Merge pull request deeplearning4j#4041 from deeplearning4j/mp_upsampl…
Browse files Browse the repository at this point in the history
…ing2d_import

Upsampling2d model import + DCGAN import example
  • Loading branch information
maxpumperla authored Sep 11, 2017
2 parents ecfd11e + 700d7e5 commit faf2c73
Show file tree
Hide file tree
Showing 14 changed files with 283 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ protected KerasModel(String modelJson, String modelYaml, Hdf5Archive weightsArch
prepareLayers((List<Object>) layerLists.get((config.getModelFieldLayers())));

/* Import training configuration. */
if (trainingJson != null)
if (trainingJson != null && enforceTrainingConfig)
importTrainingConfiguration(trainingJson);

/* Infer output types for each layer. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ public KerasSequentialModel(String modelJson, String modelYaml, Hdf5Archive weig
}

/* Import training configuration. */
if (trainingJson != null)
if (trainingJson != null && enforceTrainingConfig)
importTrainingConfiguration(trainingJson);

/* Infer output types for each layer. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public class Keras1LayerConfiguration extends KerasLayerConfiguration {
/* Pooling / Upsampling layer properties */
private final String LAYER_FIELD_POOL_1D_SIZE = "pool_length";
private final String LAYER_FIELD_POOL_1D_STRIDES = "stride";
private final String LAYER_FIELD_UPSAMPLING_SIZE = "length";
private final String LAYER_FIELD_UPSAMPLING_1D_SIZE = "length";

/* Keras convolution border modes. */
private final String LAYER_FIELD_BORDER_MODE = "border_mode";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public class Keras2LayerConfiguration extends KerasLayerConfiguration {
/* Pooling / Upsampling layer properties */
private final String LAYER_FIELD_POOL_1D_SIZE = "pool_size";
private final String LAYER_FIELD_POOL_1D_STRIDES = "strides";
private final String LAYER_FIELD_UPSAMPLING_SIZE = "size";
private final String LAYER_FIELD_UPSAMPLING_1D_SIZE = "size";

/* Keras convolution border modes. */
private final String LAYER_FIELD_BORDER_MODE = "padding";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ public class KerasLayerConfiguration {
private final String LAYER_CLASS_NAME_CONVOLUTION_1D = ""; // 1: Convolution1D, 2: Conv1D
private final String LAYER_CLASS_NAME_CONVOLUTION_2D = ""; // 1: Convolution2D, 2: Conv2D
private final String LAYER_CLASS_NAME_LEAKY_RELU = "LeakyReLU";
private final String LAYER_CLASS_NAME_UPSAMPLING_2D = "UpSampling2D";


/* Partially shared layer configurations. */
Expand Down Expand Up @@ -140,7 +141,9 @@ public class KerasLayerConfiguration {
private final String LAYER_FIELD_POOL_STRIDES = "strides";
private final String LAYER_FIELD_POOL_1D_SIZE = ""; // 1: pool_length, 2: pool_size
private final String LAYER_FIELD_POOL_1D_STRIDES = ""; // 1: stride, 2: strides
private final String LAYER_FIELD_UPSAMPLING_SIZE = ""; // 1: length, 2: size
private final String LAYER_FIELD_UPSAMPLING_1D_SIZE = ""; // 1: length, 2: size
private final String LAYER_FIELD_UPSAMPLING_2D_SIZE = "size";


/* Keras convolution border modes. */
private final String LAYER_FIELD_BORDER_MODE = ""; // 1: border_mode, 2: padding
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,6 @@ public KerasLoss(String layerName, String inboundLayerName, String kerasLoss, bo
this.layer = new LossLayer.Builder(loss).name(layerName).build();
}

// private KerasLoss(Map<String, Object> layerConfig) {}
//
// private KerasLoss(Map<String, Object> layerConfig, boolean enforceTrainingConfig) {}

/**
* Get DL4J LossLayer.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,33 @@ public static int[] getDilationRate(Map<String, Object> layerConfig, int dimensi

}

/**
* Get upsampling size from Keras layer configuration.
*
* @param layerConfig dictionary containing Keras layer configuration
* @return
* @throws InvalidKerasConfigurationException
*/
public static int[] getUpsamplingSizeFromConfig(Map<String, Object> layerConfig, int dimension,
KerasLayerConfiguration conf)
throws InvalidKerasConfigurationException {
Map<String, Object> innerConfig = KerasLayerUtils.getInnerLayerConfigFromConfig(layerConfig, conf);
int[] size;
if (innerConfig.containsKey(conf.getLAYER_FIELD_UPSAMPLING_2D_SIZE()) && dimension == 2) {
List<Integer> sizeList = (List<Integer>) innerConfig.get(conf.getLAYER_FIELD_UPSAMPLING_2D_SIZE());
size = ArrayUtil.toArray(sizeList);
} else if (innerConfig.containsKey(conf.getLAYER_FIELD_UPSAMPLING_1D_SIZE()) && dimension == 1) {
int upsamplingSize1D = (int) innerConfig.get(conf.getLAYER_FIELD_UPSAMPLING_1D_SIZE());
size = new int[]{ upsamplingSize1D };
} else {
throw new InvalidKerasConfigurationException("Could not determine kernel size: no "
+ conf.getLAYER_FIELD_UPSAMPLING_1D_SIZE() + ", "
+ conf.getLAYER_FIELD_UPSAMPLING_2D_SIZE());
}
return size;
}



/**
* Get (convolution) kernel size from Keras layer configuration.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*-
*
* * 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.modelimport.keras.layers.convolutional;

import org.deeplearning4j.nn.conf.inputs.InputType;
import org.deeplearning4j.nn.conf.layers.Upsampling2D;
import org.deeplearning4j.nn.modelimport.keras.KerasLayer;
import org.deeplearning4j.nn.modelimport.keras.exceptions.InvalidKerasConfigurationException;
import org.deeplearning4j.nn.modelimport.keras.exceptions.UnsupportedKerasConfigurationException;

import java.util.Map;


/**
* Keras Upsampling2D layer support
*
* @author Max Pumperla
*/
public class KerasUpsampling2D extends KerasLayer {

/**
* Constructor from parsed Keras layer configuration dictionary.
*
* @param layerConfig dictionary containing Keras layer configuration.
* @throws InvalidKerasConfigurationException Invalid Keras configuration exception
* @throws UnsupportedKerasConfigurationException Unsupported Keras configuration exception
*/
public KerasUpsampling2D(Map<String, Object> layerConfig)
throws InvalidKerasConfigurationException, UnsupportedKerasConfigurationException {
this(layerConfig, true);
}

/**
* Constructor from parsed Keras layer configuration dictionary.
*
* @param layerConfig dictionary containing Keras layer configuration
* @param enforceTrainingConfig whether to enforce training-related configuration options
* @throws InvalidKerasConfigurationException Invalid Keras configuration exception
* @throws UnsupportedKerasConfigurationException Invalid Keras configuration exception
*/
public KerasUpsampling2D(Map<String, Object> layerConfig, boolean enforceTrainingConfig)
throws InvalidKerasConfigurationException, UnsupportedKerasConfigurationException {
super(layerConfig, enforceTrainingConfig);

int[] size = KerasConvolutionUtils.getUpsamplingSizeFromConfig(layerConfig, 2, conf);
if (size[0] != size[1])
throw new UnsupportedKerasConfigurationException("First and second size arguments have to be the same" +
"got: " + size[0] + " and " + size[1]);

Upsampling2D.Builder builder = new Upsampling2D.Builder()
.name(this.layerName)
.dropOut(this.dropout)
.size(size[0]);

this.layer = builder.build();
this.vertex = null;
}

/**
* Get DL4J Upsampling2D layer.
*
* @return Upsampling2D layer
*/
public Upsampling2D getUpsampling2DLayer() {
return (Upsampling2D) this.layer;
}

/**
* Get layer output type.
*
* @param inputType Array of InputTypes
* @return output type as InputType
* @throws InvalidKerasConfigurationException
*/
@Override
public InputType getOutputType(InputType... inputType) throws InvalidKerasConfigurationException {
if (inputType.length > 1)
throw new InvalidKerasConfigurationException(
"Keras Subsampling layer accepts only one input (received " + inputType.length + ")");
return this.getUpsampling2DLayer().getOutputType(-1, inputType[0]);
}

}
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
/*-
*
* * 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.modelimport.keras.layers.pooling;

import lombok.Data;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
/*-
*
* * 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.modelimport.keras.layers.pooling;

import lombok.extern.slf4j.Slf4j;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
/*-
*
* * 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.modelimport.keras.layers.pooling;

import lombok.extern.slf4j.Slf4j;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,8 @@ public static KerasLayer getKerasLayerFromConfig(Map<String, Object> layerConfig
layer = new KerasReshape(layerConfig, enforceTrainingConfig);
} else if (layerClassName.equals(conf.getLAYER_CLASS_NAME_ZERO_PADDING_2D())) {
layer = new KerasZeroPadding2D(layerConfig, enforceTrainingConfig);
} else if (layerClassName.equals(conf.getLAYER_CLASS_NAME_UPSAMPLING_2D())) {
layer = new KerasUpsampling2D(layerConfig, enforceTrainingConfig);
} else {
// check if user registered a custom config
Class<? extends KerasLayer> customConfig = customLayers.get(layerClassName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,30 @@ public void importCnnNoBiasTfKeras2() throws Exception {
importEndModelTest(modelPath, inputsOutputPath, true, false);
}

/**
* DCGAN import test
*/
@Test
public void importDcganDiscriminator() throws Exception {
importModelH5Test("modelimport/keras/examples/mnist_dcgan/dcgan_discriminator_epoch_50.h5");
}
@Test
public void importDcganGenerator() throws Exception {
importModelH5Test("modelimport/keras/examples/mnist_dcgan/dcgan_generator_epoch_50.h5");
}


void importModelH5Test(String modelPath) throws Exception {
ClassPathResource modelResource =
new ClassPathResource(modelPath,
KerasModelEndToEndTest.class.getClassLoader());
File modelFile = File.createTempFile(TEMP_MODEL_FILENAME, H5_EXTENSION);
Files.copy(modelResource.getInputStream(), modelFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
MultiLayerNetwork model = new KerasModel().modelBuilder().modelHdf5Filename(modelFile.getAbsolutePath())
.enforceTrainingConfig(false).buildSequential().getMultiLayerNetwork();
}


void importEndModelTest(String modelPath, String inputsOutputsPath, boolean tfOrdering, boolean checkPredictions) throws Exception {
ClassPathResource modelResource =
new ClassPathResource(modelPath,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*-
*
* * 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.modelimport.keras.layers.convolution;

import org.deeplearning4j.nn.conf.layers.Upsampling2D;
import org.deeplearning4j.nn.conf.layers.ZeroPadding1DLayer;
import org.deeplearning4j.nn.modelimport.keras.config.Keras1LayerConfiguration;
import org.deeplearning4j.nn.modelimport.keras.config.Keras2LayerConfiguration;
import org.deeplearning4j.nn.modelimport.keras.config.KerasLayerConfiguration;
import org.deeplearning4j.nn.modelimport.keras.layers.convolutional.KerasUpsampling2D;
import org.deeplearning4j.nn.modelimport.keras.layers.convolutional.KerasZeroPadding1D;
import org.junit.Test;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.junit.Assert.assertEquals;

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

private final String LAYER_NAME = "upsampling_2D_layer";
private int[] size = new int[] {2, 2};

private Integer keras1 = 1;
private Integer keras2 = 2;
private Keras1LayerConfiguration conf1 = new Keras1LayerConfiguration();
private Keras2LayerConfiguration conf2 = new Keras2LayerConfiguration();

@Test
public void testUpsampling2DLayer() throws Exception {
buildUpsampling2DLayer(conf1, keras1);
buildUpsampling2DLayer(conf2, keras2);
}


public void buildUpsampling2DLayer(KerasLayerConfiguration conf, Integer kerasVersion) throws Exception {
Map<String, Object> layerConfig = new HashMap<>();
layerConfig.put(conf.getLAYER_FIELD_CLASS_NAME(), conf.getLAYER_CLASS_NAME_MAX_POOLING_1D());
Map<String, Object> config = new HashMap<>();
List<Integer> sizeList = new ArrayList<>();
sizeList.add(size[0]);
sizeList.add(size[1]);
config.put(conf.getLAYER_FIELD_UPSAMPLING_2D_SIZE(), sizeList);
config.put(conf.getLAYER_FIELD_NAME(), LAYER_NAME);
layerConfig.put(conf.getLAYER_FIELD_CONFIG(), config);
layerConfig.put(conf.getLAYER_FIELD_KERAS_VERSION(), kerasVersion);

Upsampling2D layer = new KerasUpsampling2D(layerConfig).getUpsampling2DLayer();
assertEquals(LAYER_NAME, layer.getLayerName());
assertEquals(size[0], layer.getSize());
}

}

0 comments on commit faf2c73

Please sign in to comment.