chore: import upstream snapshot with attribution
This commit is contained in:
+43
@@ -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();
|
||||
}
|
||||
+42
@@ -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;
|
||||
}
|
||||
}
|
||||
+25
@@ -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
|
||||
}
|
||||
+186
@@ -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];
|
||||
}
|
||||
|
||||
}
|
||||
+167
@@ -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];
|
||||
}
|
||||
}
|
||||
+368
@@ -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];
|
||||
}
|
||||
|
||||
}
|
||||
+328
@@ -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];
|
||||
}
|
||||
|
||||
}
|
||||
+152
@@ -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];
|
||||
}
|
||||
}
|
||||
+200
@@ -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];
|
||||
}
|
||||
|
||||
}
|
||||
+249
@@ -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];
|
||||
}
|
||||
|
||||
}
|
||||
+155
@@ -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];
|
||||
}
|
||||
}
|
||||
+189
@@ -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];
|
||||
}
|
||||
|
||||
}
|
||||
+111
@@ -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];
|
||||
}
|
||||
}
|
||||
+160
@@ -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];
|
||||
}
|
||||
}
|
||||
+229
@@ -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];
|
||||
}
|
||||
|
||||
}
|
||||
+180
@@ -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];
|
||||
}
|
||||
|
||||
}
|
||||
+174
@@ -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];
|
||||
}
|
||||
|
||||
}
|
||||
+252
@@ -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];
|
||||
}
|
||||
|
||||
}
|
||||
+192
@@ -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];
|
||||
}
|
||||
}
|
||||
+106
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
+253
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
+356
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
+208
@@ -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);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+9
@@ -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;
|
||||
+167
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
+38
@@ -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 + ")";
|
||||
}
|
||||
}
|
||||
+43
@@ -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);
|
||||
}
|
||||
+54
@@ -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";
|
||||
}
|
||||
}
|
||||
+99
@@ -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";
|
||||
}
|
||||
}
|
||||
}
|
||||
+54
@@ -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";
|
||||
}
|
||||
}
|
||||
+123
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user