本文转载自微信公众号《小明菜市场》,作者小明菜市场。转载本文请联系小明菜市场公众号。前言长期以来,Java一直是一种非常流行的企业级编程语言,框架丰富,生态完善。Java拥有庞大的开发者社区。尽管深度学习应用不断进步和发展,但相关的深度学习框架对于Java来说相当少见。如今,主要模型都是用Python编译和训练的。对于Java开发者来说,想要学习深度学习,就需要接受一门新语言的洗礼。为了降低Java开发者学习深度学习的成本,AWS构建了一个为Java开发者定制的开源深度学习框架DeepJavaLibrary(DJL),为开发者提供了对接主流深度学习框架的接口。什么是深度学习在开始之前,了解机器学习和深度学习的基本概念。机器学习是利用统计知识将数据输入计算机进行训练,完成特定目标任务的过程。这种归纳学习方法允许计算机学习一些特征并执行一系列复杂的任务,例如识别照片中的对象。深度学习是机器学习的一个分支,主要侧重于人工神经网络的发展。人工神经网络是通过研究人脑如何学习和实现目标而总结出的一组计算逻辑。通过模拟人脑的一部分和神经之间的信息传递过程,可以实现各种复杂的任务。深度学习中的深度会在人工神经网络中进行编译,构建很多层来进一步加深数据信息。传导水平。训练MNIST手写数字识别项目配置使用gradle配置引入依赖包,使用DJL的api包和basicdataset包构建神经网络和数据集。本例中使用MXNet作为深度学习引擎,所以mxnet-engine和mxnet-native-auto两个包,依赖如下plugins{id'java'}repositories{jcenter()}dependencies{implementationplatform("ai.djl:bom:0.8.0")实现"ai.djl:api"实现"ai.djl:basicdataset"//MXNetruntimeOnly"ai.djl.mxnet:mxnet-engine"runtimeOnly"ai.djl.mxnet:mxnet-native-auto"}NDArry和NDManagerNDArray是DJL存储数据结构和数学运算的基本结构。一个NDArry表示一个固定长度的多维数组,NDArry的用法类似于Python的numpy.ndarry。NDManager是NDArry的管理者,负责管理NDArry的生成和回收过程,可以帮助我们更好的优化Java内存。每个NDArry都会由一个NDManager创建,当NDManager关闭时它们会一起关闭。模型在DJL中,训练和推理是从模型类构建的。这里我们在训练过程中主要使用构造方法。接下来,我们为Model创建一个新的target,因为Model也继承了AutoClosable结构,并且使用了tryblock实现。try(Modelmodel=Model.newInstance()){...//主要训练代码...}准备数据MNIST数据库包含大量手写数字图片,通常用于训练图像处理系统。DJL收集了MNIST数据在basicdataset数据中,每张MNIST图的大小为28*28,如果你有自己的数据集,也可以用同样的方法收集数据。数据集导入教程http://docs.djl.ai/docs/development/how_to_use_dataset.html#how-to-create-your-own-datasetintbatchSize=32;//batchsizeMnisttrainingDataset=Mnist.builder().optUsage(Usage.TRAIN)//训练集.setSampling(batchSize,true).build();MnistvalidationDataset=Mnist.builder().optUsage(Usage.TEST)//验证集.setSampling(batchSize,true).build();这段代码分别做训练集和验证集。同时,我们也随机安排了数据集,以便更好地训练。除了这些配置之外,您还可以对图片进行进一步的设置,例如设置图片大小、归一化等。制作模型并创建块。数据集准备好后,就可以构建神经网络了。在DJL中,神经网络由Block代码块组成。Block是具有各种神经网络特征的结构。它们可以代表一个运行中的神经网络。网络的一部分,甚至是一个完整的神经网络,然后块可以顺序或并行执行。同时,块本身也可以有参数和子块。这种嵌套结构可以快速帮助更新可维护的神经网络。在训练过程中,每个block附带的参数也会实时更新,其子block也会同时更新。我们在搭建这些block的时候,最简单的方法就是一个一个嵌套,直接使用准备好的DJLBlock类型,就可以快速搭建出各种神经网络。Block变体根据几种基本的神经网络工作模式,我们提供了Block的几种变体。SequentialBlock就是输出作为下一个block的输入,一直执行到最后。parallelblock用于将一个输入并行输入到每个子块中,同时也将输出结果按照特定的组合方程进行组合。Lambdablock是一个帮助用户执行快速操作的块。它没有任何参数,因此在训练期间不会更新任何部分。构建多层感知器MLP神经网络我们构建了一个简单的多层感知器神经网络。多层感知器是一个简单的前向神经网络,只包含几个完全连接的层。构建这个网络,可以直接使用sequentialblockinput=28*28;//输入层大小intoutput=10;//输出层大小int[]hidden=newint[]{128,64};//隐藏层大小SequentialBlocksequentialBlock=newSequentialBlock();sequentialBlock.add(Blocks.batchFlattenBlock(input));for(inthiddenSize:hidden){//全连接层sequentialBlock.add(Linear.builder().setUnits(hiddenSize).build());//激活函数sequentialBlock.add(activation);}sequentialBlock.add(Linear.builder().setUnits(output).build());您可以使用直接提供的MLPBlockBlockblock=newMlp(Mnist.IMAGE_HEIGHT*Mnist.IMAGE_WIDTH,Mnist.NUM_CLASSES,newint[]{128,64});Training使用以下步骤完成一个训练过程初始化:我们会对每个Block的参数进行初始化,初始化每个参数的函数由setinitializer决定。前向传播:这一步将输入数据在神经网络中逐层传递,然后生成输出数据。计算损失:我们会根据特定的损失函数损失来计算输出与标注结果之间的偏差。反向传播:在这一步中,使用损失的反向导数计算每个参数的梯度。更新权重将根据选择的优化器更新Block上每个参数的值。精简后的DJL使用了Trainer结构,简化了整个流程。开发者只需要创建一个Trainer,并指定相应的initializer、loss、optimizer即可。这些参数由TrainingConfig设置。查看参数设置。TrainingListener训练过程中设置的监听器,可以实时反馈每个阶段的训练结果。这些结果可以用来记录训练过程或者帮助调试神经网络训练过程中遇到的问题。用户可以自定义自己的TrainingListener来监控训练过程){//训练代码}训练生成后,可以定义输入Shape,然后调用git函数进行训练,结果会保存在本地目录/**MNIST包含28x28灰度图并导入变成28*28ND数组。*第一维是batchsize,这里我们将batchsize设置为1进行初始化。*/ShapeinputShape=newShape(1,Mnist.IMAGE_HEIGHT*Mnist.IMAGE_WIDTH);intnumEpoch=5;StringoutputDir="/build/model";//用输入初始化trainertrainer.initialize(inputShape);TrainingUtils.fit(trainer,numEpoch,trainingSet,validateSet,outputDir,"mlp");输出的结果图[INFO]-Downloadinglibmxnet.dylib...[INFO]-Trainingon:cpu().[INFO]-LoadMXNetEngineVersion1.7.0in0.131ms.Training:100%|████████████████████████████████████████|精度:0.93,Softmax交叉熵损失:0.24,速度:1235.20项/秒验证:100%|████████████████████████████████████████|[INFO]-Epoch1finished.[INFO]-Train:Accuracy:0.93,SoftmaxCrossEntropyLoss:0.24[INFO]-Validate:Accuracy:0.95,SoftmaxCrossEntropyLoss:0.14Training:100%|████████████████████████████████████████|准确度:0.97,Softmax交叉熵损失:0.10,速度:2851.06项/秒验证:100%|████████████████████████████████████████|[信息]-Epoch2finished.NG[1m41s][信息]-火车:准确度:0.97,SoftmaxCrossEntropyLoss:0.10[信息]-验证:准确cy:0.97,SoftmaxCrossEntropyLoss:0.09[INFO]-trainP50:12.756ms,P90:21.044ms[INFO]-forwardP50:0.375ms,P90:0.607ms[INFO]-training-metricsP50:0.021ms,P90:0.034ms[INFO]]]-backwardP50:0.608ms,P90:0.973ms[INFO]-stepP50:0.543ms,P90:0.869ms[INFO]-epochP50:35.989s,P90:35.989s训练结束后可以识别模型,used关于作者,我是笑笑,一个出生在二线城市,生活在一线城市的笑笑。本期结束,我们下期再见。
