欢迎光临散文网 会员登陆 & 注册

股票量化软件:赫兹量化系统神经网络轻松学---舍弃

2023-10-09 16:04 作者:大牛啊呢  | 我要投稿

舍弃:提升神经网络收敛性的一种方法

在训练神经网络时,会将大量特征馈入每个神经元,且很难评估每个独立特征的影响。 结果就是,某些神经元的误差会被其他神经元的调整值抹平,这些误差从而会在神经网络输出处累积。 这会导致训练在某个局部最小值处停止,且误差较大。 这种效应涉及特征检测器的协同适应,其中每个特征的影响会随环境而变化。 当环境分解成单独的特征,且可以分别评估每个特征的影响时,很可能会有相反的效果。

2010年,多伦多大学的一组科学家提议从学习过程中随机排除一些神经元,作为复杂协同适应问题的解决方案 [12]。 训练中减少特征的数量,会增加每个特征的重要性,且特征的数量和质量构成的持续变化降低了它们协同适应的风险。 此方法称为舍弃。 有时拿这种方法的应用与决策树进行比较:通过舍弃一些神经元,我们在每次训练迭代中获得一个含有其自身权重的新神经网络。 根据组合规则,这样的网络具有很大的可变性。

实现

如今,我们已研究过理论方面,我们来继续研究如何在函数库中实现此方法的变体。 我们遇到的第一件事是实现两种不同算法。 其一在训练过程需要,而第二个则用于生产。 相应地,我们需要根据每种独立情况,为神经元明确指出应采用的算法。 为此目的,我们将在基准神经元级别引入 bTrain 标志。 该标志值对于训练 应设为 true,而对于测试 则设为 false。

class CNeuronBaseOCL    :  public CObject  { protected:   bool               bTrain;             ///< Training Mode Flag


以下辅助方法将控制该标志值。

  virtual void      TrainMode(bool flag)             {  bTrain=flag;            }///< Set Training Mode Flag       virtual bool      TrainMode(void)                  {  return bTrain;          }///< Get Training Mode Flag    

该标志特意在基准神经元级别实现。 如此在以后开发时能够启用舍弃相关的代码。

2.1. 为我们的模型创建一个新类

为了实现舍弃算法,我们来创建新的 CNeuronDropoutOCL 类,它将包含在我们的模型当中作为单独的层。 新类将直接继承自 CNeuronBaseOCL 基准神经元类。 在受保护模块中声明变量:


  • OutProbability — 指定神经元的舍弃概率。

  • OutNumber  — 神经元的舍弃数量。

  • dInitValue  — 掩码向量初始化值;在本文的理论部分,该系数被指定为 1/q。

另外,声明两个指向类的指针:

  • DropOutMultiplier  — 舍弃向量。

  • PrevLayer  — 指向上一层对象的指针;它在测试和实际应用时会用到。

class CNeuronDropoutOCL    :  public   CNeuronBaseOCL  { protected:   CNeuronBaseOCL    *PrevLayer;   double            OutProbability;   double            OutNumber;   CBufferDouble     *DropOutMultiplier;   double            dInitValue; //---   virtual bool      feedForward(CNeuronBaseOCL *NeuronOCL);               ///<\brief Feed Forward method of calling kernel ::FeedForward().@param NeuronOCL Pointer to previous layer.   virtual bool      updateInputWeights(CNeuronBaseOCL *NeuronOCL) {return true;}        ///< Method for updating weights.@param NeuronOCL Pointer to previous layer. //---   int               RND(void)   { xor128; return (int)((double)(Neurons()-1)/UINT_MAX*rnd_w);  }   ///< Generates a random neuron position to turn off public:                     CNeuronDropoutOCL(void);                    ~CNeuronDropoutOCL(void); //---   virtual bool      Init(uint numOutputs, uint myIndex, COpenCLMy *open_cl, uint numNeurons,double out_prob, ENUM_OPTIMIZATION optimization_type);    ///< Method of initialization class.@param[in] numOutputs Number of connections to next layer.@param[in] myIndex Index of neuron in layer.@param[in] open_cl Pointer to #COpenCLMy object. #param[in] numNeurons Number of neurons in layer #param[in] out_prob Probability of neurons shutdown @param optimization_type Optimization type (#ENUM_OPTIMIZATION)@return Boolen result of operations. //---   virtual int       getOutputIndex(void)          {  return (bTrain ? Output.GetIndex() : PrevLayer.getOutputIndex());             }  ///< Get index of output buffer @return Index   virtual int       getGradientIndex(void)        {  return (bTrain ? Gradient.GetIndex() : PrevLayer.getGradientIndex());          }  ///< Get index of gradient buffer @return Index   //---   virtual int       getOutputVal(double &values[])   {  return (bTrain ? Output.GetData(values) : PrevLayer.getOutputVal(values)); }  ///< Get values of output buffer @param[out] values Array of data @return number of items   virtual int       getOutputVal(CArrayDouble *values)   {  return (bTrain ? Output.GetData(values) : PrevLayer.getOutputVal(values)); }  ///< Get values of output buffer @param[out] values Array of data @return number of items   virtual int       getGradient(double &values[])    {  return (bTrain ? Gradient.GetData(values) : PrevLayer.getGradient(values));    }  ///< Get values of gradient buffer @param[out] values Array of data @return number of items   virtual CBufferDouble   *getOutput(void)           {  return (bTrain ? Output : PrevLayer.getOutput());      }                 ///< Get pointer of output buffer @return Pointer to object   virtual CBufferDouble   *getGradient(void)         {  return (bTrain ? Gradient : PrevLayer.getGradient());  }                 ///< Get pointer of gradient buffer @return Pointer to object //---   virtual bool      calcInputGradients(CNeuronBaseOCL *NeuronOCL);          ///< Method to transfer gradient to previous layer by calling kernel ::CalcHiddenGradient(). @param NeuronOCL Pointer to next layer.   //---   virtual bool      Save(int const file_handle);///< Save method @param[in] file_handle handle of file @return logical result of operation   virtual bool      Load(int const file_handle);///< Load method @param[in] file_handle handle of file @return logical result of operation //---   virtual int       Type(void)        const                      {  return defNeuronDropoutOCL;                }///< Identificator of class.@return Type of class  };


股票量化软件:赫兹量化系统神经网络轻松学---舍弃的评论 (共 条)

分享到微博请遵守国家法律