美文网首页机器学习
DL4J中文文档/开始/速查表-2

DL4J中文文档/开始/速查表-2

作者: hello风一样的男子 | 来源:发表于2018-10-21 19:51 被阅读77次

    正则化

    L1/L2 正则化

    L1和L2正则化可以容易地通过配置:.l1(0.1).l2(0.2)添加到网络中。注意, .regularization(true) 必须在0.9.1上启用(这个选项在0.9.1发布后被删除)。
    L1和L2正则化仅适用于权重参数。也就是说,.l1 和 .l2 不会影响偏置参数-这些可以使用.l1Bias(0.1).l2Bias(0.2)实现被正则化。

    Dropout(丢弃)

    所有的丢弃类型公在训练时应用。它们不在测试时应用。

    • Dropout - (Source) - 每个输入激活X被独立地设置为(0,与概率1-p)或(x/p与概率p)。
    • GaussianDropout - (Source) - 这是一个输入激活上的乘法高斯噪声(均值1)。每个输入激活X独立地设置为:x * y, y ~ N(1, stdev = sqrt((1-rate)/rate))
    • GaussianNoise - (Source) - 将加法,平均零高斯噪声应用于输入-即 x = x + N(0,stddev)
    • AlphaDropout - (Source) - AlphaDropout是一个丢弃技术,由Klaumbauer et al. 2017 - 自归一化神经网络提出。设计为自归一化神经网络(SELU 激活函数, NORMAL 权重初始化)。试图让丢弃后激活的均值和方差与AlphaDropout被应用之前相同。

    注意(从当前主干开始,但不是0.9.1),丢弃参数也可以根据学习率调度部分中提到的任何调度类来指定。

    权重噪声

    根据丢弃,丢弃连接/权重噪声只适用于训练时间。

    • DropConnect - (Source) - 参考文献 DropConnect与dropout类似,但应用于网络参数(而不是输入激活)
    • WeightNoise - (Source) - 在训练时把指定分布噪声应用于权重。支持加法和乘法模式。-当 加法时,噪声应当均值为0,当乘法时,噪声均值应当为1。

    约束

    约束是在每次迭代结束时(在参数更新发生之后)放置在模型的参数上的确定性限制。它们可以被认为是正则化的一种类型。

    • MaxNormConstraint - (Source) - 将每个单元的输入权重的最大L2范数约束为小于或等于指定值。如果L2范数超过指定值,则权重将被缩减以满足约束。
    • MinMaxNormConstraint - (Source) -将每个单元的输入权重的最小和最大L2范数约束在指定值之间。如果需要的话,权重将被放大/缩小。
    • NonNegativeConstraint - (Source) - 约束所有参数为非负。负参数将被替换为0。
    • UnitNormConstraint - (Source) -将每个单元的输入权重的L2范数约束为1。

    数据类

    迭代器

    DataSetIterator是DL4J用于对小批量数据进行迭代的抽象,用于训练。DataSetIterator返回DataSet对象,这些对象是小批量,并支持最多1个输入和1个输出数组(INDArray)。
    MultiDataSetIterator类似于DataSetIterator,但是返回MultiDataSet对象,该对象可以具有网络所需的多个输入和多个输出数组。

    内置迭代器 (DL4J-提供数据)

    这些迭代器按需要下载它们的数据。它们返回的实际数据集不是可定制的。

    • MnistDataSetIterator - (Source) - 著名的MNIST数字数据集的DataSetIterator。默认情况下,返回行向量(1x784),其值被归一化为0至1范围。使用.setInputType(InputType.convolutionalFlat())来与CNN一起使用。
    • EmnistDataSetIterator - (Source) - 类似于MNIST数字数据集,但有更多的例子,也有字母。包括多个不同的分割(仅字母,数字,字母+数字等)。因此,可以使用与MNIST相同的1x784格式(除了用于某些分割的不同数量的标签之外)作为MnistDataSetIterator的置换置换。 参考文献 1, 参考文献2
    • IrisDataSetIterator - (Source) -一个众所周知的鸢尾花数据集的迭代器。4个特征,3个输出类。
    • CifarDataSetIterator - (Source) - CIOFAR图像数据集的迭代器。10类,在DL4J中CNNs的4D特征/激活格式:[minibatch,channels,height,width] = [minibatch,3,32,32]。特征不是归一化的,而是在0到255的范围内。
    • LFWDataSetIterator - (Source)
    • TinyImageNetDataSetIterator (Source) - 标准IMANET数据集的子集;200个类,每个类500个图像
    • UciSequenceDataSetIterator (Source) - UCI 综合控制时间序列数据集

    迭代器-用户提供的数据

    此子章节的迭代器与用户提供的数据一起使用。

    • RecordReaderDataSetIterator - (Source) - 采用DataVec记录读取器(如CsvRecordReader或ImageRecordReader)并处理到数据集的转换、批处理、屏蔽等的迭代器。DL4J中最常用的迭代器之一。只处理非序列数据,作为输入(即,RecordReader,非SequenceeRecordReader)。
    • RecordReaderMultiDataSetIterator - (Source) - RecordReaderDataSetIterator 的MultiDataSet版本, 支持多个读取器。具有用于创建更复杂的数据管道的构建器模式(例如,读取器输出到不同输入/输出阵列的不同子集、转换到一个热点等等)。处理序列和非序列数据作为输入。
    • SequenceRecordReaderDataSetIterator - (Source) - RecordReaderDataSetIterator 的sequence (SequenceRecordReader) 版本。 用户最好结合RecordReaderMultiDataSetIterator使用。
    • DoublesDataSetIterator - (Source)
    • FloatsDataSetIterator - (Source)
    • INDArrayDataSetIterator - (Source)

    迭代器 - 适配器与实用迭代器

    • MultiDataSetIteratorAdapter - (Source) - 包装一个 DataSetIterator来转换为一个MultiDataSetIterator
    • SingletonMultiDataSetIterator - (Source) - 包装一个MultiDataSet 转换为一个 MultiDataSetIterator 并返回一个 MultiDataSet (即, 包装的MultiDataSet是不可分割的)
    • AsyncDataSetIterator - (Source) - 在适当的情况下由多层网络和计算图自动使用。实现数据集的异步预获取以提高性能。
    • AsyncMultiDataSetIterator - (Source) - 在适当的情况下由计算图自动使用。实现多数据集的异步预获取以提高性能。
    • AsyncShieldDataSetIterator - (Source) - 通常只用于调试。使用AsyncDataSetIterator来停止多层网络和计算图。
    • AsyncShieldMultiDataSetIterator - (Source) - AsyncShieldDataSetIterator 的 MultiDataSetIterator 版本。
    • EarlyTerminationDataSetIterator - (Source) - 包装另一个DataSetIterator,确保在重置之间仅返回指定(最大)数量的小批量(DataSet)对象。可以用来“剪短”一个迭代器,只返回前N个数据集。
    • EarlyTerminationMultiDataSetIterator - (Source) - EarlyTerminationDataSetIterator的MultiDataSetIterator版本
    • ExistingDataSetIterator - (Source) - 转换一个 Iterator<DataSet>Iterable<DataSet> 为 一个 DataSetIterator。 不拆分基础数据集对象
    • FileDataSetIterator - (Source) - 一个迭代器,用于迭代以前用 DataSet.save(File)保存的DataSet文件。支持随机化、过滤、不同的输出批量大小与保存的数据集批量大小等。
    • FileMultiDataSetIterator - (Source) - FileDataSetIterator的MultiDataSet版本。
    • IteratorDataSetIterator - (Source) - 转换一个 Iterator<DataSet> 为一个 DataSetIterator. 与ExistingDataSetIterator不同,底层DataSet对象可以是拆分/组合的——即,对于输出,小批量大小可能与输入迭代器不同。
    • IteratorMultiDataSetIterator - (Source) - IteratorDataSetIterator 的Iterator<MultiDataSet>版本
    • MultiDataSetWrapperIterator - (Source) - 转换一个MultiDataSetIterator 为一个 DataSetIterator。 注意,如果特征和标签数组的数量等于1,才是可能的。
    • MultipleEpochsIterator - (Source) - 当训练时,将基础迭代器的多次训练视为单个训练。
    • WorkspaceShieldDataSetIterator - (Source) - 通常只用于调试,而通常不由用户使用。分离/迁移来自底层DataSetIterator的数据集。

    数据归一化

    ND4J提供了用于执行数据归一化的多个类。这些实现为数据集预处理器。归一化的基本模式:

    1. 创建你的 (非归一化) DataSetIterator 或 MultiDataSetIterator: DataSetIterator myTrainData = ...
    2. 创建你想使用的归一化器: NormalizerMinMaxScaler normalizer = new NormalizerMinMaxScaler();
    3. 拟合归一化器: normalizer.fit(myTrainData)
    4. 在迭代器上设置归一化器/预处理器 : myTrainData.setPreProcessor(normalizer); 最终结果:来自DataSetIterator的数据现在将被归一化。

    通常你应该只在训练数据上拟合,并且与仅在训练数据上拟合的相同的/单一的归一化器一起执行 trainData.setPreProcessor(normalizer)testData.setPreProcessor(normalizer)

    注意,在适当的情况下(NormalizerStandard.,NormalizerMinMaxScaler),诸如平均值/标准偏差/最小值/最小值的统计数据,跨时间(对于时间序列)和跨图像x/y位置(但是对于图像数据不是深度/通道)共享。

    数据归一化示例: 链接

    可用的归一化器: DataSet / DataSetIterator

    • ImagePreProcessingScaler - (Source) - 应用最小最大缩放到图像激活。默认设置将0到255输入到0-1输出(但是是可配置的)。注意,与这里的其他归一化器不同,该归一化器不依赖于从数据收集的统计数据(均值/最小值/最大值 等),因此normalizer.fit(trainData)步骤是不必要的(是非操作性的)。
    • NormalizerStandardize - (Source) - 独立地将每个特征值(和可选的标签值)归一化为0平均值和1的标准差。
    • NormalizerMinMaxScaler - (Source) - 独立归一化每个特征值(以及可选的标签值),使其位于最小值和最大值之间(默认情况下在 0和1之间)
    • VGG16ImagePreProcessor - (Source) - 这是一个专门用于VG16的预处理器。在训练集上计算,减去每个像素RGB的平均值,如在链接中所报告的。

    可用的归一化器: MultiDataSet / MultiDataSetIterator

    • ImageMultiPreProcessingScaler - (Source) - ImagePreProcessingScaler的MultiDataSet/MultiDataSetIterator版本
    • MultiNormalizerStandardize - (Source) - NormalizerStandardize的MultiDataSet/MultiDataSetIterator版本
    • MultiNormalizerMinMaxScaler - (Source) - NormalizerMinMaxScaler的 MultiDataSet/MultiDataSetIterator 版本
    • MultiNormalizerHybrid - (Source) - 一个 MultiDataSet归一化器,可以为 不同的 输入/特征 和输出/标签 数组组合不同的归一化类型(标准化,最小/最大化) 。

    迁移学习

    DL4j具有用于执行迁移学习的类/实用程序——即,采用现有网络,并修改一些层(可选地冻结其他层,以便它们的参数不改变)。例如,可以在ImageNet上训练图像分类器,然后应用于新的/不同的数据集。多层网络和计算图都可以与迁移学习一起使用——通常从模型动物园的预训练模型开始(参见下一节),虽然可以单独使用任何多层网络/计算图。

    链接: 迁移学习示例

    迁移学习的主要类别是TransferLearning。该类具有可用于添加/删除层、冻结层等的构建器模式。FineTuneConfiguration可用于指定非冻结层的学习速率和其他设置。

    训练好的模型库 - Model Zoo

    DL4J提供了一个“model zoo”——一组预训练模型,可以下载和使用(例如,用于图像分类),或者经常用于迁移学习。

    链接: Deeplearning4j Model Zoo

    DL4J 的 model zoo中可用的模型有:

    *: Keras 已训练好的模型 (不是 DL4J 提供) 或许也可以导入, 使用 DL4J的 Keras 模型导入功能。

    速查表代码片段

    Eclipse DL4J库提供了很多功能,我们将这个速查表放在一起,以帮助用户组装神经网络并更快地使用张量。

    神经网络

    用于多层网络和计算图的通用参数和层的配置代码。完整的API见MultiLayerNetworkComputationGraph

    序列网络

    大多数网络配置可以使用多层网络类,如果它们是序列的和简单的。

    MultiLayerConfiguration conf = new NeuralNetConfiguration.Builder()
        .seed(1234)
        // 如下的参数会被复制到网络中的每一层
        // 对于像 dropOut() 或 activation()这样的参数你应该每一层都设置
        // 只指定你需要的参数
        .updater(new AdaGrad())
        .activation(Activation.RELU)
        .dropOut(0.8)
        .l1(0.001)
        .l2(1e-4)
        .weightInit(WeightInit.XAVIER)
        .weightInit(Distribution.TruncatedNormalDistribution)
        .cudnnAlgoMode(ConvolutionLayer.AlgoMode.PREFER_FASTEST)
        .gradientNormalization(GradientNormalization.RenormalizeL2PerLayer)
        .gradientNormalizationThreshold(1e-3)
        .list()
        // 网络中的层,按顺序添加
        // 每层设置的参数覆盖上面设置的参数
        .layer(new DenseLayer.Builder().nIn(numInputs).nOut(numHiddenNodes)
                .weightInit(WeightInit.XAVIER)
                .build())
        .layer(new ActivationLayer(Activation.RELU))
        .layer(new ConvolutionLayer.Builder(1,1)
                .nIn(1024)
                .nOut(2048)
                .stride(1,1)
                .convolutionMode(ConvolutionMode.Same)
                .weightInit(WeightInit.XAVIER)
                .activation(Activation.IDENTITY)
                .build())
        .layer(new GravesLSTM.Builder()
                .activation(Activation.TANH)
                .nIn(inputNum)
                .nOut(100)
                .build())
        .layer(new OutputLayer.Builder(LossFunction.NEGATIVELOGLIKELIHOOD)
                .weightInit(WeightInit.XAVIER)
                .activation(Activation.SOFTMAX)
                .nIn(numHiddenNodes).nOut(numOutputs).build())
        .pretrain(false).backprop(true)
        .build();
    
    MultiLayerNetwork neuralNetwork = new MultiLayerNetwork(conf);
    
    
    image.gif

    复杂网络

    具有复杂图和“分支”的网络需要使用计算图。

    ComputationGraphConfiguration.GraphBuilder graph = new NeuralNetConfiguration.Builder()
        .seed(seed)
       // 如下的参数会被复制到网络中的每一层
        // 对于像 dropOut() 或 activation()这样的参数你应该每一层都设置
        // 只指定你需要的参数  
        .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()
        // 网络中的层,按顺序添加
        // 每层设置的参数覆盖上面设置的参数
        // 注意你必须为每一层命名并手动指定它的输入
        .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")
        .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(),
            "stem-activation1")
        .setOutputs("lossLayer")
        .setInputTypes(InputType.convolutional(224, 224, 3))
        .backprop(true).pretrain(false).build();
    
    ComputationGraph neuralNetwork = new ComputationGraph(graph);
    
    
    image.gif

    训练

    下面的代码片段创建一个基本的管道,从磁盘加载图像,应用随机变换,并将它们拟合到神经网络。它还设置了UI实例,以便你可以可视化进度,并使用早期停止来提前终止训练。你可以为许多不同的用例修改此管道。

    ParentPathLabelGenerator labelMaker = new ParentPathLabelGenerator();
    File mainPath = new File(System.getProperty("user.dir"), "dl4j-examples/src/main/resources/animals/");
    FileSplit fileSplit = new FileSplit(mainPath, NativeImageLoader.ALLOWED_FORMATS, rng);
    int numExamples = Math.toIntExact(fileSplit.length());
    int numLabels = fileSplit.getRootDir().listFiles(File::isDirectory).length; // 在仅在你的根目录是干净的:只有标签子目录的时候才会起作用。
    BalancedPathFilter pathFilter = new BalancedPathFilter(rng, labelMaker, numExamples, numLabels, maxPathsPerLabel);
    
    InputSplit[] inputSplit = fileSplit.sample(pathFilter, splitTrainTest, 1 - splitTrainTest);
    InputSplit trainData = inputSplit[0];
    InputSplit testData = inputSplit[1];
    
    boolean shuffle = false;
    ImageTransform flipTransform1 = new FlipImageTransform(rng);
    ImageTransform flipTransform2 = new FlipImageTransform(new Random(123));
    ImageTransform warpTransform = new WarpImageTransform(rng, 42);
    List<Pair<ImageTransform,Double>> pipeline = Arrays.asList(
        new Pair<>(flipTransform1,0.9),
        new Pair<>(flipTransform2,0.8),
        new Pair<>(warpTransform,0.5));
    
    ImageTransform transform = new PipelineImageTransform(pipeline,shuffle);
    DataNormalization scaler = new ImagePreProcessingScaler(0, 1);
    
    // 训练数据集
    ImageRecordReader recordReaderTrain = new ImageRecordReader(height, width, channels, labelMaker);
    recordReader.initialize(trainData, null);
    DataSetIterator trainingIterator = new RecordReaderDataSetIterator(recordReaderTrain, batchSize, 1, numLabels);
    
    //测试数据集
    ImageRecordReader recordReaderTest = new ImageRecordReader(height, width, channels, labelMaker);
    recordReader.initialize(testData, null);
    DataSetIterator testingIterator = new RecordReaderDataSetIterator(recordReaderTest, batchSize, 1, numLabels);
    
    //早停配置,模型保存器,还有训练器
    EarlyStoppingModelSaver saver = new LocalFileModelSaver(System.getProperty("user.dir"));
    EarlyStoppingConfiguration esConf = new EarlyStoppingConfiguration.Builder()
        .epochTerminationConditions(new MaxEpochsTerminationCondition(50)) //Max of 50 epochs
        .evaluateEveryNEpochs(1)
        .iterationTerminationConditions(new MaxTimeIterationTerminationCondition(20, TimeUnit.MINUTES)) //Max of 20 minutes
        .scoreCalculator(new DataSetLossCalculator(testingIterator, true))     //Calculate test set score
        .modelSaver(saver)
        .build();
    
    EarlyStoppingTrainer trainer = new EarlyStoppingTrainer(esConf, neuralNetwork, trainingIterator);
    
    // 开始训练
    trainer.fit();
    
    
    image.gif

    复杂的转换

    DataVec附带了一个便利的转换进程类,允许更复杂的数据冲突和数据转换。它与2D和序列数据集都能很好地工作。

    Schema schema = new Schema.Builder()
        .addColumnsDouble("Sepal length", "Sepal width", "Petal length", "Petal width")
        .addColumnCategorical("Species", "Iris-setosa", "Iris-versicolor", "Iris-virginica")
        .build();
    
    TransformProcess tp = new TransformProcess.Builder(schema)
        .categoricalToInteger("Species")
        .build();
    
    // 在spark上进行转换
    JavaRDD<List<Writable>> processedData = SparkTransformExecutor.execute(parsedInputData, tp);
    
    
    image.gif

    在创建更复杂的转换之前,我们建议先查看一下 DataVec examples

    评估

    MultiLayerNetwork和ComputationGraph都带有内置的eval()方法,允许你传递数据集迭代器并返回评估结果。

    // 返回具有准确度、精确度、召回和其他类别的统计信息
    Evaluation eval = neuralNetwork.eval(testIterator);
    System.out.println(eval.accuracy());
    System.out.println(eval.precision());
    System.out.println(eval.recall());
    
    // 在多分类数据集上用于曲线下面积的ROC(非二分类)
    ROCMultiClass roc = neuralNetwork.doEvaluation(testIterator, new ROCMultiClass());
    System.out.println(roc.calculateAverageAuc());
    System.out.println(roc.calculateAverageAucPR());
    
    
    image.gif

    对于高级评估,下面的代码片段可以被适用于训练管道。这是当内置的neuralNetwork.eval()方法输出混乱的结果或你需要检查原始数据时需要使用。

    //在测试集上评估模型
    Evaluation eval = new Evaluation(numClasses);
    INDArray output = neuralNetwork.output(testData.getFeatures());
    eval.eval(testData.getLabels(), output, testMetaData); //Note we are passing in the test set metadata here
    
    //从评估对象上获取一个预测错误列表
    //这样的预测误差只有在调用之后才可用。
    iterator.setCollectMetaData(true)
    List<Prediction> predictionErrors = eval.getPredictionErrors();
    System.out.println("\n\n+++++ Prediction Errors +++++");
    for(Prediction p : predictionErrors){
        System.out.println("Predicted class: " + p.getPredictedClass() + ", Actual class: " + p.getActualClass()
            + "\t" + p.getRecordMetaData(RecordMetaData.class).getLocation());
    }
    
    //我们也可以加载原始数据:
    List<Record> predictionErrorRawData = recordReader.loadFromMetaData(predictionErrorMetaData);
    for(int i=0; i<predictionErrors.size(); i++ ){
        Prediction p = predictionErrors.get(i);
        RecordMetaData meta = p.getRecordMetaData(RecordMetaData.class);
        INDArray features = predictionErrorExamples.getFeatures().getRow(i);
        INDArray labels = predictionErrorExamples.getLabels().getRow(i);
        List<Writable> rawData = predictionErrorRawData.get(i).getRecord();
    
        INDArray networkPrediction = model.output(features);
    
        System.out.println(meta.getLocation() + ": "
            + "\tRaw Data: " + rawData
            + "\tNormalized: " + features
            + "\tLabels: " + labels
            + "\tPredictions: " + networkPrediction);
    }
    
    //一此有用的评估方法:
    List<Prediction> list1 = eval.getPredictions(1,2);                  //预测: 实际类 1,预测为类 2
    List<Prediction> list2 = eval.getPredictionByPredictedClass(2);     //预测类2的所有预测
    List<Prediction> list3 = eval.getPredictionsByActualClass(2);       //对实际类2的所有预测
    
    image.gif


    翻译:风一样的男子

    有任何问题请联系微信

    image

    如果您觉得我的文章给了您帮助,请为我买一杯饮料吧!以下是我的支付宝,意思一下我将非常感激!

    image

    相关文章

      网友评论

        本文标题:DL4J中文文档/开始/速查表-2

        本文链接:https://www.haomeiwen.com/subject/bxhizftx.html