chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 12:47:05 +08:00
commit 4f3b7da785
7394 changed files with 2005594 additions and 0 deletions
@@ -0,0 +1,43 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * 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.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.zoo;
import org.deeplearning4j.nn.api.Model;
public interface InstantiableModel {
void setInputShape(int[][] inputShape);
<M extends Model> M init();
/**
* @deprecated No longer used, will be removed in a future release
*/
@Deprecated ModelMetaData metaData();
Class<? extends Model> modelType();
String pretrainedUrl(PretrainedType pretrainedType);
long pretrainedChecksum(PretrainedType pretrainedType);
String modelName();
}
@@ -0,0 +1,42 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * 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.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.zoo;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
@Deprecated
public class ModelMetaData {
private int[][] inputShape;
private int numOutputs;
private ZooType zooType;
/**
* If number of inputs are greater than 1, this states that the
* implementation should use MultiDataSet.
* @return
*/
public boolean useMDS() {
return inputShape.length > 1 ? true : false;
}
}
@@ -0,0 +1,25 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * 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.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.zoo;
public enum PretrainedType {
IMAGENET, IMAGENETLARGE, MNIST, CIFAR10, VGGFACE, SEGMENT
}
@@ -0,0 +1,111 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * 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.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.zoo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.deeplearning4j.common.resources.DL4JResources;
import org.deeplearning4j.common.resources.ResourceType;
import org.deeplearning4j.nn.api.Model;
import org.deeplearning4j.nn.graph.ComputationGraph;
import org.deeplearning4j.nn.multilayer.MultiLayerNetwork;
import org.deeplearning4j.util.ModelSerializer;
import org.eclipse.deeplearning4j.resources.DownloadResources;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.zip.Adler32;
import java.util.zip.Checksum;
@Slf4j
public abstract class ZooModel<T> implements InstantiableModel {
public boolean pretrainedAvailable(PretrainedType pretrainedType) {
return pretrainedUrl(pretrainedType) != null;
}
/**
* By default, will return a pretrained ImageNet if available.
*
* @return
* @throws IOException
*/
public Model initPretrained() throws IOException {
return initPretrained(PretrainedType.IMAGENET);
}
/**
* Returns a pretrained model for the given dataset, if available.
*
* @param pretrainedType
* @return
* @throws IOException
*/
public <M extends Model> M initPretrained(PretrainedType pretrainedType) throws IOException {
String remoteUrl = pretrainedUrl(pretrainedType);
if (remoteUrl == null)
throw new UnsupportedOperationException(
"Pretrained " + pretrainedType + " weights are not available for this model.");
String localFilename = new File(remoteUrl).getName();
File rootCacheDir = DL4JResources.getDirectory(ResourceType.ZOO_MODEL, modelName());
File cachedFile = new File(rootCacheDir, localFilename);
if (!cachedFile.exists()) {
log.info("Downloading model to " + cachedFile.toString());
FileUtils.copyURLToFile(new URL(remoteUrl), cachedFile,Integer.MAX_VALUE,Integer.MAX_VALUE);
} else {
log.info("Using cached model at " + cachedFile.toString());
}
long expectedChecksum = pretrainedChecksum(pretrainedType);
if (expectedChecksum != 0L) {
log.info("Verifying download...");
Checksum adler = new Adler32();
FileUtils.checksum(cachedFile, adler);
long localChecksum = adler.getValue();
log.info("Checksum local is " + localChecksum + ", expecting " + expectedChecksum);
if (expectedChecksum != localChecksum) {
log.error("Checksums do not match. Cleaning up files and failing...");
cachedFile.delete();
throw new IllegalStateException(
"Pretrained model file failed checksum. If this error persists, please open an issue at https://github.com/eclipse/deeplearning4j.");
}
}
if (modelType() == MultiLayerNetwork.class) {
return (M) ModelSerializer.restoreMultiLayerNetwork(cachedFile);
} else if (modelType() == ComputationGraph.class) {
return (M) ModelSerializer.restoreComputationGraph(cachedFile);
} else {
throw new UnsupportedOperationException(
"Pretrained models are only supported for MultiLayerNetwork and ComputationGraph.");
}
}
@Override
public String modelName() {
return getClass().getSimpleName().toLowerCase();
}
}
@@ -0,0 +1,25 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * 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.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.zoo;
public enum ZooType {
CNN, RNN, TEXTGENLSTM
}
@@ -0,0 +1,186 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * 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.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.zoo.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import org.deeplearning4j.nn.api.Model;
import org.deeplearning4j.nn.api.OptimizationAlgorithm;
import org.deeplearning4j.nn.conf.*;
import org.deeplearning4j.nn.conf.distribution.NormalDistribution;
import org.deeplearning4j.nn.conf.inputs.InputType;
import org.deeplearning4j.nn.conf.layers.*;
import org.deeplearning4j.nn.multilayer.MultiLayerNetwork;
import org.deeplearning4j.zoo.ModelMetaData;
import org.deeplearning4j.zoo.PretrainedType;
import org.deeplearning4j.zoo.ZooModel;
import org.deeplearning4j.zoo.ZooType;
import org.nd4j.linalg.activations.Activation;
import org.nd4j.linalg.learning.config.IUpdater;
import org.nd4j.linalg.learning.config.Nesterovs;
import org.nd4j.linalg.lossfunctions.LossFunctions;
@AllArgsConstructor
@Builder
public class AlexNet extends ZooModel {
@Builder.Default private long seed = 1234;
@Builder.Default private int[] inputShape = new int[] {3, 224, 224};
@Builder.Default private int numClasses = 0;
@Builder.Default private IUpdater updater = new Nesterovs(1e-2, 0.9);
@Builder.Default private CacheMode cacheMode = CacheMode.NONE;
@Builder.Default private WorkspaceMode workspaceMode = WorkspaceMode.ENABLED;
@Builder.Default private ConvolutionLayer.AlgoMode cudnnAlgoMode = ConvolutionLayer.AlgoMode.PREFER_FASTEST;
private AlexNet() {}
@Override
public String pretrainedUrl(PretrainedType pretrainedType) {
return null;
}
@Override
public long pretrainedChecksum(PretrainedType pretrainedType) {
return 0L;
}
@Override
public Class<? extends Model> modelType() {
return MultiLayerNetwork.class;
}
public MultiLayerConfiguration conf() {
double nonZeroBias = 1;
MultiLayerConfiguration conf = new NeuralNetConfiguration.Builder().seed(seed)
.weightInit(new NormalDistribution(0.0, 0.01))
.activation(Activation.RELU)
.optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT)
.updater(updater)
.biasUpdater(new Nesterovs(2e-2, 0.9))
.convolutionMode(ConvolutionMode.Same)
.gradientNormalization(GradientNormalization.RenormalizeL2PerLayer) // normalize to prevent vanishing or exploding gradients
.trainingWorkspaceMode(workspaceMode)
.inferenceWorkspaceMode(workspaceMode)
.cacheMode(cacheMode)
.l2(5 * 1e-4)
.miniBatch(false)
.list()
.layer(0, new ConvolutionLayer.Builder(new int[]{11,11}, new int[]{4, 4})
.name("cnn1")
.cudnnAlgoMode(ConvolutionLayer.AlgoMode.PREFER_FASTEST)
.convolutionMode(ConvolutionMode.Truncate)
.nIn(inputShape[0])
.nOut(96)
.build())
.layer(1, new LocalResponseNormalization.Builder().build())
.layer(2, new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.MAX)
.kernelSize(3,3)
.stride(2,2)
.padding(1,1)
.name("maxpool1")
.build())
.layer(3, new ConvolutionLayer.Builder(new int[]{5,5}, new int[]{1,1}, new int[]{2,2})
.name("cnn2")
.cudnnAlgoMode(ConvolutionLayer.AlgoMode.PREFER_FASTEST)
.convolutionMode(ConvolutionMode.Truncate)
.nOut(256)
.biasInit(nonZeroBias)
.build())
.layer(4, new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.MAX, new int[]{3, 3}, new int[]{2, 2})
.convolutionMode(ConvolutionMode.Truncate)
.name("maxpool2")
.build())
.layer(5, new LocalResponseNormalization.Builder().build())
.layer(6, new ConvolutionLayer.Builder()
.kernelSize(3,3)
.stride(1,1)
.convolutionMode(ConvolutionMode.Same)
.name("cnn3")
.cudnnAlgoMode(ConvolutionLayer.AlgoMode.PREFER_FASTEST)
.nOut(384)
.build())
.layer(7, new ConvolutionLayer.Builder(new int[]{3,3}, new int[]{1,1})
.name("cnn4")
.cudnnAlgoMode(ConvolutionLayer.AlgoMode.PREFER_FASTEST)
.nOut(384)
.biasInit(nonZeroBias)
.build())
.layer(8, new ConvolutionLayer.Builder(new int[]{3,3}, new int[]{1,1})
.name("cnn5")
.cudnnAlgoMode(ConvolutionLayer.AlgoMode.PREFER_FASTEST)
.nOut(256)
.biasInit(nonZeroBias)
.build())
.layer(9, new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.MAX, new int[]{3,3}, new int[]{2,2})
.name("maxpool3")
.convolutionMode(ConvolutionMode.Truncate)
.build())
.layer(10, new DenseLayer.Builder()
.name("ffn1")
.nIn(256*6*6)
.nOut(4096)
.weightInit(new NormalDistribution(0, 0.005))
.biasInit(nonZeroBias)
.build())
.layer(11, new DenseLayer.Builder()
.name("ffn2")
.nOut(4096)
.weightInit(new NormalDistribution(0, 0.005))
.biasInit(nonZeroBias)
.dropOut(0.5)
.build())
.layer(12, new OutputLayer.Builder(LossFunctions.LossFunction.NEGATIVELOGLIKELIHOOD)
.name("output")
.nOut(numClasses)
.activation(Activation.SOFTMAX)
.weightInit(new NormalDistribution(0, 0.005))
.biasInit(0.1)
.build())
.setInputType(InputType.convolutional(inputShape[2], inputShape[1], inputShape[0]))
.build();
return conf;
}
@Override
public MultiLayerNetwork init() {
MultiLayerConfiguration conf = conf();
MultiLayerNetwork network = new MultiLayerNetwork(conf);
network.init();
return network;
}
@Override
public ModelMetaData metaData() {
return new ModelMetaData(new int[][] {inputShape}, 1, ZooType.CNN);
}
@Override
public void setInputShape(int[][] inputShape) {
this.inputShape = inputShape[0];
}
}
@@ -0,0 +1,167 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * 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.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.zoo.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import org.deeplearning4j.common.resources.DL4JResources;
import org.deeplearning4j.nn.api.Model;
import org.deeplearning4j.nn.conf.*;
import org.deeplearning4j.nn.conf.ComputationGraphConfiguration.GraphBuilder;
import org.deeplearning4j.nn.conf.inputs.InputType;
import org.deeplearning4j.nn.conf.layers.*;
import org.deeplearning4j.nn.graph.ComputationGraph;
import org.deeplearning4j.nn.weights.WeightInit;
import org.deeplearning4j.zoo.ModelMetaData;
import org.deeplearning4j.zoo.PretrainedType;
import org.deeplearning4j.zoo.ZooModel;
import org.deeplearning4j.zoo.ZooType;
import org.nd4j.linalg.activations.Activation;
import org.nd4j.linalg.learning.config.IUpdater;
import org.nd4j.linalg.learning.config.Nesterovs;
import org.nd4j.linalg.lossfunctions.LossFunctions;
import static org.deeplearning4j.zoo.model.helper.DarknetHelper.addLayers;
@AllArgsConstructor
@Builder
public class Darknet19 extends ZooModel {
@Builder.Default private long seed = 1234;
@Builder.Default private int[] inputShape = {3, 224, 224};
@Builder.Default private int numClasses = 0;
@Builder.Default private WeightInit weightInit = WeightInit.RELU;
@Builder.Default private IUpdater updater = new Nesterovs(1e-3, 0.9);
@Builder.Default private CacheMode cacheMode = CacheMode.NONE;
@Builder.Default private WorkspaceMode workspaceMode = WorkspaceMode.ENABLED;
@Builder.Default private ConvolutionLayer.AlgoMode cudnnAlgoMode = ConvolutionLayer.AlgoMode.PREFER_FASTEST;
private Darknet19() {}
@Override
public String pretrainedUrl(PretrainedType pretrainedType) {
if (pretrainedType == PretrainedType.IMAGENET)
if (inputShape[1] == 448 && inputShape[2] == 448)
return DL4JResources.getURLString("models/darknet19_448_dl4j_inference.v2.zip");
else
return DL4JResources.getURLString("models/darknet19_dl4j_inference.v2.zip");
else
return null;
}
@Override
public long pretrainedChecksum(PretrainedType pretrainedType) {
if (pretrainedType == PretrainedType.IMAGENET)
if (inputShape[1] == 448 && inputShape[2] == 448)
return 1054319943L;
else
return 691100891L;
else
return 0L;
}
@Override
public Class<? extends Model> modelType() {
return ComputationGraph.class;
}
public ComputationGraphConfiguration conf() {
GraphBuilder graphBuilder = new NeuralNetConfiguration.Builder()
.seed(seed)
.updater(updater)
.weightInit(weightInit)
.l2(0.00001)
.activation(Activation.IDENTITY)
.cacheMode(cacheMode)
.trainingWorkspaceMode(workspaceMode)
.inferenceWorkspaceMode(workspaceMode)
.cudnnAlgoMode(cudnnAlgoMode)
.graphBuilder()
.addInputs("input")
.setInputTypes(InputType.convolutional(inputShape[2], inputShape[1], inputShape[0]));
addLayers(graphBuilder, 1, 3, inputShape[0], 32, 2);
addLayers(graphBuilder, 2, 3, 32, 64, 2);
addLayers(graphBuilder, 3, 3, 64, 128, 0);
addLayers(graphBuilder, 4, 1, 128, 64, 0);
addLayers(graphBuilder, 5, 3, 64, 128, 2);
addLayers(graphBuilder, 6, 3, 128, 256, 0);
addLayers(graphBuilder, 7, 1, 256, 128, 0);
addLayers(graphBuilder, 8, 3, 128, 256, 2);
addLayers(graphBuilder, 9, 3, 256, 512, 0);
addLayers(graphBuilder, 10, 1, 512, 256, 0);
addLayers(graphBuilder, 11, 3, 256, 512, 0);
addLayers(graphBuilder, 12, 1, 512, 256, 0);
addLayers(graphBuilder, 13, 3, 256, 512, 2);
addLayers(graphBuilder, 14, 3, 512, 1024, 0);
addLayers(graphBuilder, 15, 1, 1024, 512, 0);
addLayers(graphBuilder, 16, 3, 512, 1024, 0);
addLayers(graphBuilder, 17, 1, 1024, 512, 0);
addLayers(graphBuilder, 18, 3, 512, 1024, 0);
int layerNumber = 19;
graphBuilder
.addLayer("convolution2d_" + layerNumber,
new ConvolutionLayer.Builder(1,1)
.nIn(1024)
.nOut(numClasses)
.weightInit(WeightInit.XAVIER)
.stride(1,1)
.convolutionMode(ConvolutionMode.Same)
.weightInit(WeightInit.RELU)
.activation(Activation.IDENTITY)
.build(),
"activation_" + (layerNumber - 1))
.addLayer("globalpooling", new GlobalPoolingLayer.Builder(PoolingType.AVG)
.build(), "convolution2d_" + layerNumber)
.addLayer("softmax", new ActivationLayer.Builder()
.activation(Activation.SOFTMAX)
.build(), "globalpooling")
.addLayer("loss", new LossLayer.Builder(LossFunctions.LossFunction.NEGATIVELOGLIKELIHOOD)
.build(), "softmax")
.setOutputs("loss");
return graphBuilder.build();
}
@Override
public ComputationGraph init() {
ComputationGraph model = new ComputationGraph(conf());
model.init();
return model;
}
@Override
public ModelMetaData metaData() {
return new ModelMetaData(new int[][] {inputShape}, 1, ZooType.CNN);
}
@Override
public void setInputShape(int[][] inputShape) {
this.inputShape = inputShape[0];
}
}
@@ -0,0 +1,368 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * 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.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.zoo.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import org.deeplearning4j.nn.api.Model;
import org.deeplearning4j.nn.api.OptimizationAlgorithm;
import org.deeplearning4j.nn.conf.*;
import org.deeplearning4j.nn.conf.graph.L2NormalizeVertex;
import org.deeplearning4j.nn.conf.graph.MergeVertex;
import org.deeplearning4j.nn.conf.inputs.InputType;
import org.deeplearning4j.nn.conf.layers.*;
import org.deeplearning4j.nn.graph.ComputationGraph;
import org.deeplearning4j.nn.weights.WeightInit;
import org.deeplearning4j.zoo.ModelMetaData;
import org.deeplearning4j.zoo.PretrainedType;
import org.deeplearning4j.zoo.ZooModel;
import org.deeplearning4j.zoo.ZooType;
import org.deeplearning4j.zoo.model.helper.FaceNetHelper;
import org.nd4j.linalg.activations.Activation;
import org.nd4j.linalg.learning.config.Adam;
import org.nd4j.linalg.learning.config.IUpdater;
import org.nd4j.linalg.lossfunctions.LossFunctions;
@AllArgsConstructor
@Builder
public class FaceNetNN4Small2 extends ZooModel {
@Builder.Default private long seed = 1234;
@Builder.Default private int[] inputShape = new int[] {3, 96, 96};
@Builder.Default private int numClasses = 0;
@Builder.Default private IUpdater updater = new Adam(0.1, 0.9, 0.999, 0.01);
@Builder.Default private Activation transferFunction = Activation.RELU;
@Builder.Default CacheMode cacheMode = CacheMode.NONE;
@Builder.Default private WorkspaceMode workspaceMode = WorkspaceMode.ENABLED;
@Builder.Default private ConvolutionLayer.AlgoMode cudnnAlgoMode = ConvolutionLayer.AlgoMode.PREFER_FASTEST;
@Builder.Default private int embeddingSize = 128;
private FaceNetNN4Small2() {}
@Override
public String pretrainedUrl(PretrainedType pretrainedType) {
return null;
}
@Override
public long pretrainedChecksum(PretrainedType pretrainedType) {
return 0L;
}
@Override
public Class<? extends Model> modelType() {
return ComputationGraph.class;
}
public ComputationGraphConfiguration conf() {
ComputationGraphConfiguration.GraphBuilder graph = new NeuralNetConfiguration.Builder().seed(seed)
.activation(Activation.IDENTITY)
.optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT)
.updater(updater)
.weightInit(WeightInit.RELU)
.l2(5e-5)
.miniBatch(true)
.cacheMode(cacheMode)
.trainingWorkspaceMode(workspaceMode)
.inferenceWorkspaceMode(workspaceMode)
.cudnnAlgoMode(cudnnAlgoMode)
.convolutionMode(ConvolutionMode.Same)
.graphBuilder();
graph.addInputs("input1")
.addLayer("stem-cnn1",
new ConvolutionLayer.Builder(new int[] {7, 7}, new int[] {2, 2},
new int[] {3, 3}).nIn(inputShape[0]).nOut(64)
.cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE)
.build(),
"input1")
.addLayer("stem-batch1", new BatchNormalization.Builder(false).nIn(64).nOut(64).build(),
"stem-cnn1")
.addLayer("stem-activation1", new ActivationLayer.Builder().activation(Activation.RELU).build(),
"stem-batch1")
// pool -> norm
.addLayer("stem-pool1",
new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.MAX, new int[] {3, 3},
new int[] {2, 2}, new int[] {1, 1}).build(),
"stem-activation1")
.addLayer("stem-lrn1", new LocalResponseNormalization.Builder(1, 5, 1e-4, 0.75).build(),
"stem-pool1")
// Inception 2
.addLayer("inception-2-cnn1",
new ConvolutionLayer.Builder(new int[] {1, 1}).nIn(64).nOut(64)
.cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE).build(),
"stem-lrn1")
.addLayer("inception-2-batch1", new BatchNormalization.Builder(false).nIn(64).nOut(64).build(),
"inception-2-cnn1")
.addLayer("inception-2-activation1",
new ActivationLayer.Builder().activation(Activation.RELU).build(),
"inception-2-batch1")
.addLayer("inception-2-cnn2",
new ConvolutionLayer.Builder(new int[] {3, 3}, new int[] {1, 1},
new int[] {1, 1}).nIn(64).nOut(192)
.cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE)
.build(),
"inception-2-activation1")
.addLayer("inception-2-batch2",
new BatchNormalization.Builder(false).nIn(192).nOut(192).build(),
"inception-2-cnn2")
.addLayer("inception-2-activation2",
new ActivationLayer.Builder().activation(Activation.RELU).build(),
"inception-2-batch2")
// norm -> pool
.addLayer("inception-2-lrn1", new LocalResponseNormalization.Builder(1, 5, 1e-4, 0.75).build(),
"inception-2-activation2")
.addLayer("inception-2-pool1",
new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.MAX, new int[] {3, 3},
new int[] {2, 2}, new int[] {1, 1}).build(),
"inception-2-lrn1");
// Inception 3a
FaceNetHelper.appendGraph(graph, "3a", 192, new int[] {3, 5}, new int[] {1, 1}, new int[] {128, 32},
new int[] {96, 16, 32, 64}, SubsamplingLayer.PoolingType.MAX, transferFunction,
"inception-2-pool1");
// Inception 3b
FaceNetHelper.appendGraph(graph, "3b", 256, new int[] {3, 5}, new int[] {1, 1}, new int[] {128, 64},
new int[] {96, 32, 64, 64}, SubsamplingLayer.PoolingType.PNORM, 2, transferFunction,
"inception-3a");
// Inception 3c
// Inception.appendGraph(graph, "3c", 320,
// new int[]{3,5}, new int[]{1,1}, new int[]{256,64}, new int[]{128,64},
// SubsamplingLayer.PoolingType.PNORM, 2, true, "inception-3b");
graph.addLayer("3c-1x1",
new ConvolutionLayer.Builder(new int[] {1, 1}, new int[] {1, 1}).nIn(320).nOut(128)
.cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE).build(),
"inception-3b")
.addLayer("3c-1x1-norm", FaceNetHelper.batchNorm(128, 128), "3c-1x1")
.addLayer("3c-transfer1", new ActivationLayer.Builder().activation(transferFunction).build(),
"3c-1x1-norm")
.addLayer("3c-3x3",
new ConvolutionLayer.Builder(new int[] {3, 3}, new int[] {2, 2}).nIn(128)
.nOut(256).cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE)
.build(),
"3c-transfer1")
.addLayer("3c-3x3-norm", FaceNetHelper.batchNorm(256, 256), "3c-3x3")
.addLayer("3c-transfer2", new ActivationLayer.Builder().activation(transferFunction).build(),
"3c-3x3-norm")
.addLayer("3c-2-1x1",
new ConvolutionLayer.Builder(new int[] {1, 1}, new int[] {1, 1}).nIn(320)
.nOut(32).cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE)
.build(),
"inception-3b")
.addLayer("3c-2-1x1-norm", FaceNetHelper.batchNorm(32, 32), "3c-2-1x1")
.addLayer("3c-2-transfer3", new ActivationLayer.Builder().activation(transferFunction).build(),
"3c-2-1x1-norm")
.addLayer("3c-2-5x5",
new ConvolutionLayer.Builder(new int[] {3, 3}, new int[] {2, 2}).nIn(32)
.nOut(64).cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE)
.build(),
"3c-2-transfer3")
.addLayer("3c-2-5x5-norm", FaceNetHelper.batchNorm(64, 64), "3c-2-5x5")
.addLayer("3c-2-transfer4", new ActivationLayer.Builder().activation(transferFunction).build(),
"3c-2-5x5-norm")
.addLayer("3c-pool", new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.MAX,
new int[] {3, 3}, new int[] {2, 2}, new int[] {1, 1}).build(), "inception-3b")
.addVertex("inception-3c", new MergeVertex(), "3c-transfer2", "3c-2-transfer4", "3c-pool");
// Inception 4a
FaceNetHelper.appendGraph(graph, "4a", 640, new int[] {3, 5}, new int[] {1, 1}, new int[] {192, 64},
new int[] {96, 32, 128, 256}, SubsamplingLayer.PoolingType.PNORM, 2, transferFunction,
"inception-3c");
// // Inception 4e
// Inception.appendGraph(graph, "4e", 640,
// new int[]{3,5}, new int[]{2,2}, new int[]{256,128}, new int[]{160,64},
// SubsamplingLayer.PoolingType.MAX, 2, 1, true, "inception-4a");
graph.addLayer("4e-1x1",
new ConvolutionLayer.Builder(new int[] {1, 1}, new int[] {1, 1}).nIn(640).nOut(160)
.cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE).build(),
"inception-4a")
.addLayer("4e-1x1-norm", FaceNetHelper.batchNorm(160, 160), "4e-1x1")
.addLayer("4e-transfer1", new ActivationLayer.Builder().activation(transferFunction).build(),
"4e-1x1-norm")
.addLayer("4e-3x3",
new ConvolutionLayer.Builder(new int[] {3, 3}, new int[] {2, 2}).nIn(160)
.nOut(256).cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE)
.build(),
"4e-transfer1")
.addLayer("4e-3x3-norm", FaceNetHelper.batchNorm(256, 256), "4e-3x3")
.addLayer("4e-transfer2", new ActivationLayer.Builder().activation(transferFunction).build(),
"4e-3x3-norm")
.addLayer("4e-2-1x1",
new ConvolutionLayer.Builder(new int[] {1, 1}, new int[] {1, 1}).nIn(640)
.nOut(64).cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE)
.build(),
"inception-4a")
.addLayer("4e-2-1x1-norm", FaceNetHelper.batchNorm(64, 64), "4e-2-1x1")
.addLayer("4e-2-transfer3", new ActivationLayer.Builder().activation(transferFunction).build(),
"4e-2-1x1-norm")
.addLayer("4e-2-5x5",
new ConvolutionLayer.Builder(new int[] {3, 3}, new int[] {2, 2}).nIn(64)
.nOut(128).cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE)
.build(),
"4e-2-transfer3")
.addLayer("4e-2-5x5-norm", FaceNetHelper.batchNorm(128, 128), "4e-2-5x5")
.addLayer("4e-2-transfer4", new ActivationLayer.Builder().activation(transferFunction).build(),
"4e-2-5x5-norm")
.addLayer("4e-pool", new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.MAX,
new int[] {3, 3}, new int[] {2, 2}, new int[] {1, 1}).build(), "inception-4a")
.addVertex("inception-4e", new MergeVertex(), "4e-transfer2", "4e-2-transfer4", "4e-pool");
// Inception 5a
// Inception.appendGraph(graph, "5a", 1024,
// new int[]{3}, new int[]{1}, new int[]{384}, new int[]{96,96,256},
// SubsamplingLayer.PoolingType.PNORM, 2, true, "inception-4e");
graph.addLayer("5a-1x1",
new ConvolutionLayer.Builder(new int[] {1, 1}, new int[] {1, 1}).nIn(1024).nOut(256)
.cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE).build(),
"inception-4e").addLayer("5a-1x1-norm", FaceNetHelper.batchNorm(256, 256), "5a-1x1")
.addLayer("5a-transfer1", new ActivationLayer.Builder().activation(transferFunction).build(),
"5a-1x1-norm")
.addLayer("5a-2-1x1",
new ConvolutionLayer.Builder(new int[] {1, 1}, new int[] {1, 1}).nIn(1024)
.nOut(96).cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE)
.build(),
"inception-4e")
.addLayer("5a-2-1x1-norm", FaceNetHelper.batchNorm(96, 96), "5a-2-1x1")
.addLayer("5a-2-transfer2", new ActivationLayer.Builder().activation(transferFunction).build(),
"5a-2-1x1-norm")
.addLayer("5a-2-3x3",
new ConvolutionLayer.Builder(new int[] {3, 3}, new int[] {1, 1}).nIn(96)
.nOut(384).cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE)
.build(),
"5a-2-transfer2")
.addLayer("5a-2-3x3-norm", FaceNetHelper.batchNorm(384, 384), "5a-2-3x3")
.addLayer("5a-transfer3", new ActivationLayer.Builder().activation(transferFunction).build(),
"5a-2-3x3-norm")
.addLayer("5a-3-pool",
new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.PNORM,
new int[] {3, 3}, new int[] {1, 1}).pnorm(2).build(),
"inception-4e")
.addLayer("5a-3-1x1reduce",
new ConvolutionLayer.Builder(new int[] {1, 1}, new int[] {1, 1}).nIn(1024)
.nOut(96).cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE)
.build(),
"5a-3-pool")
.addLayer("5a-3-1x1reduce-norm", FaceNetHelper.batchNorm(96, 96), "5a-3-1x1reduce")
.addLayer("5a-3-transfer4", new ActivationLayer.Builder().activation(Activation.RELU).build(),
"5a-3-1x1reduce-norm")
.addVertex("inception-5a", new MergeVertex(), "5a-transfer1", "5a-transfer3", "5a-3-transfer4");
// Inception 5b
// Inception.appendGraph(graph, "5b", 736,
// new int[]{3}, new int[]{1}, new int[]{384}, new int[]{96,96,256},
// SubsamplingLayer.PoolingType.MAX, 1, 1, true, "inception-5a");
graph.addLayer("5b-1x1",
new ConvolutionLayer.Builder(new int[] {1, 1}, new int[] {1, 1}).nIn(736).nOut(256)
.cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE).build(),
"inception-5a").addLayer("5b-1x1-norm", FaceNetHelper.batchNorm(256, 256), "5b-1x1")
.addLayer("5b-transfer1", new ActivationLayer.Builder().activation(transferFunction).build(),
"5b-1x1-norm")
.addLayer("5b-2-1x1",
new ConvolutionLayer.Builder(new int[] {1, 1}, new int[] {1, 1}).nIn(736)
.nOut(96).cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE)
.build(),
"inception-5a")
.addLayer("5b-2-1x1-norm", FaceNetHelper.batchNorm(96, 96), "5b-2-1x1")
.addLayer("5b-2-transfer2", new ActivationLayer.Builder().activation(transferFunction).build(),
"5b-2-1x1-norm")
.addLayer("5b-2-3x3",
new ConvolutionLayer.Builder(new int[] {3, 3}, new int[] {1, 1}).nIn(96)
.nOut(384).cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE)
.build(),
"5b-2-transfer2")
.addLayer("5b-2-3x3-norm", FaceNetHelper.batchNorm(384, 384), "5b-2-3x3")
.addLayer("5b-2-transfer3", new ActivationLayer.Builder().activation(transferFunction).build(),
"5b-2-3x3-norm")
.addLayer("5b-3-pool",
new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.MAX, new int[] {3, 3},
new int[] {1, 1}, new int[] {1, 1}).build(),
"inception-5a")
.addLayer("5b-3-1x1reduce",
new ConvolutionLayer.Builder(new int[] {1, 1}, new int[] {1, 1}).nIn(736)
.nOut(96).cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE)
.build(),
"5b-3-pool")
.addLayer("5b-3-1x1reduce-norm", FaceNetHelper.batchNorm(96, 96), "5b-3-1x1reduce")
.addLayer("5b-3-transfer4", new ActivationLayer.Builder().activation(transferFunction).build(),
"5b-3-1x1reduce-norm")
.addVertex("inception-5b", new MergeVertex(), "5b-transfer1", "5b-2-transfer3",
"5b-3-transfer4");
graph.addLayer("avgpool",
new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.AVG, new int[] {3, 3},
new int[] {3, 3}).build(),
"inception-5b")
.addLayer("bottleneck",new DenseLayer.Builder().nOut(embeddingSize)
.activation(Activation.IDENTITY).build(),"avgpool")
.addVertex("embeddings", new L2NormalizeVertex(new long[] {}, 1e-6), "bottleneck")
.addLayer("lossLayer", new CenterLossOutputLayer.Builder()
.lossFunction(LossFunctions.LossFunction.SQUARED_LOSS)
.activation(Activation.SOFTMAX).nOut(numClasses).lambda(1e-4).alpha(0.9)
.gradientNormalization(GradientNormalization.RenormalizeL2PerLayer).build(),
"embeddings")
.setOutputs("lossLayer")
.setInputTypes(InputType.convolutional(inputShape[2], inputShape[1], inputShape[0]));
return graph.build();
}
@Override
public ComputationGraph init() {
ComputationGraph model = new ComputationGraph(conf());
model.init();
return model;
}
@Override
public ModelMetaData metaData() {
return new ModelMetaData(new int[][] {inputShape}, 1, ZooType.CNN);
}
@Override
public void setInputShape(int[][] inputShape) {
this.inputShape = inputShape[0];
}
}
@@ -0,0 +1,328 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * 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.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.zoo.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import org.deeplearning4j.nn.api.Model;
import org.deeplearning4j.nn.api.OptimizationAlgorithm;
import org.deeplearning4j.nn.conf.*;
import org.deeplearning4j.nn.conf.distribution.NormalDistribution;
import org.deeplearning4j.nn.conf.distribution.TruncatedNormalDistribution;
import org.deeplearning4j.nn.conf.graph.L2NormalizeVertex;
import org.deeplearning4j.nn.conf.graph.MergeVertex;
import org.deeplearning4j.nn.conf.inputs.InputType;
import org.deeplearning4j.nn.conf.layers.*;
import org.deeplearning4j.nn.graph.ComputationGraph;
import org.deeplearning4j.nn.weights.WeightInit;
import org.deeplearning4j.zoo.ModelMetaData;
import org.deeplearning4j.zoo.PretrainedType;
import org.deeplearning4j.zoo.ZooModel;
import org.deeplearning4j.zoo.ZooType;
import org.deeplearning4j.zoo.model.helper.InceptionResNetHelper;
import org.nd4j.linalg.activations.Activation;
import org.nd4j.linalg.learning.config.IUpdater;
import org.nd4j.linalg.learning.config.RmsProp;
import org.nd4j.linalg.lossfunctions.LossFunctions;
@AllArgsConstructor
@Builder
public class InceptionResNetV1 extends ZooModel {
@Builder.Default private long seed = 1234;
@Builder.Default private int[] inputShape = new int[] {3, 160, 160};
@Builder.Default private int numClasses = 0;
@Builder.Default private IUpdater updater = new RmsProp(0.1, 0.96, 0.001);
@Builder.Default private CacheMode cacheMode = CacheMode.NONE;
@Builder.Default private WorkspaceMode workspaceMode = WorkspaceMode.ENABLED;
@Builder.Default private ConvolutionLayer.AlgoMode cudnnAlgoMode = ConvolutionLayer.AlgoMode.PREFER_FASTEST;
private InceptionResNetV1() {}
@Override
public String pretrainedUrl(PretrainedType pretrainedType) {
return null;
}
@Override
public long pretrainedChecksum(PretrainedType pretrainedType) {
return 0L;
}
@Override
public Class<? extends Model> modelType() {
return ComputationGraph.class;
}
@Override
public ComputationGraph init() {
int embeddingSize = 128;
ComputationGraphConfiguration.GraphBuilder graph = graphBuilder("input1");
graph.addInputs("input1").setInputTypes(InputType.convolutional(inputShape[2], inputShape[1], inputShape[0]))
// Logits
.addLayer("bottleneck", new DenseLayer.Builder().nIn(5376).nOut(embeddingSize).build(),
"avgpool")
// Embeddings
.addVertex("embeddings", new L2NormalizeVertex(new long[] {1}, 1e-10), "bottleneck")
// Output
.addLayer("outputLayer",
new CenterLossOutputLayer.Builder()
.lossFunction(LossFunctions.LossFunction.NEGATIVELOGLIKELIHOOD)
.activation(Activation.SOFTMAX).alpha(0.9).lambda(1e-4)
.nIn(embeddingSize).nOut(numClasses).build(),
"embeddings")
.setOutputs("outputLayer");
ComputationGraphConfiguration conf = graph.build();
ComputationGraph model = new ComputationGraph(conf);
model.init();
return model;
}
public ComputationGraphConfiguration.GraphBuilder graphBuilder(String input) {
ComputationGraphConfiguration.GraphBuilder graph = new NeuralNetConfiguration.Builder().seed(seed)
.activation(Activation.RELU)
.optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT)
.updater(updater)
.weightInit(new TruncatedNormalDistribution(0.0, 0.5))
.l2(5e-5)
.miniBatch(true)
.cacheMode(cacheMode)
.trainingWorkspaceMode(workspaceMode)
.inferenceWorkspaceMode(workspaceMode)
.convolutionMode(ConvolutionMode.Truncate).graphBuilder();
graph
// stem
.addLayer("stem-cnn1",
new ConvolutionLayer.Builder(new int[] {3, 3}, new int[] {2, 2})
.nIn(inputShape[0]).nOut(32)
.cudnnAlgoMode(cudnnAlgoMode).build(),
input)
.addLayer("stem-batch1",
new BatchNormalization.Builder(false).decay(0.995).eps(0.001).nIn(32).nOut(32)
.build(),
"stem-cnn1")
.addLayer("stem-cnn2",
new ConvolutionLayer.Builder(new int[] {3, 3}).nIn(32).nOut(32)
.cudnnAlgoMode(cudnnAlgoMode).build(),
"stem-batch1")
.addLayer("stem-batch2",
new BatchNormalization.Builder(false).decay(0.995).eps(0.001).nIn(32).nOut(32)
.build(),
"stem-cnn2")
.addLayer("stem-cnn3",
new ConvolutionLayer.Builder(new int[] {3, 3})
.convolutionMode(ConvolutionMode.Same).nIn(32).nOut(64)
.cudnnAlgoMode(cudnnAlgoMode).build(),
"stem-batch2")
.addLayer("stem-batch3", new BatchNormalization.Builder(false).decay(0.995).eps(0.001).nIn(64)
.nOut(64).build(), "stem-cnn3")
.addLayer("stem-pool4", new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.MAX,
new int[] {3, 3}, new int[] {2, 2}).build(), "stem-batch3")
.addLayer("stem-cnn5",
new ConvolutionLayer.Builder(new int[] {1, 1}).nIn(64).nOut(80)
.cudnnAlgoMode(cudnnAlgoMode).build(),
"stem-pool4")
.addLayer("stem-batch5",
new BatchNormalization.Builder(false).decay(0.995).eps(0.001).nIn(80).nOut(80)
.build(),
"stem-cnn5")
.addLayer("stem-cnn6",
new ConvolutionLayer.Builder(new int[] {3, 3}).nIn(80).nOut(128)
.cudnnAlgoMode(cudnnAlgoMode).build(),
"stem-batch5")
.addLayer("stem-batch6",
new BatchNormalization.Builder(false).decay(0.995).eps(0.001).nIn(128).nOut(128)
.build(),
"stem-cnn6")
.addLayer("stem-cnn7",
new ConvolutionLayer.Builder(new int[] {3, 3}, new int[] {2, 2}).nIn(128)
.nOut(192).cudnnAlgoMode(cudnnAlgoMode)
.build(),
"stem-batch6")
.addLayer("stem-batch7", new BatchNormalization.Builder(false).decay(0.995).eps(0.001).nIn(192)
.nOut(192).build(), "stem-cnn7");
// 5xInception-resnet-A
InceptionResNetHelper.inceptionV1ResA(graph, "resnetA", 5, 0.17, "stem-batch7");
// Reduction-A
graph
// 3x3
.addLayer("reduceA-cnn1",
new ConvolutionLayer.Builder(new int[] {3, 3}, new int[] {2, 2}).nIn(192)
.nOut(192).cudnnAlgoMode(cudnnAlgoMode)
.build(),
"resnetA")
.addLayer("reduceA-batch1",
new BatchNormalization.Builder(false).decay(0.995).eps(0.001).nIn(192).nOut(192)
.build(),
"reduceA-cnn1")
// 1x1 -> 3x3 -> 3x3
.addLayer("reduceA-cnn2",
new ConvolutionLayer.Builder(new int[] {1, 1})
.convolutionMode(ConvolutionMode.Same).nIn(192).nOut(128)
.cudnnAlgoMode(cudnnAlgoMode).build(),
"resnetA")
.addLayer("reduceA-batch2",
new BatchNormalization.Builder(false).decay(0.995).eps(0.001).nIn(128).nOut(128)
.build(),
"reduceA-cnn2")
.addLayer("reduceA-cnn3",
new ConvolutionLayer.Builder(new int[] {3, 3})
.convolutionMode(ConvolutionMode.Same).nIn(128).nOut(128)
.cudnnAlgoMode(cudnnAlgoMode).build(),
"reduceA-batch2")
.addLayer("reduceA-batch3",
new BatchNormalization.Builder(false).decay(0.995).eps(0.001).nIn(128).nOut(128)
.build(),
"reduceA-cnn3")
.addLayer("reduceA-cnn4",
new ConvolutionLayer.Builder(new int[] {3, 3}, new int[] {2, 2}).nIn(128)
.nOut(192).cudnnAlgoMode(cudnnAlgoMode)
.build(),
"reduceA-batch3")
.addLayer("reduceA-batch4",
new BatchNormalization.Builder(false).decay(0.995).eps(0.001).nIn(192).nOut(192)
.build(),
"reduceA-cnn4")
// maxpool
.addLayer("reduceA-pool5",
new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.MAX, new int[] {3, 3},
new int[] {2, 2}).build(),
"resnetA")
// -->
.addVertex("reduceA", new MergeVertex(), "reduceA-batch1", "reduceA-batch4", "reduceA-pool5");
// 10xInception-resnet-B
InceptionResNetHelper.inceptionV1ResB(graph, "resnetB", 10, 0.10, "reduceA");
// Reduction-B
graph
// 3x3 pool
.addLayer("reduceB-pool1",
new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.MAX, new int[] {3, 3},
new int[] {2, 2}).build(),
"resnetB")
// 1x1 -> 3x3
.addLayer("reduceB-cnn2",
new ConvolutionLayer.Builder(new int[] {1, 1})
.convolutionMode(ConvolutionMode.Same).nIn(576).nOut(256)
.cudnnAlgoMode(cudnnAlgoMode).build(),
"resnetB")
.addLayer("reduceB-batch1",
new BatchNormalization.Builder(false).decay(0.995).eps(0.001).nIn(256).nOut(256)
.build(),
"reduceB-cnn2")
.addLayer("reduceB-cnn3",
new ConvolutionLayer.Builder(new int[] {3, 3}, new int[] {2, 2}).nIn(256)
.nOut(256).cudnnAlgoMode(cudnnAlgoMode)
.build(),
"reduceB-batch1")
.addLayer("reduceB-batch2",
new BatchNormalization.Builder(false).decay(0.995).eps(0.001).nIn(256).nOut(256)
.build(),
"reduceB-cnn3")
// 1x1 -> 3x3
.addLayer("reduceB-cnn4",
new ConvolutionLayer.Builder(new int[] {1, 1})
.convolutionMode(ConvolutionMode.Same).nIn(576).nOut(256)
.cudnnAlgoMode(cudnnAlgoMode).build(),
"resnetB")
.addLayer("reduceB-batch3",
new BatchNormalization.Builder(false).decay(0.995).eps(0.001).nIn(256).nOut(256)
.build(),
"reduceB-cnn4")
.addLayer("reduceB-cnn5",
new ConvolutionLayer.Builder(new int[] {3, 3}, new int[] {2, 2}).nIn(256)
.nOut(256).cudnnAlgoMode(cudnnAlgoMode)
.build(),
"reduceB-batch3")
.addLayer("reduceB-batch4",
new BatchNormalization.Builder(false).decay(0.995).eps(0.001).nIn(256).nOut(256)
.build(),
"reduceB-cnn5")
// 1x1 -> 3x3 -> 3x3
.addLayer("reduceB-cnn6",
new ConvolutionLayer.Builder(new int[] {1, 1})
.convolutionMode(ConvolutionMode.Same).nIn(576).nOut(256)
.cudnnAlgoMode(cudnnAlgoMode).build(),
"resnetB")
.addLayer("reduceB-batch5",
new BatchNormalization.Builder(false).decay(0.995).eps(0.001).nIn(256).nOut(256)
.build(),
"reduceB-cnn6")
.addLayer("reduceB-cnn7",
new ConvolutionLayer.Builder(new int[] {3, 3})
.convolutionMode(ConvolutionMode.Same).nIn(256).nOut(256)
.cudnnAlgoMode(cudnnAlgoMode).build(),
"reduceB-batch5")
.addLayer("reduceB-batch6",
new BatchNormalization.Builder(false).decay(0.995).eps(0.001).nIn(256).nOut(256)
.build(),
"reduceB-cnn7")
.addLayer("reduceB-cnn8",
new ConvolutionLayer.Builder(new int[] {3, 3}, new int[] {2, 2}).nIn(256)
.nOut(256).cudnnAlgoMode(cudnnAlgoMode)
.build(),
"reduceB-batch6")
.addLayer("reduceB-batch7",
new BatchNormalization.Builder(false).decay(0.995).eps(0.001).nIn(256).nOut(256)
.build(),
"reduceB-cnn8")
// -->
.addVertex("reduceB", new MergeVertex(), "reduceB-pool1", "reduceB-batch2", "reduceB-batch4",
"reduceB-batch7");
// 10xInception-resnet-C
InceptionResNetHelper.inceptionV1ResC(graph, "resnetC", 5, 0.20, "reduceB");
// Average pooling
graph.addLayer("avgpool",
new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.AVG, new int[] {1, 1}).build(),
"resnetC");
return graph;
}
@Override
public ModelMetaData metaData() {
return new ModelMetaData(new int[][] {inputShape}, 1, ZooType.CNN);
}
@Override
public void setInputShape(int[][] inputShape) {
this.inputShape = inputShape[0];
}
}
@@ -0,0 +1,152 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * 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.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.zoo.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import org.deeplearning4j.common.resources.DL4JResources;
import org.deeplearning4j.nn.api.Model;
import org.deeplearning4j.nn.api.OptimizationAlgorithm;
import org.deeplearning4j.nn.conf.*;
import org.deeplearning4j.nn.conf.inputs.InputType;
import org.deeplearning4j.nn.conf.layers.ConvolutionLayer;
import org.deeplearning4j.nn.conf.layers.DenseLayer;
import org.deeplearning4j.nn.conf.layers.OutputLayer;
import org.deeplearning4j.nn.conf.layers.SubsamplingLayer;
import org.deeplearning4j.nn.multilayer.MultiLayerNetwork;
import org.deeplearning4j.nn.weights.WeightInit;
import org.deeplearning4j.zoo.ModelMetaData;
import org.deeplearning4j.zoo.PretrainedType;
import org.deeplearning4j.zoo.ZooModel;
import org.deeplearning4j.zoo.ZooType;
import org.nd4j.linalg.activations.Activation;
import org.nd4j.linalg.learning.config.AdaDelta;
import org.nd4j.linalg.learning.config.IUpdater;
import org.nd4j.linalg.lossfunctions.LossFunctions;
@AllArgsConstructor
@Builder
public class LeNet extends ZooModel {
@Builder.Default private long seed = 1234;
@Builder.Default private int[] inputShape = new int[] {1, 28, 28};
@Builder.Default private int numClasses = 0;
@Builder.Default private IUpdater updater = new AdaDelta();
@Builder.Default private CacheMode cacheMode = CacheMode.NONE;
@Builder.Default private WorkspaceMode workspaceMode = WorkspaceMode.ENABLED;
@Builder.Default private ConvolutionLayer.AlgoMode cudnnAlgoMode = ConvolutionLayer.AlgoMode.PREFER_FASTEST;
private LeNet() {}
@Override
public String pretrainedUrl(PretrainedType pretrainedType) {
if (pretrainedType == PretrainedType.MNIST)
return DL4JResources.getURLString("models/lenet_dl4j_mnist_inference.zip");
else
return null;
}
@Override
public long pretrainedChecksum(PretrainedType pretrainedType) {
if (pretrainedType == PretrainedType.MNIST)
return 1906861161L;
else
return 0L;
}
@Override
public Class<? extends Model> modelType() {
return MultiLayerNetwork.class;
}
public MultiLayerConfiguration conf() {
MultiLayerConfiguration conf = new NeuralNetConfiguration.Builder().seed(seed)
.activation(Activation.IDENTITY)
.weightInit(WeightInit.XAVIER)
.optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT)
.updater(updater)
.cacheMode(cacheMode)
.trainingWorkspaceMode(workspaceMode)
.inferenceWorkspaceMode(workspaceMode)
.cudnnAlgoMode(cudnnAlgoMode)
.convolutionMode(ConvolutionMode.Same)
.list()
// block 1
.layer(new ConvolutionLayer.Builder()
.name("cnn1")
.kernelSize(5, 5)
.stride(1, 1)
.nIn(inputShape[0])
.nOut(20)
.activation(Activation.RELU)
.build())
.layer(new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.MAX)
.name("maxpool1")
.kernelSize(2, 2)
.stride(2, 2)
.build())
// block 2
.layer(new ConvolutionLayer.Builder()
.name("cnn2")
.kernelSize(5, 5)
.stride(1, 1)
.nOut(50)
.activation(Activation.RELU).build())
.layer(new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.MAX)
.name("maxpool2")
.kernelSize(2, 2)
.stride(2, 2)
.build())
// fully connected
.layer(new DenseLayer.Builder()
.name("ffn1")
.activation(Activation.RELU)
.nOut(500)
.build())
// output
.layer(new OutputLayer.Builder(LossFunctions.LossFunction.MCXENT)
.name("output")
.nOut(numClasses)
.activation(Activation.SOFTMAX) // radial basis function required
.build())
.setInputType(InputType.convolutionalFlat(inputShape[2], inputShape[1], inputShape[0]))
.build();
return conf;
}
@Override
public Model init() {
MultiLayerNetwork network = new MultiLayerNetwork(conf());
network.init();
return network;
}
@Override
public ModelMetaData metaData() {
return new ModelMetaData(new int[][] {inputShape}, 1, ZooType.CNN);
}
@Override
public void setInputShape(int[][] inputShape) {
this.inputShape = inputShape[0];
}
}
@@ -0,0 +1,200 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * 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.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.zoo.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import org.deeplearning4j.common.resources.DL4JResources;
import org.deeplearning4j.nn.api.Model;
import org.deeplearning4j.nn.api.OptimizationAlgorithm;
import org.deeplearning4j.nn.conf.*;
import org.deeplearning4j.nn.conf.inputs.InputType;
import org.deeplearning4j.nn.conf.layers.*;
import org.deeplearning4j.nn.graph.ComputationGraph;
import org.deeplearning4j.nn.weights.WeightInit;
import org.deeplearning4j.zoo.ModelMetaData;
import org.deeplearning4j.zoo.PretrainedType;
import org.deeplearning4j.zoo.ZooModel;
import org.deeplearning4j.zoo.ZooType;
import org.nd4j.linalg.activations.Activation;
import org.nd4j.linalg.learning.config.AdaDelta;
import org.nd4j.linalg.learning.config.IUpdater;
import org.nd4j.linalg.lossfunctions.LossFunctions;
import org.nd4j.common.primitives.Pair;
import static org.deeplearning4j.zoo.model.helper.NASNetHelper.normalA;
import static org.deeplearning4j.zoo.model.helper.NASNetHelper.reductionA;
@AllArgsConstructor
@Builder
public class NASNet extends ZooModel {
@Builder.Default private long seed = 1234;
@Builder.Default private int[] inputShape = new int[] {3, 224, 224};
@Builder.Default private int numClasses = 0;
@Builder.Default private WeightInit weightInit = WeightInit.RELU;
@Builder.Default private IUpdater updater = new AdaDelta();
@Builder.Default private CacheMode cacheMode = CacheMode.DEVICE;
@Builder.Default private WorkspaceMode workspaceMode = WorkspaceMode.ENABLED;
@Builder.Default private ConvolutionLayer.AlgoMode cudnnAlgoMode = ConvolutionLayer.AlgoMode.PREFER_FASTEST;
// NASNet specific
@Builder.Default private int numBlocks = 6;
@Builder.Default private int penultimateFilters = 1056;
@Builder.Default private int stemFilters = 96;
@Builder.Default private int filterMultiplier = 2;
@Builder.Default private boolean skipReduction = true;
private NASNet() {}
@Override
public String pretrainedUrl(PretrainedType pretrainedType) {
if (pretrainedType == PretrainedType.IMAGENET)
return DL4JResources.getURLString("models/nasnetmobile_dl4j_inference.v1.zip");
else if (pretrainedType == PretrainedType.IMAGENETLARGE)
return DL4JResources.getURLString("models/nasnetlarge_dl4j_inference.v1.zip");
else
return null;
}
@Override
public long pretrainedChecksum(PretrainedType pretrainedType) {
if (pretrainedType == PretrainedType.IMAGENET)
return 3082463801L;
else if (pretrainedType == PretrainedType.IMAGENETLARGE)
return 321395591L;
else
return 0L;
}
@Override
public Class<? extends Model> modelType() {
return ComputationGraph.class;
}
@Override
public ComputationGraph init() {
ComputationGraphConfiguration.GraphBuilder graph = graphBuilder();
graph.addInputs("input").setInputTypes(InputType.convolutional(inputShape[2], inputShape[1], inputShape[0]));
ComputationGraphConfiguration conf = graph.build();
ComputationGraph model = new ComputationGraph(conf);
model.init();
return model;
}
public ComputationGraphConfiguration.GraphBuilder graphBuilder() {
if(penultimateFilters % 24 != 0) {
throw new IllegalArgumentException("For NASNet-A models penultimate filters must be divisible by 24. Current value is "+penultimateFilters);
}
int filters = (int) Math.floor(penultimateFilters / 24);
ComputationGraphConfiguration.GraphBuilder graph = new NeuralNetConfiguration.Builder().seed(seed)
.optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT)
.updater(updater)
.weightInit(weightInit)
.l2(5e-5)
.miniBatch(true)
.cacheMode(cacheMode)
.trainingWorkspaceMode(workspaceMode)
.inferenceWorkspaceMode(workspaceMode)
.cudnnAlgoMode(cudnnAlgoMode)
.convolutionMode(ConvolutionMode.Truncate)
.graphBuilder();
if(!skipReduction) {
graph.addLayer("stem_conv1", new ConvolutionLayer.Builder(3, 3).stride(2, 2).nOut(stemFilters).hasBias(false)
.cudnnAlgoMode(cudnnAlgoMode).build(), "input");
} else {
graph.addLayer("stem_conv1", new ConvolutionLayer.Builder(3, 3).stride(1, 1).nOut(stemFilters).hasBias(false)
.cudnnAlgoMode(cudnnAlgoMode).build(), "input");
}
graph.addLayer("stem_bn1", new BatchNormalization.Builder().eps(1e-3).gamma(0.9997).build(), "stem_conv1");
String inputX = "stem_bn1";
String inputP = null;
if(!skipReduction) {
Pair<String, String> stem1 = reductionA(graph, (int) Math.floor(stemFilters / Math.pow(filterMultiplier,2)), "stem1", "stem_conv1", inputP);
Pair<String, String> stem2 = reductionA(graph, (int) Math.floor(stemFilters / (filterMultiplier)), "stem2", stem1.getFirst(), stem1.getSecond());
inputX = stem2.getFirst();
inputP = stem2.getSecond();
}
for(int i = 0; i < numBlocks; i++){
Pair<String, String> block = normalA(graph, filters, String.valueOf(i), inputX, inputP);
inputX = block.getFirst();
inputP = block.getSecond();
}
String inputP0;
Pair<String, String> reduce = reductionA(graph, filters * filterMultiplier, "reduce"+numBlocks, inputX, inputP);
inputX = reduce.getFirst();
inputP0 = reduce.getSecond();
if(!skipReduction) inputP = inputP0;
for(int i = 0; i < numBlocks; i++){
Pair<String, String> block = normalA(graph, filters * filterMultiplier, String.valueOf(i+numBlocks+1), inputX, inputP);
inputX = block.getFirst();
inputP = block.getSecond();
}
reduce = reductionA(graph, filters * (int)Math.pow(filterMultiplier, 2), "reduce"+(2*numBlocks), inputX, inputP);
inputX = reduce.getFirst();
inputP0 = reduce.getSecond();
if(!skipReduction) inputP = inputP0;
for(int i = 0; i < numBlocks; i++){
Pair<String, String> block = normalA(graph, filters * (int) Math.pow(filterMultiplier, 2), String.valueOf(i+(2*numBlocks)+1), inputX, inputP);
inputX = block.getFirst();
inputP = block.getSecond();
}
// output
graph
.addLayer("act", new ActivationLayer(Activation.RELU), inputX)
.addLayer("avg_pool", new GlobalPoolingLayer.Builder(PoolingType.AVG).build(), "act")
.addLayer("output", new OutputLayer.Builder(LossFunctions.LossFunction.MCXENT)
.activation(Activation.SOFTMAX).build(), "avg_pool")
.setOutputs("output")
;
return graph;
}
@Override
public ModelMetaData metaData() {
return new ModelMetaData(new int[][] {inputShape}, 1, ZooType.CNN);
}
@Override
public void setInputShape(int[][] inputShape) {
this.inputShape = inputShape[0];
}
}
@@ -0,0 +1,249 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * 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.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.zoo.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import org.deeplearning4j.common.resources.DL4JResources;
import org.deeplearning4j.nn.api.Model;
import org.deeplearning4j.nn.api.OptimizationAlgorithm;
import org.deeplearning4j.nn.conf.*;
import org.deeplearning4j.nn.conf.distribution.NormalDistribution;
import org.deeplearning4j.nn.conf.distribution.TruncatedNormalDistribution;
import org.deeplearning4j.nn.conf.graph.ElementWiseVertex;
import org.deeplearning4j.nn.conf.inputs.InputType;
import org.deeplearning4j.nn.conf.layers.*;
import org.deeplearning4j.nn.graph.ComputationGraph;
import org.deeplearning4j.nn.weights.IWeightInit;
import org.deeplearning4j.nn.weights.WeightInit;
import org.deeplearning4j.nn.weights.WeightInitDistribution;
import org.deeplearning4j.zoo.ModelMetaData;
import org.deeplearning4j.zoo.PretrainedType;
import org.deeplearning4j.zoo.ZooModel;
import org.deeplearning4j.zoo.ZooType;
import org.nd4j.linalg.activations.Activation;
import org.nd4j.linalg.learning.config.IUpdater;
import org.nd4j.linalg.learning.config.RmsProp;
import org.nd4j.linalg.lossfunctions.LossFunctions;
@AllArgsConstructor
@Builder
public class ResNet50 extends ZooModel {
@Builder.Default private long seed = 1234;
@Builder.Default private int[] inputShape = new int[] {3, 224, 224};
@Builder.Default private int numClasses = 0;
@Builder.Default private IWeightInit weightInit = new WeightInitDistribution(new TruncatedNormalDistribution(0.0, 0.5));
@Builder.Default private IUpdater updater = new RmsProp(0.1, 0.96, 0.001);
@Builder.Default private CacheMode cacheMode = CacheMode.NONE;
@Builder.Default private WorkspaceMode workspaceMode = WorkspaceMode.ENABLED;
@Builder.Default private ConvolutionLayer.AlgoMode cudnnAlgoMode = ConvolutionLayer.AlgoMode.PREFER_FASTEST;
private ResNet50() {}
@Override
public String pretrainedUrl(PretrainedType pretrainedType) {
if (pretrainedType == PretrainedType.IMAGENET)
return DL4JResources.getURLString("models/resnet50_dl4j_inference.v3.zip");
else
return null;
}
@Override
public long pretrainedChecksum(PretrainedType pretrainedType) {
if (pretrainedType == PretrainedType.IMAGENET)
return 3914447815L;
else
return 0L;
}
@Override
public Class<? extends Model> modelType() {
return ComputationGraph.class;
}
@Override
public ComputationGraph init() {
ComputationGraphConfiguration.GraphBuilder graph = graphBuilder();
ComputationGraphConfiguration conf = graph.build();
ComputationGraph model = new ComputationGraph(conf);
model.init();
return model;
}
private void identityBlock(ComputationGraphConfiguration.GraphBuilder graph, int[] kernelSize, int[] filters,
String stage, String block, String input) {
String convName = "res" + stage + block + "_branch";
String batchName = "bn" + stage + block + "_branch";
String activationName = "act" + stage + block + "_branch";
String shortcutName = "short" + stage + block + "_branch";
graph.addLayer(convName + "2a",
new ConvolutionLayer.Builder(new int[] {1, 1}).nOut(filters[0]).cudnnAlgoMode(cudnnAlgoMode)
.build(),
input)
.addLayer(batchName + "2a", new BatchNormalization(), convName + "2a")
.addLayer(activationName + "2a",
new ActivationLayer.Builder().activation(Activation.RELU).build(),
batchName + "2a")
.addLayer(convName + "2b", new ConvolutionLayer.Builder(kernelSize).nOut(filters[1])
.cudnnAlgoMode(cudnnAlgoMode).convolutionMode(ConvolutionMode.Same).build(),
activationName + "2a")
.addLayer(batchName + "2b", new BatchNormalization(), convName + "2b")
.addLayer(activationName + "2b",
new ActivationLayer.Builder().activation(Activation.RELU).build(),
batchName + "2b")
.addLayer(convName + "2c",
new ConvolutionLayer.Builder(new int[] {1, 1}).nOut(filters[2])
.cudnnAlgoMode(cudnnAlgoMode).build(),
activationName + "2b")
.addLayer(batchName + "2c", new BatchNormalization(), convName + "2c")
.addVertex(shortcutName, new ElementWiseVertex(ElementWiseVertex.Op.Add), batchName + "2c",
input)
.addLayer(convName, new ActivationLayer.Builder().activation(Activation.RELU).build(),
shortcutName);
}
private void convBlock(ComputationGraphConfiguration.GraphBuilder graph, int[] kernelSize, int[] filters,
String stage, String block, String input) {
convBlock(graph, kernelSize, filters, stage, block, new int[] {2, 2}, input);
}
private void convBlock(ComputationGraphConfiguration.GraphBuilder graph, int[] kernelSize, int[] filters,
String stage, String block, int[] stride, String input) {
String convName = "res" + stage + block + "_branch";
String batchName = "bn" + stage + block + "_branch";
String activationName = "act" + stage + block + "_branch";
String shortcutName = "short" + stage + block + "_branch";
graph.addLayer(convName + "2a", new ConvolutionLayer.Builder(new int[] {1, 1}, stride).nOut(filters[0]).build(),
input)
.addLayer(batchName + "2a", new BatchNormalization(), convName + "2a")
.addLayer(activationName + "2a",
new ActivationLayer.Builder().activation(Activation.RELU).build(),
batchName + "2a")
.addLayer(convName + "2b",
new ConvolutionLayer.Builder(kernelSize).nOut(filters[1])
.convolutionMode(ConvolutionMode.Same).build(),
activationName + "2a")
.addLayer(batchName + "2b", new BatchNormalization(), convName + "2b")
.addLayer(activationName + "2b",
new ActivationLayer.Builder().activation(Activation.RELU).build(),
batchName + "2b")
.addLayer(convName + "2c",
new ConvolutionLayer.Builder(new int[] {1, 1}).nOut(filters[2]).build(),
activationName + "2b")
.addLayer(batchName + "2c", new BatchNormalization(), convName + "2c")
// shortcut
.addLayer(convName + "1",
new ConvolutionLayer.Builder(new int[] {1, 1}, stride).nOut(filters[2]).build(),
input)
.addLayer(batchName + "1", new BatchNormalization(), convName + "1")
.addVertex(shortcutName, new ElementWiseVertex(ElementWiseVertex.Op.Add), batchName + "2c",
batchName + "1")
.addLayer(convName, new ActivationLayer.Builder().activation(Activation.RELU).build(),
shortcutName);
}
public ComputationGraphConfiguration.GraphBuilder graphBuilder() {
ComputationGraphConfiguration.GraphBuilder graph = new NeuralNetConfiguration.Builder().seed(seed)
.activation(Activation.IDENTITY)
.optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT)
.updater(updater)
.weightInit(weightInit)
.l1(1e-7)
.l2(5e-5)
.miniBatch(true)
.cacheMode(cacheMode)
.trainingWorkspaceMode(workspaceMode)
.inferenceWorkspaceMode(workspaceMode)
.cudnnAlgoMode(cudnnAlgoMode)
.convolutionMode(ConvolutionMode.Truncate)
.graphBuilder();
graph.addInputs("input").setInputTypes(InputType.convolutional(inputShape[2], inputShape[1], inputShape[0]))
// stem
.addLayer("stem-zero", new ZeroPaddingLayer.Builder(3, 3).build(), "input")
.addLayer("stem-cnn1",
new ConvolutionLayer.Builder(new int[] {7, 7}, new int[] {2, 2}).nOut(64)
.build(),
"stem-zero")
.addLayer("stem-batch1", new BatchNormalization(), "stem-cnn1")
.addLayer("stem-act1", new ActivationLayer.Builder().activation(Activation.RELU).build(),
"stem-batch1")
.addLayer("stem-maxpool1", new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.MAX,
new int[] {3, 3}, new int[] {2, 2}).build(), "stem-act1");
convBlock(graph, new int[] {3, 3}, new int[] {64, 64, 256}, "2", "a", new int[] {2, 2}, "stem-maxpool1");
identityBlock(graph, new int[] {3, 3}, new int[] {64, 64, 256}, "2", "b", "res2a_branch");
identityBlock(graph, new int[] {3, 3}, new int[] {64, 64, 256}, "2", "c", "res2b_branch");
convBlock(graph, new int[] {3, 3}, new int[] {128, 128, 512}, "3", "a", "res2c_branch");
identityBlock(graph, new int[] {3, 3}, new int[] {128, 128, 512}, "3", "b", "res3a_branch");
identityBlock(graph, new int[] {3, 3}, new int[] {128, 128, 512}, "3", "c", "res3b_branch");
identityBlock(graph, new int[] {3, 3}, new int[] {128, 128, 512}, "3", "d", "res3c_branch");
convBlock(graph, new int[] {3, 3}, new int[] {256, 256, 1024}, "4", "a", "res3d_branch");
identityBlock(graph, new int[] {3, 3}, new int[] {256, 256, 1024}, "4", "b", "res4a_branch");
identityBlock(graph, new int[] {3, 3}, new int[] {256, 256, 1024}, "4", "c", "res4b_branch");
identityBlock(graph, new int[] {3, 3}, new int[] {256, 256, 1024}, "4", "d", "res4c_branch");
identityBlock(graph, new int[] {3, 3}, new int[] {256, 256, 1024}, "4", "e", "res4d_branch");
identityBlock(graph, new int[] {3, 3}, new int[] {256, 256, 1024}, "4", "f", "res4e_branch");
convBlock(graph, new int[] {3, 3}, new int[] {512, 512, 2048}, "5", "a", "res4f_branch");
identityBlock(graph, new int[] {3, 3}, new int[] {512, 512, 2048}, "5", "b", "res5a_branch");
identityBlock(graph, new int[] {3, 3}, new int[] {512, 512, 2048}, "5", "c", "res5b_branch");
graph.addLayer("avgpool",
new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.MAX, new int[] {3, 3}).build(),
"res5c_branch")
// TODO add flatten/reshape layer here
.addLayer("output",
new OutputLayer.Builder(LossFunctions.LossFunction.NEGATIVELOGLIKELIHOOD)
.nOut(numClasses).activation(Activation.SOFTMAX).build(),
"avgpool")
.setOutputs("output");
return graph;
}
@Override
public ModelMetaData metaData() {
return new ModelMetaData(new int[][] {inputShape}, 1, ZooType.CNN);
}
@Override
public void setInputShape(int[][] inputShape) {
this.inputShape = inputShape[0];
}
}
@@ -0,0 +1,155 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * 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.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.zoo.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import org.deeplearning4j.nn.api.Model;
import org.deeplearning4j.nn.api.OptimizationAlgorithm;
import org.deeplearning4j.nn.conf.*;
import org.deeplearning4j.nn.conf.inputs.InputType;
import org.deeplearning4j.nn.conf.layers.*;
import org.deeplearning4j.nn.multilayer.MultiLayerNetwork;
import org.deeplearning4j.nn.weights.WeightInit;
import org.deeplearning4j.zoo.ModelMetaData;
import org.deeplearning4j.zoo.PretrainedType;
import org.deeplearning4j.zoo.ZooModel;
import org.deeplearning4j.zoo.ZooType;
import org.nd4j.linalg.activations.Activation;
import org.nd4j.linalg.learning.config.AdaDelta;
import org.nd4j.linalg.learning.config.IUpdater;
@AllArgsConstructor
@Builder
public class SimpleCNN extends ZooModel {
@Builder.Default private long seed = 1234;
@Builder.Default private int[] inputShape = new int[] {3, 48, 48};
@Builder.Default private int numClasses = 0;
@Builder.Default private IUpdater updater = new AdaDelta();
@Builder.Default private CacheMode cacheMode = CacheMode.NONE;
@Builder.Default private WorkspaceMode workspaceMode = WorkspaceMode.ENABLED;
@Builder.Default private ConvolutionLayer.AlgoMode cudnnAlgoMode = ConvolutionLayer.AlgoMode.PREFER_FASTEST;
private SimpleCNN() {}
@Override
public String pretrainedUrl(PretrainedType pretrainedType) {
return null;
}
@Override
public long pretrainedChecksum(PretrainedType pretrainedType) {
return 0L;
}
@Override
public Class<? extends Model> modelType() {
return MultiLayerNetwork.class;
}
public MultiLayerConfiguration conf() {
MultiLayerConfiguration conf =
new NeuralNetConfiguration.Builder().seed(seed)
.activation(Activation.IDENTITY)
.weightInit(WeightInit.RELU)
.optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT)
.updater(updater)
.cacheMode(cacheMode)
.trainingWorkspaceMode(workspaceMode)
.inferenceWorkspaceMode(workspaceMode)
.convolutionMode(ConvolutionMode.Same)
.list()
// block 1
.layer(0, new ConvolutionLayer.Builder(new int[] {7, 7}).name("image_array")
.nIn(inputShape[0]).nOut(16).build())
.layer(1, new BatchNormalization.Builder().build())
.layer(2, new ConvolutionLayer.Builder(new int[] {7, 7}).nIn(16).nOut(16)
.build())
.layer(3, new BatchNormalization.Builder().build())
.layer(4, new ActivationLayer.Builder().activation(Activation.RELU).build())
.layer(5, new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.AVG,
new int[] {2, 2}).build())
.layer(6, new DropoutLayer.Builder(0.5).build())
// block 2
.layer(7, new ConvolutionLayer.Builder(new int[] {5, 5}).nOut(32).build())
.layer(8, new BatchNormalization.Builder().build())
.layer(9, new ConvolutionLayer.Builder(new int[] {5, 5}).nOut(32).build())
.layer(10, new BatchNormalization.Builder().build())
.layer(11, new ActivationLayer.Builder().activation(Activation.RELU).build())
.layer(12, new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.AVG,
new int[] {2, 2}).build())
.layer(13, new DropoutLayer.Builder(0.5).build())
// block 3
.layer(14, new ConvolutionLayer.Builder(new int[] {3, 3}).nOut(64).build())
.layer(15, new BatchNormalization.Builder().build())
.layer(16, new ConvolutionLayer.Builder(new int[] {3, 3}).nOut(64).build())
.layer(17, new BatchNormalization.Builder().build())
.layer(18, new ActivationLayer.Builder().activation(Activation.RELU).build())
.layer(19, new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.AVG,
new int[] {2, 2}).build())
.layer(20, new DropoutLayer.Builder(0.5).build())
// block 4
.layer(21, new ConvolutionLayer.Builder(new int[] {3, 3}).nOut(128).build())
.layer(22, new BatchNormalization.Builder().build())
.layer(23, new ConvolutionLayer.Builder(new int[] {3, 3}).nOut(128).build())
.layer(24, new BatchNormalization.Builder().build())
.layer(25, new ActivationLayer.Builder().activation(Activation.RELU).build())
.layer(26, new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.AVG,
new int[] {2, 2}).build())
.layer(27, new DropoutLayer.Builder(0.5).build())
// block 5
.layer(28, new ConvolutionLayer.Builder(new int[] {3, 3}).nOut(256).build())
.layer(29, new BatchNormalization.Builder().build())
.layer(30, new ConvolutionLayer.Builder(new int[] {3, 3}).nOut(numClasses)
.build())
.layer(31, new GlobalPoolingLayer.Builder(PoolingType.AVG).build())
.layer(32, new ActivationLayer.Builder().activation(Activation.SOFTMAX).build())
.setInputType(InputType.convolutional(inputShape[2], inputShape[1],
inputShape[0]))
.build();
return conf;
}
@Override
public Model init() {
MultiLayerNetwork network = new MultiLayerNetwork(conf());
network.init();
return network;
}
@Override
public ModelMetaData metaData() {
return new ModelMetaData(new int[][] {inputShape}, 1, ZooType.CNN);
}
@Override
public void setInputShape(int[][] inputShape) {
this.inputShape = inputShape[0];
}
}
@@ -0,0 +1,189 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * 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.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.zoo.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import org.deeplearning4j.common.resources.DL4JResources;
import org.deeplearning4j.nn.api.Model;
import org.deeplearning4j.nn.api.OptimizationAlgorithm;
import org.deeplearning4j.nn.conf.*;
import org.deeplearning4j.nn.conf.distribution.NormalDistribution;
import org.deeplearning4j.nn.conf.graph.MergeVertex;
import org.deeplearning4j.nn.conf.inputs.InputType;
import org.deeplearning4j.nn.conf.layers.*;
import org.deeplearning4j.nn.graph.ComputationGraph;
import org.deeplearning4j.nn.weights.WeightInit;
import org.deeplearning4j.zoo.ModelMetaData;
import org.deeplearning4j.zoo.PretrainedType;
import org.deeplearning4j.zoo.ZooModel;
import org.deeplearning4j.zoo.ZooType;
import org.nd4j.linalg.activations.Activation;
import org.nd4j.linalg.learning.config.AdaDelta;
import org.nd4j.linalg.learning.config.IUpdater;
import org.nd4j.linalg.lossfunctions.LossFunctions;
import java.io.IOException;
@AllArgsConstructor
@Builder
public class SqueezeNet extends ZooModel {
@Builder.Default private long seed = 1234;
@Builder.Default private int[] inputShape = new int[] {3, 227, 227};
@Builder.Default private int numClasses = 0;
@Builder.Default private WeightInit weightInit = WeightInit.RELU;
@Builder.Default private IUpdater updater = new AdaDelta();
@Builder.Default private CacheMode cacheMode = CacheMode.NONE;
@Builder.Default private WorkspaceMode workspaceMode = WorkspaceMode.ENABLED;
@Builder.Default private ConvolutionLayer.AlgoMode cudnnAlgoMode = ConvolutionLayer.AlgoMode.PREFER_FASTEST;
private SqueezeNet() {}
@Override
public String pretrainedUrl(PretrainedType pretrainedType) {
if (pretrainedType == PretrainedType.IMAGENET)
return DL4JResources.getURLString("models/squeezenet_dl4j_inference.v2.zip");
else
return null;
}
@Override
public long pretrainedChecksum(PretrainedType pretrainedType) {
if (pretrainedType == PretrainedType.IMAGENET)
return 3711411239L;
else
return 0L;
}
@Override
public ComputationGraph initPretrained(PretrainedType pretrainedType) throws IOException {
ComputationGraph cg = (ComputationGraph) super.initPretrained(pretrainedType);
//Set collapse dimensions to true in global avg pooling - more useful for users [N,1000] rather than [N,1000,1,1] out. Also matches non-pretrain config
((GlobalPoolingLayer)cg.getLayer("global_average_pooling2d_5").conf().getLayer()).setCollapseDimensions(true);
return cg;
}
@Override
public Class<? extends Model> modelType() {
return ComputationGraph.class;
}
@Override
public ComputationGraph init() {
ComputationGraphConfiguration.GraphBuilder graph = graphBuilder();
graph.addInputs("input").setInputTypes(InputType.convolutional(inputShape[2], inputShape[1], inputShape[0]));
ComputationGraphConfiguration conf = graph.build();
ComputationGraph model = new ComputationGraph(conf);
model.init();
return model;
}
public ComputationGraphConfiguration.GraphBuilder graphBuilder() {
ComputationGraphConfiguration.GraphBuilder graph = new NeuralNetConfiguration.Builder().seed(seed)
.optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT)
.updater(updater)
.weightInit(weightInit)
.l2(5e-5)
.miniBatch(true)
.cacheMode(cacheMode)
.trainingWorkspaceMode(workspaceMode)
.inferenceWorkspaceMode(workspaceMode)
.convolutionMode(ConvolutionMode.Truncate)
.graphBuilder();
graph
// stem
.addLayer("conv1", new ConvolutionLayer.Builder(3,3).stride(2,2).nOut(64)
.cudnnAlgoMode(cudnnAlgoMode).build(), "input")
.addLayer("conv1_act", new ActivationLayer(Activation.RELU), "conv1")
.addLayer("pool1", new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.MAX).kernelSize(3,3).stride(2,2).build(), "conv1_act");
// fire modules
fireModule(graph, 2, 16, 64, "pool1");
fireModule(graph, 3, 16, 64, "fire2");
graph.addLayer("pool3", new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.MAX).kernelSize(3,3).stride(2,2).build(), "fire3");
fireModule(graph, 4, 32, 128, "pool3");
fireModule(graph, 5, 32, 128, "fire4");
graph.addLayer("pool5", new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.MAX).kernelSize(3,3).stride(2,2).build(), "fire5");
fireModule(graph, 6, 48, 192, "pool5");
fireModule(graph, 7, 48, 192, "fire6");
fireModule(graph, 8, 64, 256, "fire7");
fireModule(graph, 9, 64, 256, "fire8");
graph
// output
.addLayer("drop9", new DropoutLayer.Builder(0.5).build(), "fire9")
.addLayer("conv10", new ConvolutionLayer.Builder(1,1).nOut(numClasses)
.cudnnAlgoMode(cudnnAlgoMode).build(), "drop9")
.addLayer("conv10_act", new ActivationLayer(Activation.RELU), "conv10")
.addLayer("avg_pool", new GlobalPoolingLayer(PoolingType.AVG), "conv10_act")
.addLayer("softmax", new ActivationLayer(Activation.SOFTMAX), "avg_pool")
.addLayer("loss", new LossLayer.Builder(LossFunctions.LossFunction.MCXENT).build(), "softmax")
.setOutputs("loss")
;
return graph;
}
private String fireModule(ComputationGraphConfiguration.GraphBuilder graphBuilder, int fireId, int squeeze, int expand, String input) {
String prefix = "fire"+fireId;
graphBuilder
.addLayer(prefix+"_sq1x1", new ConvolutionLayer.Builder(1, 1).nOut(squeeze)
.cudnnAlgoMode(cudnnAlgoMode).build(), input)
.addLayer(prefix+"_relu_sq1x1", new ActivationLayer(Activation.RELU), prefix+"_sq1x1")
.addLayer(prefix+"_exp1x1", new ConvolutionLayer.Builder(1, 1).nOut(expand)
.cudnnAlgoMode(cudnnAlgoMode).build(), prefix+"_relu_sq1x1")
.addLayer(prefix+"_relu_exp1x1", new ActivationLayer(Activation.RELU), prefix+"_exp1x1")
.addLayer(prefix+"_exp3x3", new ConvolutionLayer.Builder(3,3).nOut(expand)
.convolutionMode(ConvolutionMode.Same)
.cudnnAlgoMode(cudnnAlgoMode).build(), prefix+"_relu_sq1x1")
.addLayer(prefix+"_relu_exp3x3", new ActivationLayer(Activation.RELU), prefix+"_exp3x3")
.addVertex(prefix, new MergeVertex(), prefix+"_relu_exp1x1", prefix+"_relu_exp3x3");
return prefix;
}
@Override
public ModelMetaData metaData() {
return new ModelMetaData(new int[][] {inputShape}, 1, ZooType.CNN);
}
@Override
public void setInputShape(int[][] inputShape) {
this.inputShape = inputShape[0];
}
}
@@ -0,0 +1,111 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * 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.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.zoo.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import org.deeplearning4j.nn.api.Model;
import org.deeplearning4j.nn.api.OptimizationAlgorithm;
import org.deeplearning4j.nn.conf.*;
import org.deeplearning4j.nn.conf.layers.ConvolutionLayer;
import org.deeplearning4j.nn.conf.layers.LSTM;
import org.deeplearning4j.nn.conf.layers.RnnOutputLayer;
import org.deeplearning4j.nn.multilayer.MultiLayerNetwork;
import org.deeplearning4j.nn.weights.WeightInit;
import org.deeplearning4j.zoo.ModelMetaData;
import org.deeplearning4j.zoo.PretrainedType;
import org.deeplearning4j.zoo.ZooModel;
import org.deeplearning4j.zoo.ZooType;
import org.nd4j.linalg.activations.Activation;
import org.nd4j.linalg.learning.config.IUpdater;
import org.nd4j.linalg.learning.config.RmsProp;
import org.nd4j.linalg.lossfunctions.LossFunctions;
@AllArgsConstructor
@Builder
public class TextGenerationLSTM extends ZooModel {
@Builder.Default private long seed = 1234;
@Builder.Default private int maxLength = 40;
@Builder.Default private int totalUniqueCharacters = 47;
private int[] inputShape = new int[] {maxLength, totalUniqueCharacters};
@Builder.Default private IUpdater updater = new RmsProp(0.01);
@Builder.Default private CacheMode cacheMode = CacheMode.NONE;
@Builder.Default private WorkspaceMode workspaceMode = WorkspaceMode.ENABLED;
@Builder.Default private ConvolutionLayer.AlgoMode cudnnAlgoMode = ConvolutionLayer.AlgoMode.PREFER_FASTEST;
private TextGenerationLSTM() {}
@Override
public String pretrainedUrl(PretrainedType pretrainedType) {
return null;
}
@Override
public long pretrainedChecksum(PretrainedType pretrainedType) {
return 0L;
}
@Override
public Class<? extends Model> modelType() {
return MultiLayerNetwork.class;
}
public MultiLayerConfiguration conf() {
MultiLayerConfiguration conf = new NeuralNetConfiguration.Builder().seed(12345)
.optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT)
.l2(0.001)
.weightInit(WeightInit.XAVIER)
.updater(updater)
.cacheMode(cacheMode)
.trainingWorkspaceMode(workspaceMode)
.inferenceWorkspaceMode(workspaceMode)
.cudnnAlgoMode(cudnnAlgoMode)
.list()
.layer(0, new LSTM.Builder().nIn(inputShape[1]).nOut(256).activation(Activation.TANH)
.build())
.layer(1, new LSTM.Builder().nOut(256).activation(Activation.TANH).build())
.layer(2, new RnnOutputLayer.Builder(LossFunctions.LossFunction.MCXENT)
.activation(Activation.SOFTMAX) //MCXENT + softmax for classification
.nOut(totalUniqueCharacters).build())
.backpropType(BackpropType.TruncatedBPTT).tBPTTForwardLength(50).tBPTTBackwardLength(50)
.build();
return conf;
}
@Override
public Model init() {
MultiLayerNetwork network = new MultiLayerNetwork(conf());
network.init();
return network;
}
@Override
public ModelMetaData metaData() {
return new ModelMetaData(new int[][] {inputShape}, 1, ZooType.RNN);
}
@Override
public void setInputShape(int[][] inputShape) {
this.inputShape = inputShape[0];
}
}
@@ -0,0 +1,160 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * 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.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.zoo.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import org.deeplearning4j.common.resources.DL4JResources;
import org.deeplearning4j.nn.api.Model;
import org.deeplearning4j.nn.api.OptimizationAlgorithm;
import org.deeplearning4j.nn.conf.*;
import org.deeplearning4j.nn.conf.ComputationGraphConfiguration.GraphBuilder;
import org.deeplearning4j.nn.conf.inputs.InputType;
import org.deeplearning4j.nn.conf.layers.ConvolutionLayer;
import org.deeplearning4j.nn.conf.layers.objdetect.Yolo2OutputLayer;
import org.deeplearning4j.nn.graph.ComputationGraph;
import org.deeplearning4j.nn.weights.WeightInit;
import org.deeplearning4j.zoo.ModelMetaData;
import org.deeplearning4j.zoo.PretrainedType;
import org.deeplearning4j.zoo.ZooModel;
import org.deeplearning4j.zoo.ZooType;
import org.nd4j.linalg.activations.Activation;
import org.nd4j.linalg.api.ndarray.INDArray;
import org.nd4j.linalg.factory.Nd4j;
import org.nd4j.linalg.learning.config.Adam;
import org.nd4j.linalg.learning.config.IUpdater;
import static org.deeplearning4j.zoo.model.helper.DarknetHelper.addLayers;
@AllArgsConstructor
@Builder
public class TinyYOLO extends ZooModel {
@Builder.Default @Getter private int nBoxes = 5;
@Builder.Default @Getter private double[][] priorBoxes = {{1.08, 1.19}, {3.42, 4.41}, {6.63, 11.38}, {9.42, 5.11}, {16.62, 10.52}};
@Builder.Default private long seed = 1234;
@Builder.Default private int[] inputShape = {3, 416, 416};
@Builder.Default private int numClasses = 0;
@Builder.Default private IUpdater updater = new Adam(1e-3);
@Builder.Default private CacheMode cacheMode = CacheMode.NONE;
@Builder.Default private WorkspaceMode workspaceMode = WorkspaceMode.ENABLED;
@Builder.Default private ConvolutionLayer.AlgoMode cudnnAlgoMode = ConvolutionLayer.AlgoMode.PREFER_FASTEST;
private TinyYOLO() {}
@Override
public String pretrainedUrl(PretrainedType pretrainedType) {
if (pretrainedType == PretrainedType.IMAGENET)
return DL4JResources.getURLString("models/tiny-yolo-voc_dl4j_inference.v2.zip");
else
return null;
}
@Override
public long pretrainedChecksum(PretrainedType pretrainedType) {
if (pretrainedType == PretrainedType.IMAGENET)
return 1256226465L;
else
return 0L;
}
@Override
public Class<? extends Model> modelType() {
return ComputationGraph.class;
}
public ComputationGraphConfiguration conf() {
INDArray priors = Nd4j.create(priorBoxes);
GraphBuilder graphBuilder = new NeuralNetConfiguration.Builder()
.seed(seed)
.optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT)
.gradientNormalization(GradientNormalization.RenormalizeL2PerLayer)
.gradientNormalizationThreshold(1.0)
.updater(updater)
.l2(0.00001)
.activation(Activation.IDENTITY)
.cacheMode(cacheMode)
.trainingWorkspaceMode(workspaceMode)
.inferenceWorkspaceMode(workspaceMode)
.cudnnAlgoMode(cudnnAlgoMode)
.graphBuilder()
.addInputs("input")
.setInputTypes(InputType.convolutional(inputShape[2], inputShape[1], inputShape[0]));
addLayers(graphBuilder, 1, 3, inputShape[0], 16, 2, 2);
addLayers(graphBuilder, 2, 3, 16, 32, 2, 2);
addLayers(graphBuilder, 3, 3, 32, 64, 2, 2);
addLayers(graphBuilder, 4, 3, 64, 128, 2, 2);
addLayers(graphBuilder, 5, 3, 128, 256, 2, 2);
addLayers(graphBuilder, 6, 3, 256, 512, 2, 1);
addLayers(graphBuilder, 7, 3, 512, 1024, 0, 0);
addLayers(graphBuilder, 8, 3, 1024, 1024, 0, 0);
int layerNumber = 9;
graphBuilder
.addLayer("convolution2d_" + layerNumber,
new ConvolutionLayer.Builder(1,1)
.nIn(1024)
.nOut(nBoxes * (5 + numClasses))
.weightInit(WeightInit.XAVIER)
.stride(1,1)
.convolutionMode(ConvolutionMode.Same)
.weightInit(WeightInit.RELU)
.activation(Activation.IDENTITY)
.build(),
"activation_" + (layerNumber - 1))
.addLayer("outputs",
new Yolo2OutputLayer.Builder()
.boundingBoxPriors(priors)
.build(),
"convolution2d_" + layerNumber)
.setOutputs("outputs");
return graphBuilder.build();
}
@Override
public ComputationGraph init() {
ComputationGraph model = new ComputationGraph(conf());
model.init();
return model;
}
@Override
public ModelMetaData metaData() {
return new ModelMetaData(new int[][] {inputShape}, 1, ZooType.CNN);
}
@Override
public void setInputShape(int[][] inputShape) {
this.inputShape = inputShape[0];
}
}
@@ -0,0 +1,229 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * 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.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.zoo.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import org.deeplearning4j.common.resources.DL4JResources;
import org.deeplearning4j.nn.api.Model;
import org.deeplearning4j.nn.api.OptimizationAlgorithm;
import org.deeplearning4j.nn.conf.*;
import org.deeplearning4j.nn.conf.distribution.TruncatedNormalDistribution;
import org.deeplearning4j.nn.conf.graph.MergeVertex;
import org.deeplearning4j.nn.conf.inputs.InputType;
import org.deeplearning4j.nn.conf.layers.*;
import org.deeplearning4j.nn.graph.ComputationGraph;
import org.deeplearning4j.nn.weights.WeightInit;
import org.deeplearning4j.zoo.ModelMetaData;
import org.deeplearning4j.zoo.PretrainedType;
import org.deeplearning4j.zoo.ZooModel;
import org.deeplearning4j.zoo.ZooType;
import org.nd4j.linalg.activations.Activation;
import org.nd4j.linalg.learning.config.AdaDelta;
import org.nd4j.linalg.learning.config.IUpdater;
import org.nd4j.linalg.lossfunctions.LossFunctions;
@AllArgsConstructor
@Builder
public class UNet extends ZooModel {
@Builder.Default private long seed = 1234;
@Builder.Default private int[] inputShape = new int[] {3, 512, 512};
@Builder.Default private int numClasses = 0;
@Builder.Default private WeightInit weightInit = WeightInit.RELU;
@Builder.Default private IUpdater updater = new AdaDelta();
@Builder.Default private CacheMode cacheMode = CacheMode.NONE;
@Builder.Default private WorkspaceMode workspaceMode = WorkspaceMode.ENABLED;
@Builder.Default private ConvolutionLayer.AlgoMode cudnnAlgoMode = ConvolutionLayer.AlgoMode.PREFER_FASTEST;
private UNet() {}
@Override
public String pretrainedUrl(PretrainedType pretrainedType) {
if (pretrainedType == PretrainedType.SEGMENT)
return DL4JResources.getURLString("models/unet_dl4j_segment_inference.v1.zip");
else
return null;
}
@Override
public long pretrainedChecksum(PretrainedType pretrainedType) {
if (pretrainedType == PretrainedType.SEGMENT)
return 712347958L;
else
return 0L;
}
@Override
public Class<? extends Model> modelType() {
return ComputationGraph.class;
}
@Override
public ComputationGraph init() {
ComputationGraphConfiguration.GraphBuilder graph = graphBuilder();
graph.addInputs("input").setInputTypes(InputType.convolutional(inputShape[2], inputShape[1], inputShape[0]));
ComputationGraphConfiguration conf = graph.build();
ComputationGraph model = new ComputationGraph(conf);
model.init();
return model;
}
public ComputationGraphConfiguration.GraphBuilder graphBuilder() {
ComputationGraphConfiguration.GraphBuilder graph = new NeuralNetConfiguration.Builder().seed(seed)
.optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT)
.updater(updater)
.weightInit(weightInit)
.l2(5e-5)
.miniBatch(true)
.cacheMode(cacheMode)
.trainingWorkspaceMode(workspaceMode)
.inferenceWorkspaceMode(workspaceMode)
.graphBuilder();
graph
.addLayer("conv1-1", new ConvolutionLayer.Builder(3,3).stride(1,1).nOut(64)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode)
.activation(Activation.RELU).build(), "input")
.addLayer("conv1-2", new ConvolutionLayer.Builder(3,3).stride(1,1).nOut(64)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode)
.activation(Activation.RELU).build(), "conv1-1")
.addLayer("pool1", new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.MAX).kernelSize(2,2)
.build(), "conv1-2")
.addLayer("conv2-1", new ConvolutionLayer.Builder(3,3).stride(1,1).nOut(128)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode)
.activation(Activation.RELU).build(), "pool1")
.addLayer("conv2-2", new ConvolutionLayer.Builder(3,3).stride(1,1).nOut(128)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode)
.activation(Activation.RELU).build(), "conv2-1")
.addLayer("pool2", new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.MAX).kernelSize(2,2)
.build(), "conv2-2")
.addLayer("conv3-1", new ConvolutionLayer.Builder(3,3).stride(1,1).nOut(256)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode)
.activation(Activation.RELU).build(), "pool2")
.addLayer("conv3-2", new ConvolutionLayer.Builder(3,3).stride(1,1).nOut(256)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode)
.activation(Activation.RELU).build(), "conv3-1")
.addLayer("pool3", new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.MAX).kernelSize(2,2)
.build(), "conv3-2")
.addLayer("conv4-1", new ConvolutionLayer.Builder(3,3).stride(1,1).nOut(512)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode)
.activation(Activation.RELU).build(), "pool3")
.addLayer("conv4-2", new ConvolutionLayer.Builder(3,3).stride(1,1).nOut(512)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode)
.activation(Activation.RELU).build(), "conv4-1")
.addLayer("drop4", new DropoutLayer.Builder(0.5).build(), "conv4-2")
.addLayer("pool4", new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.MAX).kernelSize(2,2)
.build(), "drop4")
.addLayer("conv5-1", new ConvolutionLayer.Builder(3,3).stride(1,1).nOut(1024)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode)
.activation(Activation.RELU).build(), "pool4")
.addLayer("conv5-2", new ConvolutionLayer.Builder(3,3).stride(1,1).nOut(1024)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode)
.activation(Activation.RELU).build(), "conv5-1")
.addLayer("drop5", new DropoutLayer.Builder(0.5).build(), "conv5-2")
// up6
.addLayer("up6-1", new Upsampling2D.Builder(2).build(), "drop5")
.addLayer("up6-2", new ConvolutionLayer.Builder(2,2).stride(1,1).nOut(512)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode)
.activation(Activation.RELU).build(), "up6-1")
.addVertex("merge6", new MergeVertex(), "drop4", "up6-2")
.addLayer("conv6-1", new ConvolutionLayer.Builder(3,3).stride(1,1).nOut(512)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode)
.activation(Activation.RELU).build(), "merge6")
.addLayer("conv6-2", new ConvolutionLayer.Builder(3,3).stride(1,1).nOut(512)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode)
.activation(Activation.RELU).build(), "conv6-1")
// up7
.addLayer("up7-1", new Upsampling2D.Builder(2).build(), "conv6-2")
.addLayer("up7-2", new ConvolutionLayer.Builder(2,2).stride(1,1).nOut(256)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode)
.activation(Activation.RELU).build(), "up7-1")
.addVertex("merge7", new MergeVertex(), "conv3-2", "up7-2")
.addLayer("conv7-1", new ConvolutionLayer.Builder(3,3).stride(1,1).nOut(256)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode)
.activation(Activation.RELU).build(), "merge7")
.addLayer("conv7-2", new ConvolutionLayer.Builder(3,3).stride(1,1).nOut(256)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode)
.activation(Activation.RELU).build(), "conv7-1")
// up8
.addLayer("up8-1", new Upsampling2D.Builder(2).build(), "conv7-2")
.addLayer("up8-2", new ConvolutionLayer.Builder(2,2).stride(1,1).nOut(128)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode)
.activation(Activation.RELU).build(), "up8-1")
.addVertex("merge8", new MergeVertex(), "conv2-2", "up8-2")
.addLayer("conv8-1", new ConvolutionLayer.Builder(3,3).stride(1,1).nOut(128)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode)
.activation(Activation.RELU).build(), "merge8")
.addLayer("conv8-2", new ConvolutionLayer.Builder(3,3).stride(1,1).nOut(128)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode)
.activation(Activation.RELU).build(), "conv8-1")
// up9
.addLayer("up9-1", new Upsampling2D.Builder(2).build(), "conv8-2")
.addLayer("up9-2", new ConvolutionLayer.Builder(2,2).stride(1,1).nOut(64)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode)
.activation(Activation.RELU).build(), "up9-1")
.addVertex("merge9", new MergeVertex(), "conv1-2", "up9-2")
.addLayer("conv9-1", new ConvolutionLayer.Builder(3,3).stride(1,1).nOut(64)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode)
.activation(Activation.RELU).build(), "merge9")
.addLayer("conv9-2", new ConvolutionLayer.Builder(3,3).stride(1,1).nOut(64)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode)
.activation(Activation.RELU).build(), "conv9-1")
.addLayer("conv9-3", new ConvolutionLayer.Builder(3,3).stride(1,1).nOut(2)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode)
.activation(Activation.RELU).build(), "conv9-2")
.addLayer("conv10", new ConvolutionLayer.Builder(1,1).stride(1,1).nOut(1)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode)
.activation(Activation.IDENTITY).build(), "conv9-3")
.addLayer("output", new CnnLossLayer.Builder(LossFunctions.LossFunction.XENT)
.activation(Activation.SIGMOID).build(), "conv10")
.setOutputs("output");
return graph;
}
@Override
public ModelMetaData metaData() {
return new ModelMetaData(new int[][] {inputShape}, 1, ZooType.CNN);
}
@Override
public void setInputShape(int[][] inputShape) {
this.inputShape = inputShape[0];
}
}
@@ -0,0 +1,180 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * 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.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.zoo.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import org.deeplearning4j.common.resources.DL4JResources;
import org.deeplearning4j.nn.api.Model;
import org.deeplearning4j.nn.api.OptimizationAlgorithm;
import org.deeplearning4j.nn.conf.CacheMode;
import org.deeplearning4j.nn.conf.ComputationGraphConfiguration;
import org.deeplearning4j.nn.conf.NeuralNetConfiguration;
import org.deeplearning4j.nn.conf.WorkspaceMode;
import org.deeplearning4j.nn.conf.inputs.InputType;
import org.deeplearning4j.nn.conf.layers.ConvolutionLayer;
import org.deeplearning4j.nn.conf.layers.DenseLayer;
import org.deeplearning4j.nn.conf.layers.OutputLayer;
import org.deeplearning4j.nn.conf.layers.SubsamplingLayer;
import org.deeplearning4j.nn.graph.ComputationGraph;
import org.deeplearning4j.zoo.ModelMetaData;
import org.deeplearning4j.zoo.PretrainedType;
import org.deeplearning4j.zoo.ZooModel;
import org.deeplearning4j.zoo.ZooType;
import org.nd4j.linalg.activations.Activation;
import org.nd4j.linalg.learning.config.IUpdater;
import org.nd4j.linalg.learning.config.Nesterovs;
import org.nd4j.linalg.lossfunctions.LossFunctions;
@AllArgsConstructor
@Builder
public class VGG16 extends ZooModel {
@Builder.Default private long seed = 1234;
@Builder.Default private int[] inputShape = new int[] {3, 224, 224};
@Builder.Default private int numClasses = 0;
@Builder.Default private IUpdater updater = new Nesterovs();
@Builder.Default private CacheMode cacheMode = CacheMode.NONE;
@Builder.Default private WorkspaceMode workspaceMode = WorkspaceMode.ENABLED;
@Builder.Default private ConvolutionLayer.AlgoMode cudnnAlgoMode = ConvolutionLayer.AlgoMode.PREFER_FASTEST;
private VGG16() {}
@Override
public String pretrainedUrl(PretrainedType pretrainedType) {
if (pretrainedType == PretrainedType.IMAGENET)
return DL4JResources.getURLString("models/vgg16_dl4j_inference.zip");
else if (pretrainedType == PretrainedType.CIFAR10)
return DL4JResources.getURLString("models/vgg16_dl4j_cifar10_inference.v1.zip");
else if (pretrainedType == PretrainedType.VGGFACE)
return DL4JResources.getURLString("models/vgg16_dl4j_vggface_inference.v1.zip");
else
return null;
}
@Override
public long pretrainedChecksum(PretrainedType pretrainedType) {
if (pretrainedType == PretrainedType.IMAGENET)
return 3501732770L;
if (pretrainedType == PretrainedType.CIFAR10)
return 2192260131L;
if (pretrainedType == PretrainedType.VGGFACE)
return 2706403553L;
else
return 0L;
}
@Override
public Class<? extends Model> modelType() {
return ComputationGraph.class;
}
public ComputationGraphConfiguration conf() {
ComputationGraphConfiguration conf =
new NeuralNetConfiguration.Builder().seed(seed)
.optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT)
.updater(updater)
.activation(Activation.RELU)
.cacheMode(cacheMode)
.trainingWorkspaceMode(workspaceMode)
.inferenceWorkspaceMode(workspaceMode)
.graphBuilder()
.addInputs("in")
// block 1
.layer(0, new ConvolutionLayer.Builder().kernelSize(3, 3).stride(1, 1)
.padding(1, 1).nIn(inputShape[0]).nOut(64)
.cudnnAlgoMode(cudnnAlgoMode).build(), "in")
.layer(1, new ConvolutionLayer.Builder().kernelSize(3, 3).stride(1, 1)
.padding(1, 1).nOut(64).cudnnAlgoMode(cudnnAlgoMode).build(), "0")
.layer(2, new SubsamplingLayer.Builder()
.poolingType(SubsamplingLayer.PoolingType.MAX).kernelSize(2, 2)
.stride(2, 2).build(), "1")
// block 2
.layer(3, new ConvolutionLayer.Builder().kernelSize(3, 3).stride(1, 1)
.padding(1, 1).nOut(128).cudnnAlgoMode(cudnnAlgoMode).build(), "2")
.layer(4, new ConvolutionLayer.Builder().kernelSize(3, 3).stride(1, 1)
.padding(1, 1).nOut(128).cudnnAlgoMode(cudnnAlgoMode).build(), "3")
.layer(5, new SubsamplingLayer.Builder()
.poolingType(SubsamplingLayer.PoolingType.MAX).kernelSize(2, 2)
.stride(2, 2).build(), "4")
// block 3
.layer(6, new ConvolutionLayer.Builder().kernelSize(3, 3).stride(1, 1)
.padding(1, 1).nOut(256).cudnnAlgoMode(cudnnAlgoMode).build(), "5")
.layer(7, new ConvolutionLayer.Builder().kernelSize(3, 3).stride(1, 1)
.padding(1, 1).nOut(256).cudnnAlgoMode(cudnnAlgoMode).build(), "6")
.layer(8, new ConvolutionLayer.Builder().kernelSize(3, 3).stride(1, 1)
.padding(1, 1).nOut(256).cudnnAlgoMode(cudnnAlgoMode).build(), "7")
.layer(9, new SubsamplingLayer.Builder()
.poolingType(SubsamplingLayer.PoolingType.MAX).kernelSize(2, 2)
.stride(2, 2).build(), "8")
// block 4
.layer(10, new ConvolutionLayer.Builder().kernelSize(3, 3).stride(1, 1)
.padding(1, 1).nOut(512).cudnnAlgoMode(cudnnAlgoMode).build(), "9")
.layer(11, new ConvolutionLayer.Builder().kernelSize(3, 3).stride(1, 1)
.padding(1, 1).nOut(512).cudnnAlgoMode(cudnnAlgoMode).build(), "10")
.layer(12, new ConvolutionLayer.Builder().kernelSize(3, 3).stride(1, 1)
.padding(1, 1).nOut(512).cudnnAlgoMode(cudnnAlgoMode).build(), "11")
.layer(13, new SubsamplingLayer.Builder()
.poolingType(SubsamplingLayer.PoolingType.MAX).kernelSize(2, 2)
.stride(2, 2).build(), "12")
// block 5
.layer(14, new ConvolutionLayer.Builder().kernelSize(3, 3).stride(1, 1)
.padding(1, 1).nOut(512).cudnnAlgoMode(cudnnAlgoMode).build(), "13")
.layer(15, new ConvolutionLayer.Builder().kernelSize(3, 3).stride(1, 1)
.padding(1, 1).nOut(512).cudnnAlgoMode(cudnnAlgoMode).build(), "14")
.layer(16, new ConvolutionLayer.Builder().kernelSize(3, 3).stride(1, 1)
.padding(1, 1).nOut(512).cudnnAlgoMode(cudnnAlgoMode).build(), "15")
.layer(17, new SubsamplingLayer.Builder()
.poolingType(SubsamplingLayer.PoolingType.MAX).kernelSize(2, 2)
.stride(2, 2).build(), "16")
.layer(18, new DenseLayer.Builder().nOut(4096).dropOut(0.5)
.build(), "17")
.layer(19, new DenseLayer.Builder().nOut(4096).dropOut(0.5)
.build(), "18")
.layer(20, new OutputLayer.Builder(
LossFunctions.LossFunction.NEGATIVELOGLIKELIHOOD).name("output")
.nOut(numClasses).activation(Activation.SOFTMAX) // radial basis function required
.build(), "19")
.setOutputs("20")
.setInputTypes(InputType.convolutionalFlat(inputShape[2], inputShape[1], inputShape[0]))
.build();
return conf;
}
@Override
public ComputationGraph init() {
ComputationGraph network = new ComputationGraph(conf());
network.init();
return network;
}
@Override
public ModelMetaData metaData() {
return new ModelMetaData(new int[][] {inputShape}, 1, ZooType.CNN);
}
@Override
public void setInputShape(int[][] inputShape) {
this.inputShape = inputShape[0];
}
}
@@ -0,0 +1,174 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * 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.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.zoo.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import org.deeplearning4j.common.resources.DL4JResources;
import org.deeplearning4j.nn.api.Model;
import org.deeplearning4j.nn.api.OptimizationAlgorithm;
import org.deeplearning4j.nn.conf.*;
import org.deeplearning4j.nn.conf.inputs.InputType;
import org.deeplearning4j.nn.conf.layers.ConvolutionLayer;
import org.deeplearning4j.nn.conf.layers.DenseLayer;
import org.deeplearning4j.nn.conf.layers.OutputLayer;
import org.deeplearning4j.nn.conf.layers.SubsamplingLayer;
import org.deeplearning4j.nn.graph.ComputationGraph;
import org.deeplearning4j.nn.multilayer.MultiLayerNetwork;
import org.deeplearning4j.zoo.ModelMetaData;
import org.deeplearning4j.zoo.PretrainedType;
import org.deeplearning4j.zoo.ZooModel;
import org.deeplearning4j.zoo.ZooType;
import org.nd4j.linalg.activations.Activation;
import org.nd4j.linalg.learning.config.IUpdater;
import org.nd4j.linalg.learning.config.Nesterovs;
import org.nd4j.linalg.lossfunctions.LossFunctions;
@AllArgsConstructor
@Builder
public class VGG19 extends ZooModel {
@Builder.Default private long seed = 1234;
@Builder.Default private int[] inputShape = new int[] {3, 224, 224};
@Builder.Default private int numClasses = 0;
@Builder.Default private IUpdater updater = new Nesterovs();
@Builder.Default private CacheMode cacheMode = CacheMode.NONE;
@Builder.Default private WorkspaceMode workspaceMode = WorkspaceMode.ENABLED;
@Builder.Default private ConvolutionLayer.AlgoMode cudnnAlgoMode = ConvolutionLayer.AlgoMode.NO_WORKSPACE;
private VGG19() {}
@Override
public String pretrainedUrl(PretrainedType pretrainedType) {
if (pretrainedType == PretrainedType.IMAGENET)
return DL4JResources.getURLString("models/vgg19_dl4j_inference.zip");
else
return null;
}
@Override
public long pretrainedChecksum(PretrainedType pretrainedType) {
if (pretrainedType == PretrainedType.IMAGENET)
return 2782932419L;
else
return 0L;
}
@Override
public Class<? extends Model> modelType() {
return ComputationGraph.class;
}
public ComputationGraphConfiguration conf() {
ComputationGraphConfiguration conf =
new NeuralNetConfiguration.Builder().seed(seed)
.optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT)
.updater(updater)
.activation(Activation.RELU)
.cacheMode(cacheMode)
.trainingWorkspaceMode(workspaceMode)
.inferenceWorkspaceMode(workspaceMode)
.graphBuilder()
.addInputs("in")
// block 1
.layer(0, new ConvolutionLayer.Builder().kernelSize(3, 3).stride(1, 1)
.padding(1, 1).nIn(inputShape[0]).nOut(64)
.cudnnAlgoMode(cudnnAlgoMode).build(), "in")
.layer(1, new ConvolutionLayer.Builder().kernelSize(3, 3).stride(1, 1)
.padding(1, 1).nOut(64).cudnnAlgoMode(cudnnAlgoMode).build(), "0")
.layer(2, new SubsamplingLayer.Builder()
.poolingType(SubsamplingLayer.PoolingType.MAX).kernelSize(2, 2)
.stride(2, 2).build(), "1")
// block 2
.layer(3, new ConvolutionLayer.Builder().kernelSize(3, 3).stride(1, 1)
.padding(1, 1).nOut(128).cudnnAlgoMode(cudnnAlgoMode).build(), "2")
.layer(4, new ConvolutionLayer.Builder().kernelSize(3, 3).stride(1, 1)
.padding(1, 1).nOut(128).cudnnAlgoMode(cudnnAlgoMode).build(), "3")
.layer(5, new SubsamplingLayer.Builder()
.poolingType(SubsamplingLayer.PoolingType.MAX).kernelSize(2, 2)
.stride(2, 2).build(), "4")
// block 3
.layer(6, new ConvolutionLayer.Builder().kernelSize(3, 3).stride(1, 1)
.padding(1, 1).nOut(256).cudnnAlgoMode(cudnnAlgoMode).build(), "5")
.layer(7, new ConvolutionLayer.Builder().kernelSize(3, 3).stride(1, 1)
.padding(1, 1).nOut(256).cudnnAlgoMode(cudnnAlgoMode).build(), "6")
.layer(8, new ConvolutionLayer.Builder().kernelSize(3, 3).stride(1, 1)
.padding(1, 1).nOut(256).cudnnAlgoMode(cudnnAlgoMode).build(), "7")
.layer(9, new ConvolutionLayer.Builder().kernelSize(3, 3).stride(1, 1)
.padding(1, 1).nOut(256).cudnnAlgoMode(cudnnAlgoMode).build(), "8")
.layer(10, new SubsamplingLayer.Builder()
.poolingType(SubsamplingLayer.PoolingType.MAX).kernelSize(2, 2)
.stride(2, 2).build(), "9")
// block 4
.layer(11, new ConvolutionLayer.Builder().kernelSize(3, 3).stride(1, 1)
.padding(1, 1).nOut(512).cudnnAlgoMode(cudnnAlgoMode).build(), "10")
.layer(12, new ConvolutionLayer.Builder().kernelSize(3, 3).stride(1, 1)
.padding(1, 1).nOut(512).cudnnAlgoMode(cudnnAlgoMode).build(), "11")
.layer(13, new ConvolutionLayer.Builder().kernelSize(3, 3).stride(1, 1)
.padding(1, 1).nOut(512).cudnnAlgoMode(cudnnAlgoMode).build(), "12")
.layer(14, new ConvolutionLayer.Builder().kernelSize(3, 3).stride(1, 1)
.padding(1, 1).nOut(512).cudnnAlgoMode(cudnnAlgoMode).build(), "13")
.layer(15, new SubsamplingLayer.Builder()
.poolingType(SubsamplingLayer.PoolingType.MAX).kernelSize(2, 2)
.stride(2, 2).build(), "14")
// block 5
.layer(16, new ConvolutionLayer.Builder().kernelSize(3, 3).stride(1, 1)
.padding(1, 1).nOut(512).cudnnAlgoMode(cudnnAlgoMode).build(), "15")
.layer(17, new ConvolutionLayer.Builder().kernelSize(3, 3).stride(1, 1)
.padding(1, 1).nOut(512).cudnnAlgoMode(cudnnAlgoMode).build(), "16")
.layer(18, new ConvolutionLayer.Builder().kernelSize(3, 3).stride(1, 1)
.padding(1, 1).nOut(512).cudnnAlgoMode(cudnnAlgoMode).build(), "17")
.layer(19, new ConvolutionLayer.Builder().kernelSize(3, 3).stride(1, 1)
.padding(1, 1).nOut(512).cudnnAlgoMode(cudnnAlgoMode).build(), "18")
.layer(20, new SubsamplingLayer.Builder()
.poolingType(SubsamplingLayer.PoolingType.MAX).kernelSize(2, 2)
.stride(2, 2).build(), "19")
.layer(21, new DenseLayer.Builder().nOut(4096).build(), "20")
.layer(22, new OutputLayer.Builder(
LossFunctions.LossFunction.NEGATIVELOGLIKELIHOOD).name("output")
.nOut(numClasses).activation(Activation.SOFTMAX) // radial basis function required
.build(), "21")
.setOutputs("22")
.setInputTypes(InputType.convolutionalFlat(inputShape[2], inputShape[1], inputShape[0]))
.build();
return conf;
}
@Override
public ComputationGraph init() {
ComputationGraph network = new ComputationGraph(conf());
network.init();
return network;
}
@Override
public ModelMetaData metaData() {
return new ModelMetaData(new int[][] {inputShape}, 1, ZooType.CNN);
}
@Override
public void setInputShape(int[][] inputShape) {
this.inputShape = inputShape[0];
}
}
@@ -0,0 +1,252 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * 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.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.zoo.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import org.deeplearning4j.common.resources.DL4JResources;
import org.deeplearning4j.nn.api.Model;
import org.deeplearning4j.nn.api.OptimizationAlgorithm;
import org.deeplearning4j.nn.conf.*;
import org.deeplearning4j.nn.conf.distribution.NormalDistribution;
import org.deeplearning4j.nn.conf.graph.ElementWiseVertex;
import org.deeplearning4j.nn.conf.inputs.InputType;
import org.deeplearning4j.nn.conf.layers.*;
import org.deeplearning4j.nn.graph.ComputationGraph;
import org.deeplearning4j.nn.weights.WeightInit;
import org.deeplearning4j.zoo.ModelMetaData;
import org.deeplearning4j.zoo.PretrainedType;
import org.deeplearning4j.zoo.ZooModel;
import org.deeplearning4j.zoo.ZooType;
import org.nd4j.linalg.activations.Activation;
import org.nd4j.linalg.learning.config.AdaDelta;
import org.nd4j.linalg.learning.config.AdaGrad;
import org.nd4j.linalg.learning.config.IUpdater;
import org.nd4j.linalg.lossfunctions.LossFunctions;
@AllArgsConstructor
@Builder
public class Xception extends ZooModel {
@Builder.Default private long seed = 1234;
@Builder.Default private int[] inputShape = new int[] {3, 299, 299};
@Builder.Default private int numClasses = 0;
@Builder.Default private WeightInit weightInit = WeightInit.RELU;
@Builder.Default private IUpdater updater = new AdaDelta();
@Builder.Default private CacheMode cacheMode = CacheMode.NONE;
@Builder.Default private WorkspaceMode workspaceMode = WorkspaceMode.ENABLED;
@Builder.Default private ConvolutionLayer.AlgoMode cudnnAlgoMode = ConvolutionLayer.AlgoMode.PREFER_FASTEST;
private Xception() {}
@Override
public String pretrainedUrl(PretrainedType pretrainedType) {
if (pretrainedType == PretrainedType.IMAGENET)
return DL4JResources.getURLString("models/xception_dl4j_inference.v2.zip");
else
return null;
}
@Override
public long pretrainedChecksum(PretrainedType pretrainedType) {
if (pretrainedType == PretrainedType.IMAGENET)
return 3277876097L;
else
return 0L;
}
@Override
public Class<? extends Model> modelType() {
return ComputationGraph.class;
}
@Override
public ComputationGraph init() {
ComputationGraphConfiguration.GraphBuilder graph = graphBuilder();
graph.addInputs("input").setInputTypes(InputType.convolutional(inputShape[2], inputShape[1], inputShape[0]));
ComputationGraphConfiguration conf = graph.build();
ComputationGraph model = new ComputationGraph(conf);
model.init();
return model;
}
public ComputationGraphConfiguration.GraphBuilder graphBuilder() {
ComputationGraphConfiguration.GraphBuilder graph = new NeuralNetConfiguration.Builder().seed(seed)
.optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT)
.updater(updater)
.weightInit(weightInit)
.l2(4e-5)
.miniBatch(true)
.cacheMode(cacheMode)
.trainingWorkspaceMode(workspaceMode)
.inferenceWorkspaceMode(workspaceMode)
.convolutionMode(ConvolutionMode.Truncate)
.graphBuilder();
graph
// block1
.addLayer("block1_conv1", new ConvolutionLayer.Builder(3,3).stride(2,2).nOut(32).hasBias(false)
.cudnnAlgoMode(cudnnAlgoMode).build(), "input")
.addLayer("block1_conv1_bn", new BatchNormalization(), "block1_conv1")
.addLayer("block1_conv1_act", new ActivationLayer(Activation.RELU), "block1_conv1_bn")
.addLayer("block1_conv2", new ConvolutionLayer.Builder(3,3).stride(1,1).nOut(64).hasBias(false)
.cudnnAlgoMode(cudnnAlgoMode).build(), "block1_conv1_act")
.addLayer("block1_conv2_bn", new BatchNormalization(), "block1_conv2")
.addLayer("block1_conv2_act", new ActivationLayer(Activation.RELU), "block1_conv2_bn")
// residual1
.addLayer("residual1_conv", new ConvolutionLayer.Builder(1,1).stride(2,2).nOut(128).hasBias(false)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode).build(), "block1_conv2_act")
.addLayer("residual1", new BatchNormalization(), "residual1_conv")
// block2
.addLayer("block2_sepconv1", new SeparableConvolution2D.Builder(3,3).nOut(128).hasBias(false)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode).build(), "block1_conv2_act")
.addLayer("block2_sepconv1_bn", new BatchNormalization(), "block2_sepconv1")
.addLayer("block2_sepconv1_act",new ActivationLayer(Activation.RELU), "block2_sepconv1_bn")
.addLayer("block2_sepconv2", new SeparableConvolution2D.Builder(3,3).nOut(128).hasBias(false)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode).build(), "block2_sepconv1_act")
.addLayer("block2_sepconv2_bn", new BatchNormalization(), "block2_sepconv2")
.addLayer("block2_pool", new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.MAX).kernelSize(3,3).stride(2,2)
.convolutionMode(ConvolutionMode.Same).build(), "block2_sepconv2_bn")
.addVertex("add1", new ElementWiseVertex(ElementWiseVertex.Op.Add), "block2_pool", "residual1")
// residual2
.addLayer("residual2_conv", new ConvolutionLayer.Builder(1,1).stride(2,2).nOut(256).hasBias(false)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode).build(), "add1")
.addLayer("residual2", new BatchNormalization(), "residual2_conv")
// block3
.addLayer("block3_sepconv1_act", new ActivationLayer(Activation.RELU), "add1")
.addLayer("block3_sepconv1", new SeparableConvolution2D.Builder(3,3).nOut(256).hasBias(false)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode).build(), "block3_sepconv1_act")
.addLayer("block3_sepconv1_bn", new BatchNormalization(), "block3_sepconv1")
.addLayer("block3_sepconv2_act", new ActivationLayer(Activation.RELU), "block3_sepconv1_bn")
.addLayer("block3_sepconv2", new SeparableConvolution2D.Builder(3,3).nOut(256).hasBias(false)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode).build(), "block3_sepconv2_act")
.addLayer("block3_sepconv2_bn", new BatchNormalization(), "block3_sepconv2")
.addLayer("block3_pool", new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.MAX).kernelSize(3,3).stride(2,2)
.convolutionMode(ConvolutionMode.Same).build(), "block3_sepconv2_bn")
.addVertex("add2", new ElementWiseVertex(ElementWiseVertex.Op.Add), "block3_pool", "residual2")
// residual3
.addLayer("residual3_conv", new ConvolutionLayer.Builder(1,1).stride(2,2).nOut(728).hasBias(false)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode).build(), "add2")
.addLayer("residual3", new BatchNormalization(), "residual3_conv")
// block4
.addLayer("block4_sepconv1_act", new ActivationLayer(Activation.RELU), "add2")
.addLayer("block4_sepconv1", new SeparableConvolution2D.Builder(3,3).nOut(728).hasBias(false)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode).build(), "block4_sepconv1_act")
.addLayer("block4_sepconv1_bn", new BatchNormalization(), "block4_sepconv1")
.addLayer("block4_sepconv2_act", new ActivationLayer(Activation.RELU), "block4_sepconv1_bn")
.addLayer("block4_sepconv2", new SeparableConvolution2D.Builder(3,3).nOut(728).hasBias(false)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode).build(), "block4_sepconv2_act")
.addLayer("block4_sepconv2_bn", new BatchNormalization(), "block4_sepconv2")
.addLayer("block4_pool", new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.MAX).kernelSize(3,3).stride(2,2)
.convolutionMode(ConvolutionMode.Same).build(), "block4_sepconv2_bn")
.addVertex("add3", new ElementWiseVertex(ElementWiseVertex.Op.Add), "block4_pool", "residual3");
// towers
int residual = 3;
int block = 5;
for(int i = 0; i < 8; i++) {
String previousInput = "add"+residual;
String blockName = "block"+block;
graph
.addLayer(blockName+"_sepconv1_act", new ActivationLayer(Activation.RELU), previousInput)
.addLayer(blockName+"_sepconv1", new SeparableConvolution2D.Builder(3,3).nOut(728).hasBias(false)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode).build(), blockName+"_sepconv1_act")
.addLayer(blockName+"_sepconv1_bn", new BatchNormalization(), blockName+"_sepconv1")
.addLayer(blockName+"_sepconv2_act", new ActivationLayer(Activation.RELU), blockName+"_sepconv1_bn")
.addLayer(blockName+"_sepconv2", new SeparableConvolution2D.Builder(3,3).nOut(728).hasBias(false)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode).build(), blockName+"_sepconv2_act")
.addLayer(blockName+"_sepconv2_bn", new BatchNormalization(), blockName+"_sepconv2")
.addLayer(blockName+"_sepconv3_act", new ActivationLayer(Activation.RELU), blockName+"_sepconv2_bn")
.addLayer(blockName+"_sepconv3", new SeparableConvolution2D.Builder(3,3).nOut(728).hasBias(false)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode).build(), blockName+"_sepconv3_act")
.addLayer(blockName+"_sepconv3_bn", new BatchNormalization(), blockName+"_sepconv3")
.addVertex("add"+(residual+1), new ElementWiseVertex(ElementWiseVertex.Op.Add), blockName+"_sepconv3_bn", previousInput);
residual++;
block++;
}
// residual12
graph.addLayer("residual12_conv", new ConvolutionLayer.Builder(1,1).stride(2,2).nOut(1024).hasBias(false)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode).build(), "add" + residual)
.addLayer("residual12", new BatchNormalization(), "residual12_conv");
// block13
graph
.addLayer("block13_sepconv1_act", new ActivationLayer(Activation.RELU), "add11" )
.addLayer("block13_sepconv1", new SeparableConvolution2D.Builder(3,3).nOut(728).hasBias(false)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode).build(), "block13_sepconv1_act")
.addLayer("block13_sepconv1_bn", new BatchNormalization(), "block13_sepconv1")
.addLayer("block13_sepconv2_act", new ActivationLayer(Activation.RELU), "block13_sepconv1_bn")
.addLayer("block13_sepconv2", new SeparableConvolution2D.Builder(3,3).nOut(1024).hasBias(false)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode).build(), "block13_sepconv2_act")
.addLayer("block13_sepconv2_bn", new BatchNormalization(), "block13_sepconv2")
.addLayer("block13_pool", new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.MAX).kernelSize(3,3).stride(2,2)
.convolutionMode(ConvolutionMode.Same).build(), "block13_sepconv2_bn")
.addVertex("add12", new ElementWiseVertex(ElementWiseVertex.Op.Add), "block13_pool", "residual12");
// block14
graph
.addLayer("block14_sepconv1", new SeparableConvolution2D.Builder(3,3).nOut(1536).hasBias(false)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode).build(), "add12")
.addLayer("block14_sepconv1_bn", new BatchNormalization(), "block14_sepconv1")
.addLayer("block14_sepconv1_act", new ActivationLayer(Activation.RELU), "block14_sepconv1_bn")
.addLayer("block14_sepconv2", new SeparableConvolution2D.Builder(3,3).nOut(2048).hasBias(false)
.convolutionMode(ConvolutionMode.Same).cudnnAlgoMode(cudnnAlgoMode).build(), "block14_sepconv1_act")
.addLayer("block14_sepconv2_bn", new BatchNormalization(), "block14_sepconv2")
.addLayer("block14_sepconv2_act", new ActivationLayer(Activation.RELU), "block14_sepconv2_bn")
.addLayer("avg_pool", new GlobalPoolingLayer.Builder(PoolingType.AVG).build(), "block14_sepconv2_act")
.addLayer("predictions", new OutputLayer.Builder(LossFunctions.LossFunction.MCXENT)
.nOut(numClasses)
.activation(Activation.SOFTMAX).build(), "avg_pool")
.setOutputs("predictions")
;
return graph;
}
@Override
public ModelMetaData metaData() {
return new ModelMetaData(new int[][] {inputShape}, 1, ZooType.CNN);
}
@Override
public void setInputShape(int[][] inputShape) {
this.inputShape = inputShape[0];
}
}
@@ -0,0 +1,192 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * 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.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.zoo.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import org.deeplearning4j.common.resources.DL4JResources;
import org.deeplearning4j.nn.api.Model;
import org.deeplearning4j.nn.api.OptimizationAlgorithm;
import org.deeplearning4j.nn.conf.*;
import org.deeplearning4j.nn.conf.ComputationGraphConfiguration.GraphBuilder;
import org.deeplearning4j.nn.conf.graph.MergeVertex;
import org.deeplearning4j.nn.conf.inputs.InputType;
import org.deeplearning4j.nn.conf.layers.ConvolutionLayer;
import org.deeplearning4j.nn.conf.layers.SpaceToDepthLayer;
import org.deeplearning4j.nn.conf.layers.objdetect.Yolo2OutputLayer;
import org.deeplearning4j.nn.graph.ComputationGraph;
import org.deeplearning4j.nn.weights.WeightInit;
import org.deeplearning4j.zoo.ModelMetaData;
import org.deeplearning4j.zoo.PretrainedType;
import org.deeplearning4j.zoo.ZooModel;
import org.deeplearning4j.zoo.ZooType;
import org.nd4j.linalg.activations.Activation;
import org.nd4j.linalg.api.ndarray.INDArray;
import org.nd4j.linalg.factory.Nd4j;
import org.nd4j.linalg.learning.config.Adam;
import org.nd4j.linalg.learning.config.IUpdater;
import static org.deeplearning4j.zoo.model.helper.DarknetHelper.addLayers;
@AllArgsConstructor
@Builder
public class YOLO2 extends ZooModel {
/**
* Default prior boxes for the model
*/
public static final double[][] DEFAULT_PRIOR_BOXES = {{0.57273, 0.677385}, {1.87446, 2.06253}, {3.33843, 5.47434}, {7.88282, 3.52778}, {9.77052, 9.16828}};
@Builder.Default @Getter private int nBoxes = 5;
@Builder.Default @Getter private double[][] priorBoxes = DEFAULT_PRIOR_BOXES;
@Builder.Default private long seed = 1234;
@Builder.Default private int[] inputShape = {3, 608, 608};
@Builder.Default private int numClasses = 0;
@Builder.Default private IUpdater updater = new Adam(1e-3);
@Builder.Default private CacheMode cacheMode = CacheMode.NONE;
@Builder.Default private WorkspaceMode workspaceMode = WorkspaceMode.ENABLED;
@Builder.Default private ConvolutionLayer.AlgoMode cudnnAlgoMode = ConvolutionLayer.AlgoMode.PREFER_FASTEST;
private YOLO2() {}
@Override
public String pretrainedUrl(PretrainedType pretrainedType) {
if (pretrainedType == PretrainedType.IMAGENET)
return DL4JResources.getURLString("models/yolo2_dl4j_inference.v3.zip");
else
return null;
}
@Override
public long pretrainedChecksum(PretrainedType pretrainedType) {
if (pretrainedType == PretrainedType.IMAGENET)
return 3658373840L;
else
return 0L;
}
@Override
public Class<? extends Model> modelType() {
return ComputationGraph.class;
}
public ComputationGraphConfiguration conf() {
INDArray priors = Nd4j.create(priorBoxes);
GraphBuilder graphBuilder = new NeuralNetConfiguration.Builder()
.seed(seed)
.optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT)
.gradientNormalization(GradientNormalization.RenormalizeL2PerLayer)
.gradientNormalizationThreshold(1.0)
.updater(updater)
.l2(0.00001)
.activation(Activation.IDENTITY)
.cacheMode(cacheMode)
.trainingWorkspaceMode(workspaceMode)
.inferenceWorkspaceMode(workspaceMode)
.cudnnAlgoMode(cudnnAlgoMode)
.graphBuilder()
.addInputs("input")
.setInputTypes(InputType.convolutional(inputShape[2], inputShape[1], inputShape[0]));
addLayers(graphBuilder, 1, 3, inputShape[0], 32, 2);
addLayers(graphBuilder, 2, 3, 32, 64, 2);
addLayers(graphBuilder, 3, 3, 64, 128, 0);
addLayers(graphBuilder, 4, 1, 128, 64, 0);
addLayers(graphBuilder, 5, 3, 64, 128, 2);
addLayers(graphBuilder, 6, 3, 128, 256, 0);
addLayers(graphBuilder, 7, 1, 256, 128, 0);
addLayers(graphBuilder, 8, 3, 128, 256, 2);
addLayers(graphBuilder, 9, 3, 256, 512, 0);
addLayers(graphBuilder, 10, 1, 512, 256, 0);
addLayers(graphBuilder, 11, 3, 256, 512, 0);
addLayers(graphBuilder, 12, 1, 512, 256, 0);
addLayers(graphBuilder, 13, 3, 256, 512, 2);
addLayers(graphBuilder, 14, 3, 512, 1024, 0);
addLayers(graphBuilder, 15, 1, 1024, 512, 0);
addLayers(graphBuilder, 16, 3, 512, 1024, 0);
addLayers(graphBuilder, 17, 1, 1024, 512, 0);
addLayers(graphBuilder, 18, 3, 512, 1024, 0);
// #######
addLayers(graphBuilder, 19, 3, 1024, 1024, 0);
addLayers(graphBuilder, 20, 3, 1024, 1024, 0);
// route
addLayers(graphBuilder, 21, "activation_13", 1, 512, 64, 0, 0);
// reorg
graphBuilder.addLayer("rearrange_21",new SpaceToDepthLayer.Builder(2).build(), "activation_21")
// route
.addVertex("concatenate_21", new MergeVertex(),
"rearrange_21", "activation_20");
addLayers(graphBuilder, 22, "concatenate_21", 3, 1024 + 256, 1024, 0, 0);
graphBuilder
.addLayer("convolution2d_23",
new ConvolutionLayer.Builder(1,1)
.nIn(1024)
.nOut(nBoxes * (5 + numClasses))
.weightInit(WeightInit.XAVIER)
.stride(1,1)
.convolutionMode(ConvolutionMode.Same)
.weightInit(WeightInit.RELU)
.activation(Activation.IDENTITY)
.cudnnAlgoMode(cudnnAlgoMode)
.build(),
"activation_22")
.addLayer("outputs",
new Yolo2OutputLayer.Builder()
.boundingBoxPriors(priors)
.build(),
"convolution2d_23")
.setOutputs("outputs");
return graphBuilder.build();
}
@Override
public ComputationGraph init() {
ComputationGraph model = new ComputationGraph(conf());
model.init();
return model;
}
@Override
public ModelMetaData metaData() {
return new ModelMetaData(new int[][] {inputShape}, 1, ZooType.CNN);
}
@Override
public void setInputShape(int[][] inputShape) {
this.inputShape = inputShape[0];
}
}
@@ -0,0 +1,106 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * 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.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.zoo.model.helper;
import org.deeplearning4j.nn.conf.ComputationGraphConfiguration;
import org.deeplearning4j.nn.conf.ConvolutionMode;
import org.deeplearning4j.nn.conf.layers.ActivationLayer;
import org.deeplearning4j.nn.conf.layers.BatchNormalization;
import org.deeplearning4j.nn.conf.layers.ConvolutionLayer;
import org.deeplearning4j.nn.conf.layers.SubsamplingLayer;
import org.deeplearning4j.nn.weights.WeightInit;
import org.deeplearning4j.zoo.model.Darknet19;
import org.deeplearning4j.zoo.model.TinyYOLO;
import org.deeplearning4j.zoo.model.YOLO2;
import org.nd4j.linalg.activations.Activation;
import org.nd4j.linalg.activations.impl.ActivationLReLU;
public class DarknetHelper {
/** Returns {@code inputShape[1] / 32}, where {@code inputShape[1]} should be a multiple of 32. */
public static int getGridWidth(int[] inputShape) {
return inputShape[1] / 32;
}
/** Returns {@code inputShape[2] / 32}, where {@code inputShape[2]} should be a multiple of 32. */
public static int getGridHeight(int[] inputShape) {
return inputShape[2] / 32;
}
public static ComputationGraphConfiguration.GraphBuilder addLayers(ComputationGraphConfiguration.GraphBuilder graphBuilder, int layerNumber, int filterSize, int nIn, int nOut, int poolSize) {
return addLayers(graphBuilder, layerNumber, filterSize, nIn, nOut, poolSize, poolSize);
}
public static ComputationGraphConfiguration.GraphBuilder addLayers(ComputationGraphConfiguration.GraphBuilder graphBuilder, int layerNumber, int filterSize, int nIn, int nOut, int poolSize, int poolStride) {
String input = "maxpooling2d_" + (layerNumber - 1);
if (!graphBuilder.getVertices().containsKey(input)) {
input = "activation_" + (layerNumber - 1);
}
if (!graphBuilder.getVertices().containsKey(input)) {
input = "concatenate_" + (layerNumber - 1);
}
if (!graphBuilder.getVertices().containsKey(input)) {
input = "input";
}
return addLayers(graphBuilder, layerNumber, input, filterSize, nIn, nOut, poolSize, poolStride);
}
public static ComputationGraphConfiguration.GraphBuilder addLayers(ComputationGraphConfiguration.GraphBuilder graphBuilder, int layerNumber, String input, int filterSize, int nIn, int nOut, int poolSize, int poolStride) {
graphBuilder
.addLayer("convolution2d_" + layerNumber,
new ConvolutionLayer.Builder(filterSize,filterSize)
.nIn(nIn)
.nOut(nOut)
.weightInit(WeightInit.XAVIER)
.convolutionMode(ConvolutionMode.Same)
.hasBias(false)
.stride(1,1)
.activation(Activation.IDENTITY)
.build(),
input)
.addLayer("batchnormalization_" + layerNumber,
new BatchNormalization.Builder()
.nIn(nOut).nOut(nOut)
.weightInit(WeightInit.XAVIER)
.activation(Activation.IDENTITY)
.build(),
"convolution2d_" + layerNumber)
.addLayer("activation_" + layerNumber,
new ActivationLayer.Builder()
.activation(new ActivationLReLU(0.1))
.build(),
"batchnormalization_" + layerNumber);
if (poolSize > 0) {
graphBuilder
.addLayer("maxpooling2d_" + layerNumber,
new SubsamplingLayer.Builder()
.kernelSize(poolSize, poolSize)
.stride(poolStride, poolStride)
.convolutionMode(ConvolutionMode.Same)
.build(),
"activation_" + layerNumber);
}
return graphBuilder;
}
}
@@ -0,0 +1,253 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * 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.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.zoo.model.helper;
import org.deeplearning4j.nn.conf.ComputationGraphConfiguration;
import org.deeplearning4j.nn.conf.graph.MergeVertex;
import org.deeplearning4j.nn.conf.layers.*;
import org.nd4j.linalg.activations.Activation;
public class FaceNetHelper {
public static String getModuleName() {
return "inception";
}
public static String getModuleName(String layerName) {
return getModuleName() + "-" + layerName;
}
public static ConvolutionLayer conv1x1(int in, int out, double bias) {
return new ConvolutionLayer.Builder(new int[] {1, 1}, new int[] {1, 1}, new int[] {0, 0}).nIn(in).nOut(out)
.biasInit(bias).cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE).build();
}
public static ConvolutionLayer c3x3reduce(int in, int out, double bias) {
return conv1x1(in, out, bias);
}
public static ConvolutionLayer c5x5reduce(int in, int out, double bias) {
return conv1x1(in, out, bias);
}
public static ConvolutionLayer conv3x3(int in, int out, double bias) {
return new ConvolutionLayer.Builder(new int[] {3, 3}, new int[] {1, 1}, new int[] {1, 1}).nIn(in).nOut(out)
.biasInit(bias).build();
}
public static ConvolutionLayer conv5x5(int in, int out, double bias) {
return new ConvolutionLayer.Builder(new int[] {5, 5}, new int[] {1, 1}, new int[] {2, 2}).nIn(in).nOut(out)
.biasInit(bias).cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE).build();
}
public static ConvolutionLayer conv7x7(int in, int out, double bias) {
return new ConvolutionLayer.Builder(new int[] {7, 7}, new int[] {2, 2}, new int[] {3, 3}).nIn(in).nOut(out)
.biasInit(bias).cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE).build();
}
public static SubsamplingLayer avgPool7x7(int stride) {
return new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.AVG, new int[] {7, 7}, new int[] {1, 1})
.build();
}
public static SubsamplingLayer avgPoolNxN(int size, int stride) {
return new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.AVG, new int[] {size, size},
new int[] {stride, stride}).build();
}
public static SubsamplingLayer pNormNxN(int pNorm, int size, int stride) {
return new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.PNORM, new int[] {size, size},
new int[] {stride, stride}).pnorm(pNorm).build();
}
public static SubsamplingLayer maxPool3x3(int stride) {
return new SubsamplingLayer.Builder(new int[] {3, 3}, new int[] {stride, stride}, new int[] {1, 1}).build();
}
public static SubsamplingLayer maxPoolNxN(int size, int stride) {
return new SubsamplingLayer.Builder(new int[] {size, size}, new int[] {stride, stride}, new int[] {1, 1})
.build();
}
public static DenseLayer fullyConnected(int in, int out, double dropOut) {
return new DenseLayer.Builder().nIn(in).nOut(out).dropOut(dropOut).build();
}
public static ConvolutionLayer convNxN(int reduceSize, int outputSize, int kernelSize, int kernelStride,
boolean padding) {
int pad = padding ? ((int) Math.floor(kernelStride / 2) * 2) : 0;
return new ConvolutionLayer.Builder(new int[] {kernelSize, kernelSize}, new int[] {kernelStride, kernelStride},
new int[] {pad, pad}).nIn(reduceSize).nOut(outputSize).biasInit(0.2)
.cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE).build();
}
public static ConvolutionLayer convNxNreduce(int inputSize, int reduceSize, int reduceStride) {
return new ConvolutionLayer.Builder(new int[] {1, 1}, new int[] {reduceStride, reduceStride}).nIn(inputSize)
.nOut(reduceSize).biasInit(0.2).cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE).build();
}
public static BatchNormalization batchNorm(int in, int out) {
return new BatchNormalization.Builder(false).nIn(in).nOut(out).build();
}
public static ComputationGraphConfiguration.GraphBuilder appendGraph(
ComputationGraphConfiguration.GraphBuilder graph, String moduleLayerName, int inputSize,
int[] kernelSize, int[] kernelStride, int[] outputSize, int[] reduceSize,
SubsamplingLayer.PoolingType poolingType, Activation transferFunction, String inputLayer) {
return appendGraph(graph, moduleLayerName, inputSize, kernelSize, kernelStride, outputSize, reduceSize,
poolingType, 0, 3, 1, transferFunction, inputLayer);
}
public static ComputationGraphConfiguration.GraphBuilder appendGraph(
ComputationGraphConfiguration.GraphBuilder graph, String moduleLayerName, int inputSize,
int[] kernelSize, int[] kernelStride, int[] outputSize, int[] reduceSize,
SubsamplingLayer.PoolingType poolingType, int pNorm, Activation transferFunction,
String inputLayer) {
return appendGraph(graph, moduleLayerName, inputSize, kernelSize, kernelStride, outputSize, reduceSize,
poolingType, pNorm, 3, 1, transferFunction, inputLayer);
}
public static ComputationGraphConfiguration.GraphBuilder appendGraph(
ComputationGraphConfiguration.GraphBuilder graph, String moduleLayerName, int inputSize,
int[] kernelSize, int[] kernelStride, int[] outputSize, int[] reduceSize,
SubsamplingLayer.PoolingType poolingType, int poolSize, int poolStride, Activation transferFunction,
String inputLayer) {
return appendGraph(graph, moduleLayerName, inputSize, kernelSize, kernelStride, outputSize, reduceSize,
poolingType, 0, poolSize, poolStride, transferFunction, inputLayer);
}
/**
* Appends inception layer configurations a GraphBuilder object, based on the concept of
* Inception via the GoogleLeNet paper: https://arxiv.org/abs/1409.4842
*
* @param graph An existing computation graph GraphBuilder object.
* @param moduleLayerName The numerical order of inception (like 2, 2a, 3e, etc.)
* @param inputSize
* @param kernelSize
* @param kernelStride
* @param outputSize
* @param reduceSize
* @param poolingType
* @param poolSize
* @param poolStride
* @param inputLayer
* @return
*/
public static ComputationGraphConfiguration.GraphBuilder appendGraph(
ComputationGraphConfiguration.GraphBuilder graph, String moduleLayerName, int inputSize,
int[] kernelSize, int[] kernelStride, int[] outputSize, int[] reduceSize,
SubsamplingLayer.PoolingType poolingType, int pNorm, int poolSize, int poolStride,
Activation transferFunction, String inputLayer) {
// 1x1 reduce -> nxn conv
for (int i = 0; i < kernelSize.length; i++) {
graph.addLayer(getModuleName(moduleLayerName) + "-cnn1-" + i, conv1x1(inputSize, reduceSize[i], 0.2),
inputLayer);
graph.addLayer(getModuleName(moduleLayerName) + "-batch1-" + i, batchNorm(reduceSize[i], reduceSize[i]),
getModuleName(moduleLayerName) + "-cnn1-" + i);
graph.addLayer(getModuleName(moduleLayerName) + "-transfer1-" + i,
new ActivationLayer.Builder().activation(transferFunction).build(),
getModuleName(moduleLayerName) + "-batch1-" + i);
graph.addLayer(getModuleName(moduleLayerName) + "-reduce1-" + i,
convNxN(reduceSize[i], outputSize[i], kernelSize[i], kernelStride[i], true),
getModuleName(moduleLayerName) + "-transfer1-" + i);
graph.addLayer(getModuleName(moduleLayerName) + "-batch2-" + i, batchNorm(outputSize[i], outputSize[i]),
getModuleName(moduleLayerName) + "-reduce1-" + i);
graph.addLayer(getModuleName(moduleLayerName) + "-transfer2-" + i,
new ActivationLayer.Builder().activation(transferFunction).build(),
getModuleName(moduleLayerName) + "-batch2-" + i);
}
// pool -> 1x1 conv
int i = kernelSize.length;
try {
int checkIndex = reduceSize[i];
switch (poolingType) {
case AVG:
graph.addLayer(getModuleName(moduleLayerName) + "-pool1", avgPoolNxN(poolSize, poolStride),
inputLayer);
break;
case MAX:
graph.addLayer(getModuleName(moduleLayerName) + "-pool1", maxPoolNxN(poolSize, poolStride),
inputLayer);
break;
case PNORM:
if (pNorm <= 0)
throw new IllegalArgumentException("p-norm must be greater than zero.");
graph.addLayer(getModuleName(moduleLayerName) + "-pool1", pNormNxN(pNorm, poolSize, poolStride),
inputLayer);
break;
default:
throw new IllegalStateException(
"You must specify a valid pooling type of avg or max for Inception module.");
}
graph.addLayer(getModuleName(moduleLayerName) + "-cnn2", convNxNreduce(inputSize, reduceSize[i], 1),
getModuleName(moduleLayerName) + "-pool1");
graph.addLayer(getModuleName(moduleLayerName) + "-batch3", batchNorm(reduceSize[i], reduceSize[i]),
getModuleName(moduleLayerName) + "-cnn2");
graph.addLayer(getModuleName(moduleLayerName) + "-transfer3",
new ActivationLayer.Builder().activation(transferFunction).build(),
getModuleName(moduleLayerName) + "-batch3");
} catch (IndexOutOfBoundsException e) {
}
i++;
// reduce
try {
graph.addLayer(getModuleName(moduleLayerName) + "-reduce2", convNxNreduce(inputSize, reduceSize[i], 1),
inputLayer);
graph.addLayer(getModuleName(moduleLayerName) + "-batch4", batchNorm(reduceSize[i], reduceSize[i]),
getModuleName(moduleLayerName) + "-reduce2");
graph.addLayer(getModuleName(moduleLayerName) + "-transfer4",
new ActivationLayer.Builder().activation(transferFunction).build(),
getModuleName(moduleLayerName) + "-batch4");
} catch (IndexOutOfBoundsException e) {
}
// TODO: there's a better way to do this
if (kernelSize.length == 1 && reduceSize.length == 3) {
graph.addVertex(getModuleName(moduleLayerName), new MergeVertex(),
getModuleName(moduleLayerName) + "-transfer2-0",
getModuleName(moduleLayerName) + "-transfer3",
getModuleName(moduleLayerName) + "-transfer4");
} else if (kernelSize.length == 2 && reduceSize.length == 2) {
graph.addVertex(getModuleName(moduleLayerName), new MergeVertex(),
getModuleName(moduleLayerName) + "-transfer2-0",
getModuleName(moduleLayerName) + "-transfer2-1");
} else if (kernelSize.length == 2 && reduceSize.length == 3) {
graph.addVertex(getModuleName(moduleLayerName), new MergeVertex(),
getModuleName(moduleLayerName) + "-transfer2-0",
getModuleName(moduleLayerName) + "-transfer2-1",
getModuleName(moduleLayerName) + "-transfer3");
} else if (kernelSize.length == 2 && reduceSize.length == 4) {
graph.addVertex(getModuleName(moduleLayerName), new MergeVertex(),
getModuleName(moduleLayerName) + "-transfer2-0",
getModuleName(moduleLayerName) + "-transfer2-1",
getModuleName(moduleLayerName) + "-transfer3",
getModuleName(moduleLayerName) + "-transfer4");
} else
throw new IllegalStateException(
"Only kernel of shape 1 or 2 and a reduce shape between 2 and 4 is supported.");
return graph;
}
}
@@ -0,0 +1,356 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * 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.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.zoo.model.helper;
import org.deeplearning4j.nn.conf.ComputationGraphConfiguration;
import org.deeplearning4j.nn.conf.ConvolutionMode;
import org.deeplearning4j.nn.conf.graph.ElementWiseVertex;
import org.deeplearning4j.nn.conf.graph.MergeVertex;
import org.deeplearning4j.nn.conf.graph.ScaleVertex;
import org.deeplearning4j.nn.conf.layers.ActivationLayer;
import org.deeplearning4j.nn.conf.layers.BatchNormalization;
import org.deeplearning4j.nn.conf.layers.ConvolutionLayer;
import org.nd4j.linalg.activations.Activation;
public class InceptionResNetHelper {
public static String nameLayer(String blockName, String layerName, int i) {
return blockName + "-" + layerName + "-" + i;
}
/**
* Append Inception-ResNet A to a computation graph.
* @param graph
* @param blockName
* @param scale
* @param activationScale
* @param input
* @return
*/
public static ComputationGraphConfiguration.GraphBuilder inceptionV1ResA(
ComputationGraphConfiguration.GraphBuilder graph, String blockName, int scale,
double activationScale, String input) {
// // first add the RELU activation layer
// graph.addLayer(nameLayer(blockName,"activation1",0), new ActivationLayer.Builder().activation(Activation.TANH).build(), input);
// loop and add each subsequent resnet blocks
String previousBlock = input;
for (int i = 1; i <= scale; i++) {
graph
// 1x1
.addLayer(nameLayer(blockName, "cnn1", i),
new ConvolutionLayer.Builder(new int[] {1, 1})
.convolutionMode(ConvolutionMode.Same).nIn(192).nOut(32)
.cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE)
.build(),
previousBlock)
.addLayer(nameLayer(blockName, "batch1", i),
new BatchNormalization.Builder(false).decay(0.995).eps(0.001).nIn(32)
.nOut(32).build(),
nameLayer(blockName, "cnn1", i))
// 1x1 -> 3x3
.addLayer(nameLayer(blockName, "cnn2", i),
new ConvolutionLayer.Builder(new int[] {1, 1})
.convolutionMode(ConvolutionMode.Same).nIn(192).nOut(32)
.cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE)
.build(),
previousBlock)
.addLayer(nameLayer(blockName, "batch2", i),
new BatchNormalization.Builder(false).decay(0.995).eps(0.001).nIn(32)
.nOut(32).build(),
nameLayer(blockName, "cnn2", i))
.addLayer(nameLayer(blockName, "cnn3", i),
new ConvolutionLayer.Builder(new int[] {3, 3})
.convolutionMode(ConvolutionMode.Same).nIn(32).nOut(32)
.cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE)
.build(),
nameLayer(blockName, "batch2", i))
.addLayer(nameLayer(blockName, "batch3", i),
new BatchNormalization.Builder(false).decay(0.995).eps(0.001).nIn(32)
.nOut(32).build(),
nameLayer(blockName, "cnn3", i))
// 1x1 -> 3x3 -> 3x3
.addLayer(nameLayer(blockName, "cnn4", i),
new ConvolutionLayer.Builder(new int[] {1, 1})
.convolutionMode(ConvolutionMode.Same).nIn(192).nOut(32)
.cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE)
.build(),
previousBlock)
.addLayer(nameLayer(blockName, "batch4", i),
new BatchNormalization.Builder(false).decay(0.995).eps(0.001).nIn(32)
.nOut(32).build(),
nameLayer(blockName, "cnn4", i))
.addLayer(nameLayer(blockName, "cnn5", i),
new ConvolutionLayer.Builder(new int[] {3, 3})
.convolutionMode(ConvolutionMode.Same).nIn(32).nOut(32)
.cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE)
.build(),
nameLayer(blockName, "batch4", i))
.addLayer(nameLayer(blockName, "batch5", i),
new BatchNormalization.Builder(false).decay(0.995).eps(0.001).nIn(32)
.nOut(32).build(),
nameLayer(blockName, "cnn5", i))
.addLayer(nameLayer(blockName, "cnn6", i),
new ConvolutionLayer.Builder(new int[] {3, 3})
.convolutionMode(ConvolutionMode.Same).nIn(32).nOut(32)
.cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE)
.build(),
nameLayer(blockName, "batch5", i))
.addLayer(nameLayer(blockName, "batch6", i),
new BatchNormalization.Builder(false).decay(0.995).eps(0.001).nIn(32)
.nOut(32).build(),
nameLayer(blockName, "cnn6", i))
// --> 1x1 --> scaling -->
.addVertex(nameLayer(blockName, "merge1", i), new MergeVertex(),
nameLayer(blockName, "batch1", i), nameLayer(blockName, "batch3", i),
nameLayer(blockName, "batch6", i))
.addLayer(nameLayer(blockName, "cnn7", i),
new ConvolutionLayer.Builder(new int[] {3, 3})
.convolutionMode(ConvolutionMode.Same).nIn(96).nOut(192)
.cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE)
.build(),
nameLayer(blockName, "merge1", i))
.addLayer(nameLayer(blockName, "batch7", i),
new BatchNormalization.Builder(false).decay(0.995).eps(0.001).nIn(192)
.nOut(192).build(),
nameLayer(blockName, "cnn7", i))
.addVertex(nameLayer(blockName, "scaling", i), new ScaleVertex(activationScale),
nameLayer(blockName, "batch7", i))
// -->
.addLayer(nameLayer(blockName, "shortcut-identity", i),
new ActivationLayer.Builder().activation(Activation.IDENTITY).build(),
previousBlock)
.addVertex(nameLayer(blockName, "shortcut", i),
new ElementWiseVertex(ElementWiseVertex.Op.Add),
nameLayer(blockName, "scaling", i),
nameLayer(blockName, "shortcut-identity", i));
// leave the last vertex as the block name for convenience
if (i == scale)
graph.addLayer(blockName, new ActivationLayer.Builder().activation(Activation.TANH).build(),
nameLayer(blockName, "shortcut", i));
else
graph.addLayer(nameLayer(blockName, "activation", i),
new ActivationLayer.Builder().activation(Activation.TANH).build(),
nameLayer(blockName, "shortcut", i));
previousBlock = nameLayer(blockName, "activation", i);
}
return graph;
}
/**
* Append Inception-ResNet B to a computation graph.
* @param graph
* @param blockName
* @param scale
* @param activationScale
* @param input
* @return
*/
public static ComputationGraphConfiguration.GraphBuilder inceptionV1ResB(
ComputationGraphConfiguration.GraphBuilder graph, String blockName, int scale,
double activationScale, String input) {
// first add the RELU activation layer
graph.addLayer(nameLayer(blockName, "activation1", 0),
new ActivationLayer.Builder().activation(Activation.TANH).build(), input);
// loop and add each subsequent resnet blocks
String previousBlock = nameLayer(blockName, "activation1", 0);
for (int i = 1; i <= scale; i++) {
graph
// 1x1
.addLayer(nameLayer(blockName, "cnn1", i),
new ConvolutionLayer.Builder(new int[] {1, 1})
.convolutionMode(ConvolutionMode.Same).nIn(576).nOut(128)
.cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE)
.build(),
previousBlock)
.addLayer(nameLayer(blockName, "batch1", i),
new BatchNormalization.Builder(false).decay(0.995).eps(0.001).nIn(128)
.nOut(128).build(),
nameLayer(blockName, "cnn1", i))
// 1x1 -> 3x3 -> 3x3
.addLayer(nameLayer(blockName, "cnn2", i),
new ConvolutionLayer.Builder(new int[] {1, 1})
.convolutionMode(ConvolutionMode.Same).nIn(576).nOut(128)
.cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE)
.build(),
previousBlock)
.addLayer(nameLayer(blockName, "batch2", i),
new BatchNormalization.Builder(false).decay(0.995).eps(0.001).nIn(128)
.nOut(128).build(),
nameLayer(blockName, "cnn2", i))
.addLayer(nameLayer(blockName, "cnn3", i),
new ConvolutionLayer.Builder(new int[] {1, 3})
.convolutionMode(ConvolutionMode.Same).nIn(128).nOut(128)
.cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE)
.build(),
nameLayer(blockName, "batch2", i))
.addLayer(nameLayer(blockName, "batch3", i),
new BatchNormalization.Builder(false).decay(0.995).eps(0.001).nIn(128)
.nOut(128).build(),
nameLayer(blockName, "cnn3", i))
.addLayer(nameLayer(blockName, "cnn4", i),
new ConvolutionLayer.Builder(new int[] {3, 1})
.convolutionMode(ConvolutionMode.Same).nIn(128).nOut(128)
.cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE)
.build(),
nameLayer(blockName, "batch3", i))
.addLayer(nameLayer(blockName, "batch4", i),
new BatchNormalization.Builder(false).decay(0.995).eps(0.001).nIn(128)
.nOut(128).build(),
nameLayer(blockName, "cnn4", i))
// --> 1x1 --> scaling -->
.addVertex(nameLayer(blockName, "merge1", i), new MergeVertex(),
nameLayer(blockName, "batch1", i), nameLayer(blockName, "batch4", i))
.addLayer(nameLayer(blockName, "cnn5", i),
new ConvolutionLayer.Builder(new int[] {1, 1})
.convolutionMode(ConvolutionMode.Same).nIn(256).nOut(576)
.cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE)
.build(),
nameLayer(blockName, "merge1", i))
.addLayer(nameLayer(blockName, "batch5", i),
new BatchNormalization.Builder(false).decay(0.995).eps(0.001).nIn(576)
.nOut(576).build(),
nameLayer(blockName, "cnn5", i))
.addVertex(nameLayer(blockName, "scaling", i), new ScaleVertex(activationScale),
nameLayer(blockName, "batch5", i))
// -->
.addLayer(nameLayer(blockName, "shortcut-identity", i),
new ActivationLayer.Builder().activation(Activation.IDENTITY).build(),
previousBlock)
.addVertex(nameLayer(blockName, "shortcut", i),
new ElementWiseVertex(ElementWiseVertex.Op.Add),
nameLayer(blockName, "scaling", i),
nameLayer(blockName, "shortcut-identity", i));
// leave the last vertex as the block name for convenience
if (i == scale)
graph.addLayer(blockName, new ActivationLayer.Builder().activation(Activation.TANH).build(),
nameLayer(blockName, "shortcut", i));
else
graph.addLayer(nameLayer(blockName, "activation", i),
new ActivationLayer.Builder().activation(Activation.TANH).build(),
nameLayer(blockName, "shortcut", i));
previousBlock = nameLayer(blockName, "activation", i);
}
return graph;
}
/**
* Append Inception-ResNet C to a computation graph.
* @param graph
* @param blockName
* @param scale
* @param activationScale
* @param input
* @return
*/
public static ComputationGraphConfiguration.GraphBuilder inceptionV1ResC(
ComputationGraphConfiguration.GraphBuilder graph, String blockName, int scale,
double activationScale, String input) {
// loop and add each subsequent resnet blocks
String previousBlock = input;
for (int i = 1; i <= scale; i++) {
graph
// 1x1
.addLayer(nameLayer(blockName, "cnn1", i),
new ConvolutionLayer.Builder(new int[] {1, 1})
.convolutionMode(ConvolutionMode.Same).nIn(1344).nOut(192)
.cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE)
.build(),
previousBlock)
.addLayer(nameLayer(blockName, "batch1", i),
new BatchNormalization.Builder(false).decay(0.995).eps(0.001).nIn(192)
.nOut(192).build(),
nameLayer(blockName, "cnn1", i))
// 1x1 -> 1x3 -> 3x1
.addLayer(nameLayer(blockName, "cnn2", i),
new ConvolutionLayer.Builder(new int[] {1, 1})
.convolutionMode(ConvolutionMode.Same).nIn(1344).nOut(192)
.cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE)
.build(),
previousBlock)
.addLayer(nameLayer(blockName, "batch2", i),
new BatchNormalization.Builder(false).decay(0.995).eps(0.001).nIn(192)
.nOut(192).build(),
nameLayer(blockName, "cnn2", i))
.addLayer(nameLayer(blockName, "cnn3", i),
new ConvolutionLayer.Builder(new int[] {1, 3})
.convolutionMode(ConvolutionMode.Same).nIn(192).nOut(192)
.cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE)
.build(),
nameLayer(blockName, "batch2", i))
.addLayer(nameLayer(blockName, "batch3", i),
new BatchNormalization.Builder(false).decay(0.995).eps(0.001).nIn(192)
.nOut(192).build(),
nameLayer(blockName, "cnn3", i))
.addLayer(nameLayer(blockName, "cnn4", i),
new ConvolutionLayer.Builder(new int[] {3, 1})
.convolutionMode(ConvolutionMode.Same).nIn(192).nOut(192)
.cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE)
.build(),
nameLayer(blockName, "batch3", i))
.addLayer(nameLayer(blockName, "batch4", i),
new BatchNormalization.Builder(false).decay(0.995).eps(0.001)
.activation(Activation.TANH).nIn(192).nOut(192).build(),
nameLayer(blockName, "cnn4", i))
// --> 1x1 --> scale -->
.addVertex(nameLayer(blockName, "merge1", i), new MergeVertex(),
nameLayer(blockName, "batch1", i), nameLayer(blockName, "batch4", i))
.addLayer(nameLayer(blockName, "cnn5", i),
new ConvolutionLayer.Builder(new int[] {1, 1})
.convolutionMode(ConvolutionMode.Same).nIn(384).nOut(1344)
.cudnnAlgoMode(ConvolutionLayer.AlgoMode.NO_WORKSPACE)
.build(),
nameLayer(blockName, "merge1", i))
.addLayer(nameLayer(blockName, "batch5", i),
new BatchNormalization.Builder(false).decay(0.995).eps(0.001)
.activation(Activation.TANH).nIn(1344).nOut(1344).build(),
nameLayer(blockName, "cnn5", i))
.addVertex(nameLayer(blockName, "scaling", i), new ScaleVertex(activationScale),
nameLayer(blockName, "batch5", i))
// -->
.addLayer(nameLayer(blockName, "shortcut-identity", i),
new ActivationLayer.Builder().activation(Activation.IDENTITY).build(),
previousBlock)
.addVertex(nameLayer(blockName, "shortcut", i),
new ElementWiseVertex(ElementWiseVertex.Op.Add),
nameLayer(blockName, "scaling", i),
nameLayer(blockName, "shortcut-identity", i));
// leave the last vertex as the block name for convenience
if (i == scale)
graph.addLayer(blockName, new ActivationLayer.Builder().activation(Activation.TANH).build(),
nameLayer(blockName, "shortcut", i));
else
graph.addLayer(nameLayer(blockName, "activation", i),
new ActivationLayer.Builder().activation(Activation.TANH).build(),
nameLayer(blockName, "shortcut", i));
previousBlock = nameLayer(blockName, "activation", i);
}
return graph;
}
}
@@ -0,0 +1,208 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * 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.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.zoo.model.helper;
import lombok.val;
import org.deeplearning4j.nn.conf.ComputationGraphConfiguration;
import org.deeplearning4j.nn.conf.ConvolutionMode;
import org.deeplearning4j.nn.conf.graph.ElementWiseVertex;
import org.deeplearning4j.nn.conf.graph.MergeVertex;
import org.deeplearning4j.nn.conf.inputs.InputType;
import org.deeplearning4j.nn.conf.layers.*;
import org.deeplearning4j.nn.conf.layers.convolutional.Cropping2D;
import org.deeplearning4j.zoo.model.NASNet;
import org.nd4j.linalg.activations.Activation;
import org.nd4j.common.primitives.Pair;
import java.util.Map;
public class NASNetHelper {
public static String sepConvBlock(ComputationGraphConfiguration.GraphBuilder graphBuilder, int filters, int kernelSize, int stride, String blockId, String input) {
String prefix = "sepConvBlock"+blockId;
graphBuilder
.addLayer(prefix+"_act", new ActivationLayer(Activation.RELU), input)
.addLayer(prefix+"_sepconv1", new SeparableConvolution2D.Builder(kernelSize, kernelSize).stride(stride, stride).nOut(filters).hasBias(false)
.convolutionMode(ConvolutionMode.Same).build(), prefix+"_act")
.addLayer(prefix+"_conv1_bn", new BatchNormalization.Builder().eps(1e-3).gamma(0.9997).build(), prefix+"_sepconv1")
.addLayer(prefix+"_act2", new ActivationLayer(Activation.RELU), prefix+"_conv1_bn")
.addLayer(prefix+"_sepconv2", new SeparableConvolution2D.Builder(kernelSize, kernelSize).stride(stride, stride).nOut(filters).hasBias(false)
.convolutionMode(ConvolutionMode.Same).build(), prefix+"_act2")
.addLayer(prefix+"_conv2_bn", new BatchNormalization.Builder().eps(1e-3).gamma(0.9997).build(), prefix+"_sepconv2");
return prefix+"_conv2_bn";
}
public static String adjustBlock(ComputationGraphConfiguration.GraphBuilder graphBuilder, int filters, String blockId, String input) {
return adjustBlock(graphBuilder, filters, blockId, input, null);
}
public static String adjustBlock(ComputationGraphConfiguration.GraphBuilder graphBuilder, int filters, String blockId, String input, String inputToMatch) {
String prefix = "adjustBlock"+blockId;
String outputName = input;
if(inputToMatch == null) {
inputToMatch = input;
}
Map<String, InputType> layerActivationTypes = graphBuilder.getLayerActivationTypes();
val shapeToMatch = layerActivationTypes.get(inputToMatch).getShape();
val inputShape = layerActivationTypes.get(input).getShape();
if(shapeToMatch[1] != inputShape[1]) {
graphBuilder
.addLayer(prefix+"_relu1", new ActivationLayer(Activation.RELU), input)
// tower 1
.addLayer(prefix+"_avgpool1", new SubsamplingLayer.Builder(PoolingType.AVG).kernelSize(1,1).stride(2,2)
.convolutionMode(ConvolutionMode.Truncate).build(), prefix+"_relu1")
.addLayer(prefix+"_conv1", new ConvolutionLayer.Builder(1,1).stride(1,1).nOut((int) Math.floor(filters / 2)).hasBias(false)
.convolutionMode(ConvolutionMode.Same).build(), prefix+"_avg_pool_1")
// tower 2
.addLayer(prefix+"_zeropad1", new ZeroPaddingLayer(0,1), prefix+"_relu1")
.addLayer(prefix+"_crop1", new Cropping2D(1,0), prefix+"_zeropad_1")
.addLayer(prefix+"_avgpool2", new SubsamplingLayer.Builder(PoolingType.AVG).kernelSize(1,1).stride(2,2)
.convolutionMode(ConvolutionMode.Truncate).build(), prefix+"_crop1")
.addLayer(prefix+"_conv2", new ConvolutionLayer.Builder(1,1).stride(1,1).nOut((int) Math.floor(filters / 2)).hasBias(false)
.convolutionMode(ConvolutionMode.Same).build(), prefix+"_avgpool2")
.addVertex(prefix+"_concat1", new MergeVertex(), prefix+"_conv1", prefix+"_conv2")
.addLayer(prefix+"_bn1", new BatchNormalization.Builder().eps(1e-3).gamma(0.9997)
.build(), prefix+"_concat1");
outputName = prefix+"_bn1";
}
if(inputShape[3] != filters) {
graphBuilder
.addLayer(prefix+"_projection_relu", new ActivationLayer(Activation.RELU), outputName)
.addLayer(prefix+"_projection_conv", new ConvolutionLayer.Builder(1,1).stride(1,1).nOut(filters).hasBias(false)
.convolutionMode(ConvolutionMode.Same).build(), prefix+"_projection_relu")
.addLayer(prefix+"_projection_bn", new BatchNormalization.Builder().eps(1e-3).gamma(0.9997)
.build(), prefix+"_projection_conv");
outputName = prefix+"_projection_bn";
}
return outputName;
}
public static Pair<String, String> normalA(ComputationGraphConfiguration.GraphBuilder graphBuilder, int filters, String blockId, String inputX, String inputP) {
String prefix = "normalA"+blockId;
String topAdjust = adjustBlock(graphBuilder, filters, prefix, inputP, inputX);
// top block
graphBuilder
.addLayer(prefix+"_relu1", new ActivationLayer(Activation.RELU), topAdjust)
.addLayer(prefix+"_conv1", new ConvolutionLayer.Builder(1,1).stride(1,1).nOut(filters).hasBias(false)
.convolutionMode(ConvolutionMode.Same).build(), prefix+"_relu1")
.addLayer(prefix+"_bn1", new BatchNormalization.Builder().eps(1e-3).gamma(0.9997)
.build(), prefix+"_conv1");
// block 1
String left1 = sepConvBlock(graphBuilder, filters, 5, 1, prefix+"_left1", prefix+"_bn1");
String right1 = sepConvBlock(graphBuilder, filters, 3, 1, prefix+"_right1", topAdjust);
graphBuilder.addVertex(prefix+"_add1", new ElementWiseVertex(ElementWiseVertex.Op.Add), left1, right1);
// block 2
String left2 = sepConvBlock(graphBuilder, filters, 5, 1, prefix+"_left2", topAdjust);
String right2 = sepConvBlock(graphBuilder, filters, 3, 1, prefix+"_right2", topAdjust);
graphBuilder.addVertex(prefix+"_add2", new ElementWiseVertex(ElementWiseVertex.Op.Add), left2, right2);
// block 3
graphBuilder
.addLayer(prefix+"_left3", new SubsamplingLayer.Builder(PoolingType.AVG).kernelSize(3,3).stride(1,1)
.convolutionMode(ConvolutionMode.Same).build(), prefix+"_bn1")
.addVertex(prefix+"_add3", new ElementWiseVertex(ElementWiseVertex.Op.Add), prefix+"_left3", topAdjust);
// block 4
graphBuilder
.addLayer(prefix+"_left4", new SubsamplingLayer.Builder(PoolingType.AVG).kernelSize(3,3).stride(1,1)
.convolutionMode(ConvolutionMode.Same).build(), topAdjust)
.addLayer(prefix+"_right4", new SubsamplingLayer.Builder(PoolingType.AVG).kernelSize(3,3).stride(1,1)
.convolutionMode(ConvolutionMode.Same).build(), topAdjust)
.addVertex(prefix+"_add4", new ElementWiseVertex(ElementWiseVertex.Op.Add), prefix+"_left4", prefix+"_right4");
// block 5
String left5 = sepConvBlock(graphBuilder, filters, 3, 1, prefix+"_left5", topAdjust);
graphBuilder.addVertex(prefix+"_add5", new ElementWiseVertex(ElementWiseVertex.Op.Add), prefix+"_left5", prefix+"_bn1");
// output
graphBuilder.addVertex(prefix, new MergeVertex(),
topAdjust, prefix+"_add1", prefix+"_add2", prefix+"_add3", prefix+"_add4", prefix+"_add5");
return new Pair<>(prefix, inputX);
}
public static Pair<String, String> reductionA(ComputationGraphConfiguration.GraphBuilder graphBuilder, int filters, String blockId, String inputX, String inputP) {
String prefix = "reductionA"+blockId;
String topAdjust = adjustBlock(graphBuilder, filters, prefix, inputP, inputX);
// top block
graphBuilder
.addLayer(prefix+"_relu1", new ActivationLayer(Activation.RELU), topAdjust)
.addLayer(prefix+"_conv1", new ConvolutionLayer.Builder(1,1).stride(1,1).nOut(filters).hasBias(false)
.convolutionMode(ConvolutionMode.Same).build(), prefix+"_relu1")
.addLayer(prefix+"_bn1", new BatchNormalization.Builder().eps(1e-3).gamma(0.9997)
.build(), prefix+"_conv1");
// block 1
String left1 = sepConvBlock(graphBuilder, filters, 5, 2, prefix+"_left1", prefix+"_bn1");
String right1 = sepConvBlock(graphBuilder, filters, 7, 2, prefix+"_right1", topAdjust);
graphBuilder.addVertex(prefix+"_add1", new ElementWiseVertex(ElementWiseVertex.Op.Add), left1, right1);
// block 2
graphBuilder.addLayer(prefix+"_left2", new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.MAX).kernelSize(3,3).stride(2,2)
.convolutionMode(ConvolutionMode.Same).build(), prefix+"_bn1");
String right2 = sepConvBlock(graphBuilder, filters, 3, 1, prefix+"_right2", topAdjust);
graphBuilder.addVertex(prefix+"_add2", new ElementWiseVertex(ElementWiseVertex.Op.Add), prefix+"_left2", right2);
// block 3
graphBuilder.addLayer(prefix+"_left3", new SubsamplingLayer.Builder(SubsamplingLayer.PoolingType.AVG).kernelSize(3,3).stride(2,2)
.convolutionMode(ConvolutionMode.Same).build(), prefix+"_bn1");
String right3 = sepConvBlock(graphBuilder, filters, 5, 2, prefix+"_right3", topAdjust);
graphBuilder.addVertex(prefix+"_add3", new ElementWiseVertex(ElementWiseVertex.Op.Add), prefix+"_left3", right3);
// block 4
graphBuilder
.addLayer(prefix+"_left4", new SubsamplingLayer.Builder(PoolingType.AVG).kernelSize(3,3).stride(1,1)
.convolutionMode(ConvolutionMode.Same).build(), prefix+"_add1")
.addVertex(prefix+"_add4", new ElementWiseVertex(ElementWiseVertex.Op.Add), prefix+"_add2", prefix+"_left4");
// block 5
String left5 = sepConvBlock(graphBuilder, filters, 3, 2, prefix+"_left5", prefix+"_add1");
graphBuilder
.addLayer(prefix+"_right5", new SubsamplingLayer.Builder(PoolingType.MAX).kernelSize(3,3).stride(2,2)
.convolutionMode(ConvolutionMode.Same).build(), prefix+"_bn1")
.addVertex(prefix+"_add5", new ElementWiseVertex(ElementWiseVertex.Op.Add), left5, prefix+"_right5");
// output
graphBuilder.addVertex(prefix, new MergeVertex(),
prefix+"_add2", prefix+"_add3", prefix+"_add4", prefix+"_add5");
return new Pair<>(prefix, inputX);
}
}
@@ -0,0 +1,9 @@
@Deprecated()
/**
* Please use the new omnihub module for future model zoo support.
* For more please see the omnihub maven module.
* @since 1.0.0-M2
* @see {@link org.eclipse.deeplearning4j.omnihub}
*/
package org.deeplearning4j.zoo;
@@ -0,0 +1,167 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * 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.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.zoo.util;
import org.deeplearning4j.common.resources.DL4JResources;
import org.deeplearning4j.common.resources.ResourceType;
import org.nd4j.common.base.Preconditions;
import org.nd4j.linalg.api.ndarray.INDArray;
import org.nd4j.linalg.factory.Nd4j;
import org.nd4j.common.resources.Downloader;
import java.io.*;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public abstract class BaseLabels implements Labels {
protected ArrayList<String> labels;
/** Override {@link #getLabels()} when using this constructor. */
protected BaseLabels() throws IOException {
this.labels = getLabels();
}
/**
* No need to override anything with this constructor.
*
* @param textResource name of a resource containing labels as a list in a text file.
* @throws IOException
*/
protected BaseLabels(String textResource) throws IOException {
this.labels = getLabels(textResource);
}
/**
* Override to return labels when not calling {@link #BaseLabels(String)}.
*/
protected ArrayList<String> getLabels() throws IOException {
return null;
}
/**
* Returns labels based on the text file resource.
*/
protected ArrayList<String> getLabels(String textResource) throws IOException {
ArrayList<String> labels = new ArrayList<>();
File resourceFile = getResourceFile(); //Download if required
try (InputStream is = new BufferedInputStream(new FileInputStream(resourceFile)); Scanner s = new Scanner(is)) {
while (s.hasNextLine()) {
labels.add(s.nextLine());
}
}
return labels;
}
@Override
public String getLabel(int n) {
Preconditions.checkArgument(n >= 0 && n < labels.size(), "Invalid index: %s. Must be in range" +
"0 <= n < %s", n, labels.size());
return labels.get(n);
}
@Override
public List<List<ClassPrediction>> decodePredictions(INDArray predictions, int n) {
if(predictions.rank() == 1){
//Reshape 1d edge case to [1, nClasses] 2d
predictions = predictions.reshape(1, predictions.length());
}
Preconditions.checkState(predictions.size(1) == labels.size(), "Invalid input array:" +
" expected array with size(1) equal to numLabels (%s), got array with shape %s", labels.size(), predictions.shape());
long rows = predictions.size(0);
long cols = predictions.size(1);
if (predictions.isColumnVectorOrScalar()) {
predictions = predictions.ravel();
rows = (int) predictions.size(0);
cols = (int) predictions.size(1);
}
List<List<ClassPrediction>> descriptions = new ArrayList<>();
for (int batch = 0; batch < rows; batch++) {
INDArray result = predictions.getRow(batch, true);
result = Nd4j.vstack(Nd4j.linspace(result.dataType(), 0, cols, 1).reshape(1,cols), result);
result = Nd4j.sortColumns(result, 1, false);
List<ClassPrediction> current = new ArrayList<>();
for (int i = 0; i < n; i++) {
int label = result.getInt(0, i);
double prob = result.getDouble(1, i);
current.add(new ClassPrediction(label, getLabel(label), prob));
}
descriptions.add(current);
}
return descriptions;
}
/**
* @return URL of the resource to download
*/
protected abstract URL getURL();
/**
* @return Name of the resource (used for inferring local storage parent directory)
*/
protected abstract String resourceName();
/**
* @return MD5 of the resource at getURL()
*/
protected abstract String resourceMD5();
/**
* Download the resource at getURL() to the local resource directory, and return the local copy as a File
*
* @return File of the local resource
*/
protected File getResourceFile() {
URL url = getURL();
String urlString = url.toString();
String filename = urlString.substring(urlString.lastIndexOf('/')+1);
File resourceDir = DL4JResources.getDirectory(ResourceType.RESOURCE, resourceName());
File localFile = new File(resourceDir, filename);
String expMD5 = resourceMD5();
if(localFile.exists()) {
try{
//empty string means ignore the MD5
if(Downloader.checkMD5OfFile(expMD5, localFile)) {
return localFile;
}
} catch (IOException e){
//Ignore
}
//MD5 failed
localFile.delete();
}
//Download
try {
Downloader.download(resourceName(), url, localFile, expMD5, 3);
} catch (IOException e){
throw new RuntimeException("Error downloading labels",e);
}
return localFile;
}
}
@@ -0,0 +1,38 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * 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.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.zoo.util;
import lombok.AllArgsConstructor;
import lombok.Data;
@AllArgsConstructor
@Data
public class ClassPrediction {
private int number;
private String label;
private double probability;
@Override
public String toString() {
return "ClassPrediction(number=" + number + ",label=" + label + ",probability=" + probability + ")";
}
}
@@ -0,0 +1,43 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * 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.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.zoo.util;
import org.nd4j.linalg.api.ndarray.INDArray;
import java.util.List;
public interface Labels {
/**
* Returns the description of the nth class from the classes of a dataset.
* @param n
* @return label description
*/
String getLabel(int n);
/**
* Given predictions from the trained model this method will return a list
* of the top n matches and the respective probabilities.
* @param predictions raw
* @return decoded predictions
*/
List<List<ClassPrediction>> decodePredictions(INDArray predictions, int n);
}
@@ -0,0 +1,54 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * 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.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.zoo.util.darknet;
import org.deeplearning4j.common.resources.DL4JResources;
import org.deeplearning4j.zoo.util.BaseLabels;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
public class COCOLabels extends BaseLabels {
public COCOLabels() throws IOException {
super("coco.names");
}
@Override
protected URL getURL() {
try {
return DL4JResources.getURL("resources/darknet/coco.names");
} catch (MalformedURLException e){
throw new RuntimeException(e);
}
}
@Override
protected String resourceName() {
return "darknet";
}
@Override
protected String resourceMD5() {
return "4caf6834300c8b2ff19964b36e54d637";
}
}
@@ -0,0 +1,99 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * 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.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.zoo.util.darknet;
import org.deeplearning4j.common.resources.DL4JResources;
import org.deeplearning4j.zoo.util.BaseLabels;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
public class DarknetLabels extends BaseLabels {
private boolean shortNames;
private int numClasses;
/** Calls {@code this(true)}.
* Defaults to 1000 clasess
*/
public DarknetLabels() throws IOException {
this(true);
}
/**
* @param numClasses Number of classes (usually 1000 or 9000, depending on the model)
*/
public DarknetLabels(int numClasses) throws IOException {
this(true, numClasses);
}
@Override
protected URL getURL() {
try{
if (shortNames) {
return DL4JResources.getURL("resources/darknet/imagenet.shortnames.list");
} else {
return DL4JResources.getURL("resources/darknet/imagenet.labels.list");
}
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
/**
* @param shortnames if true, uses "imagenet.shortnames.list", otherwise "imagenet.labels.list".
*/
public DarknetLabels(boolean shortnames) throws IOException {
this(shortnames, 1000);
}
/**
* @param shortnames if true, uses "imagenet.shortnames.list", otherwise "imagenet.labels.list".
* @param numClasses Number of classes (usually 1000 or 9000, depending on the model)
* @throws IOException
*/
public DarknetLabels(boolean shortnames, int numClasses) throws IOException {
this.shortNames = shortnames;
this.numClasses = numClasses;
List<String> labels = getLabels(shortnames ? "imagenet.shortnames.list" : "imagenet.labels.list");
this.labels = new ArrayList<>();
for( int i=0; i<numClasses; i++ ){
this.labels.add(labels.get(i));
}
}
@Override
protected String resourceName() {
return "darknet";
}
@Override
protected String resourceMD5() {
if(shortNames){
return "23d2a102a2de03d1b169c748b7141a20";
} else {
return "23ab429a707492324fef60a933551941";
}
}
}
@@ -0,0 +1,54 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * 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.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.zoo.util.darknet;
import org.deeplearning4j.common.resources.DL4JResources;
import org.deeplearning4j.zoo.util.BaseLabels;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
public class VOCLabels extends BaseLabels {
public VOCLabels() throws IOException {
super("voc.names");
}
@Override
protected URL getURL() {
try {
return DL4JResources.getURL("resources/darknet/voc.names");
} catch (MalformedURLException e){
throw new RuntimeException(e);
}
}
@Override
protected String resourceName() {
return "darknet";
}
@Override
protected String resourceMD5() {
return "bd70d6c917e90b6b67275b9ebda1b631";
}
}
@@ -0,0 +1,123 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * 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.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.zoo.util.imagenet;
import org.deeplearning4j.common.resources.DL4JResources;
import org.deeplearning4j.zoo.util.BaseLabels;
import org.nd4j.common.base.Preconditions;
import org.nd4j.linalg.api.ndarray.INDArray;
import org.nd4j.linalg.factory.Nd4j;
import org.nd4j.shade.jackson.databind.ObjectMapper;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
public class ImageNetLabels extends BaseLabels {
private static final String jsonResource = "imagenet_class_index.json";
private ArrayList<String> predictionLabels;
public ImageNetLabels() throws IOException {
this.predictionLabels = getLabels();
}
protected ArrayList<String> getLabels() throws IOException {
File localFile = getResourceFile();
if (predictionLabels == null) {
HashMap<String, ArrayList<String>> jsonMap;
jsonMap = new ObjectMapper().readValue(localFile, HashMap.class);
predictionLabels = new ArrayList<>(jsonMap.size());
for (int i = 0; i < jsonMap.size(); i++) {
predictionLabels.add(jsonMap.get(String.valueOf(i)).get(1));
}
}
return predictionLabels;
}
/**
* Returns the description of tne nth class in the 1000 classes of ImageNet.
* @param n
* @return
*/
public String getLabel(int n) {
return predictionLabels.get(n);
}
@Override
protected URL getURL() {
try {
return DL4JResources.getURL("resources/imagenet/" + jsonResource);
} catch (MalformedURLException e){
throw new RuntimeException(e);
}
}
@Override
protected String resourceName() {
return jsonResource;
}
@Override
protected String resourceMD5() {
return "c2c37ea517e94d9795004a39431a14cb";
}
/**
* Given predictions from the trained model this method will return a string
* listing the top five matches and the respective probabilities
* @param predictions
* @return
*/
public String decodePredictions(INDArray predictions) {
Preconditions.checkState(predictions.size(1) == predictionLabels.size(), "Invalid input array:" +
" expected array with size(1) equal to numLabels (%s), got array with shape %s", predictionLabels.size(), predictions.shape());
String predictionDescription = "";
int[] top5 = new int[5];
float[] top5Prob = new float[5];
//brute force collect top 5
int i = 0;
for (int batch = 0; batch < predictions.size(0); batch++) {
predictionDescription += "Predictions for batch ";
if (predictions.size(0) > 1) {
predictionDescription += String.valueOf(batch);
}
predictionDescription += " :";
INDArray currentBatch = predictions.getRow(batch).dup();
while (i < 5) {
top5[i] = Nd4j.argMax(currentBatch, 1).getInt(0);
top5Prob[i] = currentBatch.getFloat(batch, top5[i]);
currentBatch.putScalar(0, top5[i], 0);
predictionDescription += "\n\t" + String.format("%3f", top5Prob[i] * 100) + "%, "
+ predictionLabels.get(top5[i]);
i++;
}
}
return predictionDescription;
}
}
@@ -0,0 +1,15 @@
open module deeplearning4j.zoo {
requires commons.io;
requires jackson;
requires resources;
requires slf4j.api;
requires deeplearning4j.nn;
requires nd4j.api;
requires nd4j.common;
exports org.deeplearning4j.zoo;
exports org.deeplearning4j.zoo.model;
exports org.deeplearning4j.zoo.model.helper;
exports org.deeplearning4j.zoo.util;
exports org.deeplearning4j.zoo.util.darknet;
exports org.deeplearning4j.zoo.util.imagenet;
}