Deeplearning4j模型库

0.9.0版(0.8.1-SNAPSHOT)的Deeplearning4j配有一个全新的原生模型库,可以直接从DL4J中访问和实例化。从Github上复制模型配置的日子已经一去不复返。模型库还提供用自动下载的不同数据集进行预训练后获得的权重,预训练数据集都已经过完整性检查。

使用新模型库之前需要先将其添加为依赖项。请在Maven POM文件中加入以下代码:

<dependency>
    <groupId>org.deeplearning4j</groupId>
    <artifactId>deeplearning4j-zoo</artifactId>
    <version>${deeplearning4j.version}</version>
</dependency>

${deeplearning4j.version}应当与您所使用的DL4J版本保持一致,请采用Maven中央仓库提供的最新版本。

入门指南

将模型库依赖项添加至项目后,您就可以开始导入模型并加以使用了。每个模型都是ZooModel抽象类的扩展,采用InstantiableModel接口。这些类提供的方法可以帮助您初始化一个空白的全新网络,或者一个已完成预训练的网络。

新神经网络的初始化

您可以用.init()方法将模型库中的某一个模型实例化。例如,您可以用以下代码来实例化一个全新的、未经训练的AlexNet网络:

import org.deeplearning4j.zoo.model.AlexNet
import org.deeplearning4j.zoo.*;

...

int numberOfClassesInYourData = 1000;
int randomSeed = 123;
int iterations = 1; // 绝大多数情况都是1

ZooModel zooModel = new AlexNet(numberOfClassesInYourData, randomSeed, iterations);
Model net = zooModel.init();

如果您希望调试参数或更改优化算法,可引用网络的基础配置:

ZooModel zooModel = new AlexNet(numberOfClassesInYourData, randomSeed, iterations);
MultiLayerConfiguration net = zooModel.conf();

初始化预训练的权重

部分模型有预训练的权重可供使用,有一小部分模型已接受过多个数据集的预训练。枚举器PretrainedType界定不同的权重类型,包括IMAGENETMNISTCIFAR10VGGFACE

例如,下列代码可以让您用ImageNet权重来初始化一个VGG-16模型:

import org.deeplearning4j.zoo.model.VGG16;
import org.deeplearning4j.zoo.*;

...

ZooModel zooModel = new VGG16();
Model net = zooModel.initPretrained(PretrainedType.IMAGENET);

然后再用通过VGG-Face数据集训练所得的权重来初始化另一个VGG-16模型:

ZooModel zooModel = new VGG16();
Model net = zooModel.initPretrained(PretrainedType.VGGFACE);

如果您不确定一个模型是否包含预训练权重,可以使用返回一个布尔值的.pretrainedAvailable()方法。您只需将一个PretrainedType枚举类传递给该方法,有预训练的权重可用时,返回结果为真。

请注意,卷积网络模型的输入形状信息遵循NCHW格式。因此,假如一个模型的默认输入形状为new int[]{3, 224, 224},那么表明该模型有3个通道,高/宽为224。

模型库里有什么?

模型库中提供深度学习社区所熟知的一系列网络配置,VGG-16、ResNet-50、AlexNet、Inception-ResNet-v1、GoogLeNet、LeNet等ImageNet模型均包括在内。此外,模型库中还包括一个用于文本生成的LSTM网络,以及一个进行通用图像识别的简单卷积神经网络。

您可以通过deeplearning4j-zoo Github链接查看完整的模型列表。

高级功能

模型库还有一些额外的功能,可帮助您将模型应用于不同的情境。

模型选择器

ModelSelector让您可以一次选择多个模型。该方法的创建目的是为了同时测试多个模型。

选择器返回的结果是一个Map<ZooType, ZooModel>集合。把ZooType.RESNET50传递给ModelSelector.select(ZooType.RESNET50)后,系统将返回HashMap<ZooType.RESNET50, new ResNet50()>类型的集合。但是,如果您想同时为一个特定的数据集初始化多个模型,可以用ModelSelector.select(ZooType.RESNET50, numLabels, seed, iterations)的方式向选择器传递恰当的参数。

假设您想要对所有提供ImageNet预训练权重的模型进行基准测试。下列代码可以让您选择所有的卷积模型,检查是否有权重可用,然后执行您自己的代码。

import org.deeplearning4j.zoo.*;
...

// 选择所有卷积模型
Map<ZooType, ZooModel> models = ModelSelector.select(ZooType.CNN);

for (Map.Entry<ZooType, ZooModel> entry : models.entrySet()) {
    ZooModel zooModel = entry.getValue();

    if(model.pretrainedAvailable(PretrainedType.IMAGENET)) {
        Model net = zooModel.initPretrained(PretrainedType.IMAGENET);

        // 对预训练模型进行所需的操作
    }

    // 为当前模型进行清理(有助于避免内存不足)
    Nd4j.getWorkspaceManager().destroyAllWorkspacesForCurrentThread();
    System.gc();
    Thread.sleep(1000);
}

或者,您可以用以下代码选择具体的模型:

ModelSelector.select(ZooType.RESNET50, ZooType.VGG16, ZooType,VGG19);

改变输入

除了将特定配置信息传递给一个模型的构造器之外,您还可以用.setInputShape()来改变模型的输入形状。请注意:该方法只适用于全新配置,无法影响已完成预训练的模型。

ZooModel zooModel = new ResNet50(10, 123, 1);
zooModel.setInputShape(new int[]{3,28,28});

迁移学习

预训练模型非常适合迁移学习!您可以在此页进一步了解如何使用DL4J进行迁移学习。

工作区

初始化方法通常有一项名为workspaceMode的额外参数。大多数用户不需要使用这项参数;但假如您有一台配置超强的大型计算机,那么可以将该参数设为WorkspaceMode.SINGLE。如需进一步了解有关工作区的信息,请参阅此页