当前位置: 首页 > 科技观察

从程序员的角度设计基于Java的神经网络

时间:2023-03-12 19:16:48 科技观察

人工神经网络(ANN)或连接系统是受构成生物大脑的生物神经网络启发的计算系统。这样的系统通过考虑示例来学习(逐步提高性能)来完成任务,通常不需要特定于任务的编程。要用Java或任何其他编程语言设计神经网络,我们需要了解人工神经网络的结构和功能。ANN像专家一样执行模式识别、从数据中学习和预测趋势等任务,这与需要执行一组步骤才能实现定义目标的传统算法方法不同。由于其高度交互的网络结构,人工神经网络可以学习如何自行解决一些任务。人工神经元具有与人脑神经元相似的结构。天然神经元由细胞核、树突和轴突组成。轴突延伸到几个分支,与其他神经元的树突形成突触。到目前为止,我们已经区分了神经元的结构和连接的神经元网络。另一个重要方面是神经网络的处理或计算,分别与单个神经元相关联。神经元自然是信号处理器——它们在树突中接收微小信号,这些信号会触发轴突中的信号。有一个潜在的阈值,当达到该阈值时,会刺激轴突并将信号传播到其他神经元。因此,我们可以将人工神经元想象成在输入端有一个信号接收器,在输出端有一个激活单元,它可以发送信号,这些信号将被转发给其他神经元,类似于图中所示:神经元具有相应的权重,可以修改信号,从而影响神经元的输出。由于权重在神经网络内部并影响其输出,因此可以将它们视为神经网络的内部学科,调整描述神经元与其他神经元或外部世界连接的权重将反映神经网络的能力网络。如Bioinfo出版物所述:人工神经元接收一个或多个输入(代表树突)并将它们相加以产生输出/激活(代表神经元的轴突)。通常每个节点的总和被加权并且总和通过激活函数或传递函数。由于自然神经元的非线性行为,该组件将非线性添加到神经网络处理中。在某些特殊情况下,它可以是线性函数。维基百科提到:一个标准的计算机芯片电路可以看作是激活函数的数字网络,取决于输入是“ON”(1)还是“OFF”(0)。这类似于神经网络中线性感知器的行为。然而,非线性激活函数允许此类网络仅使用少量节点来解决特殊问题。常用的激活函数示例有S型函数、双曲正切函数、硬限制阈值和纯线性函数。将这些知识转换成Java代码,我们将有一个神经元类,如下所示:/***Representsaneuronmodelcomprisedof(由以下部分组成的神经元模型):
*

    *
  • Summingpart(求和部分)-inputsummingfunction(输入求和函数)
  • *
  • Activationfunction(激活function)
  • *
  • Inputconnections(输入连接)
  • *
  • Outputconnections(输出连接)
  • *
*/publicclassNeuron{/***Neuron的标识符*Neuronidentifier*/privateStringid;/***Collectionofneuron'sinputconnections(connectionstothisneuron)*Collectionofneuroninputconnections(connectionstothisneuron)*/protectedListinputConnections;/***Collectionofneuron'soutputconnections(connectionsfromthistoother*neurons)*一个集合神经元输出连接(从这个到其他神经元的连接)*/protectedListoutputConnections;/***Inputsummingfunctionforthisneuron*这个神经元的输入和函数*/protectedInputSummingFunctioninputSummingFunction;/***这个neu的激活函数ron*这个神经元的激活函数*/protectedActivationFunctionactivationFunction;/***Defaultconstructor*默认构造方法*/publicNeuron(){this.inputConnections=newArrayList<>();this.outputConnections=newArrayList<>();}/***Calculatestheneuron'soutput*计算神经元输出*/publicdoublecalculateOutput(){doubletotalInput=inputSummingFunction.getOutput(inputConnections);returnactivationFunction.getOutput(totalInput);}...}神经元有输入输出连接,输入求和值和激活函数,输入权重在哪里?它们包含在连接本身中,如下所示:神经元(源神经元)Thisconnectionisaoutputconnectionfromaneuron*/protectedNeuronfromNeuron;/***Toneuronforthisconnection(target,destinationneuron)This*connectionisinputconnectionfortoneuron.*对于这个连接使用的神经元(target,destinationneuron),这个连接是针对这个神经元的输入连接*/protectedNeurontoNeuron;/***Connectionweight*connectionweight*/protecteddoubleweight;/***Createsanewconnectionbetweenspecifiedneuronswithrandomweight.*在具有随机权重的指定神经元之间创建新连接*@paramfromNeuron*neurontoconnectfrom*@paramtoNeuron*neurontoconnectto*/publicNeuronsConnection(NeuronfromNeuron,NeurontoNeuron){this.fromNeuron=fromNeuron;this.toNeuron=toNeuron;this.weight=Math.random();}/***Createsanewconnectiontospecifiedneuronwithspecifiedweightobject*Createsanewconnectiontospecifiedneuronwithspecifiedweightobject*用指定的权重对象创建到指定神经元的新连接**@paramfromNeuron*neurontoconnectfrom*@paramtoNeuron*neurontoconnectto*@paramweight*weightforthisconnection*/publicNeuronsConnection(NeuronfromNeuron,NeurontoNeuron,doubleweight){this(fromNeuron,toNeuron);this.weight=weight;}/***Returnsweightforthisconnection*返回此连接的连接权重*@returnweightforthisconnection*/publicdoublegetWeight(){rreturnweight;}/***Settheweightoftheconnection.*设置连接的权重*@paramweight*Thenewweightoftheconnectiontobeset*/publicvoidsetWeight(doubleweight){this.weight=weight;}/***返回inputofthisconnection-theactivationfunctionresult*calculatedintheinputneuronofthisconnection.*返回输入ofthisconnection-该连接的输入神经元中激活函数的计算结果*@returninputreceivedthroughthisconnection*/publicdoublegetInput(){returnfromNeuron.calculateOutput();}/***Returnstheweightedinputofthisconnection*Returnstheweightedinputofthisconnection*@returnweightedinputoftheconnection*/publicdoublegetWeightedInput({returnfromNeuron.calculateOutput()*weight;}/***Getsfromneuronforthisconnection*从一个神经元获取这个连接*@returnfromneuronforthisconnection*/publicNeurongetFromNeuron(){returnfromNeuron;}/***Getstoneuronforthisconnection*为这个连接获取一个神经元*@returnneurontosetastoneuron*/publicNeurongetToNeuron(){重新turntoNeuron;}...}连接对象提供权重,负责计算输入的权重sum函数被定义为一个接口,可以替代神经元的计算策略:importjava.util.List;importedu.neuralnet.core.Connection;Collector*/publicinterfaceInputSummingFunction{/***根据输入神经元的输出值进行计算。*根据输入神经元的输出值进行计算。*@paraminputConnections*神经元的输入连接*@return具有输入连接的神经元的总输入*总输入,具有输入连接的神经元*/doublecollectinputConnections);}分别实现为:importjava.util.List;importedu.neuralnet.core。Connection;/***计算输入神经元输出的加权和。*计算输入神经元输出的加权和*/publicfinalclassWeightedSumFunctionimplementsInputSummingFunction{/***{@inheritDoc}*/@OverridepublicdoublecollectOutput(ListinputConnections){doubleweightedSum=0d;for(Connectionconnection:inputConnections){weightedSum+=connection.getWeightedInput();}returnweightedSum;}}激活函数的接口可以定义如下::/***Neuralnetworksactivationfunctioninterface.*神经网络激活激活函数接口*/publicinterfaceActivationFunction{/***Performscalculationbasedonthesumofinputneuronsoutput.*Calculationsbasedonthesumofinputneuronsoutput*@paramsummedInput*neuron'ssumofoutputsrespectivelyinputsfortheconnected*neuron**@returnOutput'scalculationbasedonthesumofinputs*Outputcalculation(doublesummedInput);}最后要做的在开始编码之前要知道的是神经网络层神经网络由几个链接层组成,形成所谓的多层网络。神经层可以分为三类:输入层隐藏层输出层在实践中,额外的神经层为外部刺激增加了另一个抽象层次,增强了神经网络识别更复杂知识的能力。层类可以定义为连接神经元的列表:importjava.util.ArrayList;importjava.util.List;它由多个连接层组成所谓的多层网络,*一个层可以定义为一组包含一个神经网络层的神经元*/publicclassNeuralNetLayer{/***Layer'sidentifier*levelidentifier*/privateStringid;/***Collectionofneuronsinthislayer*本层神经元的集合*/protectedListneurons;/***Createsanemptylayerwithanid.*创建一个空层ID*@paramid*layer'identifier*/publicNeuralNetLayer(Stringid){this.id=id;neurons=newArrayList<>();}/***Createsalayerwithalistofneuronsandanid.*Createsalayerwithalistofneuronsandanid.*Createalayerwithalistofneuronsandid*@paramid*layer'identifierlevelidentifier*@paramneurons*listofneuronstobeaddedtothelayer添加到层的列表中neurons*/publicNeuralNetLayer(Stringid,Listneurons){this.id=id;this.neurons=neurons;}...}***,用Java创建一个简单的神经网络:/***代表一个包含神经元层的人工神经网络。*具有一层神经元的人工神经网络*/publicclassNeuralNet{/***神经网络orkid*神经网络ID*/privateStringid;/***Neuralnetworkinputlayer*神经网络的输入层*/privateNeuralNetLayerinputLayer;/***Neuralnetworkhiddenlayers*神经网络隐藏层*/privateListhiddenLayers;/***Neuralnetworkoutputlayer*neural网络的输出层*/privateNeuralNetLayeroutputLayer;/***Constructsaneuralnetwithalllayerspresent.*构造一个所有层都存在的神经网络*@paramid*Neuralnetworkidtobeset设置神经网络ID*@paraminputLayer*Neuralnetworkinputlayertobeset设置神经网络的输入层*@paramhiddenLayers*Neuralnetworkhiddenneurallayerstobesets网络隐藏层*@paramoutputLayer*Neuralnetworkoutputlayertobeset设置神经网络的输出层*/publicNeuralNet(Stringid,NeuralNetLayerinputLayer,ListhiddenLayers,NeuralNetLayeroutputLayer){this.id=id;this.inputLayer=inputLayer;this=hiddenLayershiddenthis.outputLayer=outputLayer;}/***Constructsaneuralnetwithouthiddenlayers.*构造一个没有隐藏层的神经网络*@paramid*Neuralnetworkidtobeset设置神经网络ID*@paraminputLayer*Neuralnetworkinputlayertobeset设置神经网络的输入层*@paramoutputLayer*Neuralnetworkoutputlayertobeset设置神经网络的隐藏层*/publicNeuralNet(Stringid,NeuralNetLayerinputLayer,NeuralNetLayeroutputLayer){this.id=id;this.inputLayer=inputLayer;this.outputLayer=outputLayer;}...}我们得到的是一个Java-基于神经网络层、神经元和连接的结构定义我们还讨论了一些激活函数并为它们定义了一个接口。为简单起见,我们省略了各种激活函数的实现和学习神经网络的基础知识。这两个主题将在本系列的后续文章中介绍。原文链接:https://cloud.tencent.com/developer/article/1038393作者:DanielaKolarova【本文为专栏作者“云家社区”原创稿件,转载请联系原作者获得授权】点此看文章作者更多好文章