Ejemplo n.º 1
0
 /// <summary>
 /// 前向传播,计算卷积结果
 /// </summary>
 public double[,] CalculatedConvolutionResult(List <double[, ]> value)
 {
     InputValue       = value;
     double[,] result = new double[ConvolutionKernelWidth, ConvolutionKernelHeight];
     for (int i = 0; i < ConvolutionKernelWidth; i++)
     {
         for (int j = 0; j < ConvolutionKernelHeight; j++)
         {
             for (int k = 0; k < value.Count; k++)
             {
                 result[i, j] += CalculatedConvolutionPointResult(value[k], i, j, k);//卷积
             }
         }
     }
     if (Standardization)
     {
         mean     = CnnHelper.GetMean(result);
         variance = CnnHelper.GetVariance(result, mean);
     }
     //归一化每个结果
     for (int i = 0; i < ConvolutionKernelWidth; i++)
     {
         for (int j = 0; j < ConvolutionKernelHeight; j++)
         {
             if (Standardization)
             {
                 //调用激活函数计算结果
                 double z = (result[i, j] - mean) / Math.Sqrt(variance);
                 //if (double.IsNaN(z))
                 //    z = result[i, j] > 0 ? 1 : -1;
                 result[i, j] = ActivationFunction(z + OutputOffset);
             }
             else
             {
                 result[i, j] = ActivationFunction(result[i, j] + OutputOffset);
             }
         }
     }
     //正则化
     if (CnnHelper.RandomObj.NextDouble() < dropoutChance)
     {
         for (int i = 0; i < ConvolutionKernelWidth; i++)
         {
             for (int j = 0; j < ConvolutionKernelHeight; j++)
             {
                 result[i, j] = 0;
             }
         }
         dropoutState = true;
     }
     OutputValue = result;
     return(result);
 }
Ejemplo n.º 2
0
 /// <summary>
 /// 前向传播,计算结果
 /// </summary>
 public double[] CalculatedResult(double[] inputValue)
 {
     InputValue = inputValue;
     double[] result = new double[OutputCount];
     for (int i = 0; i < OutputCount; i++)
     {
         result[i] = CalculatedPointResult(inputValue, i);
         //result[i] = CalculatedPointResult(value, i) + OutputOffset[i];
         //调用激活函数计算结果
         if (!Standardization)
         {
             result[i] = ActivationFunction(result[i] + OutputOffset[i]);
         }
     }
     if (Standardization)
     {
         mean     = CnnHelper.GetMean(result);
         variance = CnnHelper.GetVariance(result, mean);
         //归一化每个结果
         for (int i = 0; i < OutputCount; i++)
         {
             //调用激活函数计算结果
             double z = (result[i] - mean) / Math.Sqrt(variance);
             result[i] = ActivationFunction(z + OutputOffset[i]);
         }
     }
     //正则化
     if (CnnHelper.RandomObj.NextDouble() < dropoutChance)
     {
         for (int i = 0; i < OutputCount; i++)
         {
             result[i] = 0;
         }
         dropoutState = true;
     }
     OutputValue = result;
     return(result);
 }
Ejemplo n.º 3
0
        /// <summary>
        /// 计算反向传播结果
        /// </summary>
        /// <returns></returns>
        private List <double[, ]> CalculatedBackPropagationResult(double[,] residual, double learningRate)
        {
            //上一层残差
            List <double[, ]> result = new List <double[, ]>();
            //当前层残差
            //double[,] residualNow = new double[ConvolutionKernelWidth, ConvolutionKernelHeight];
            //权重残差
            List <double[, ]> deltaWeight = new List <double[, ]>();
            //偏置残差
            double deltaOffset = 0;

            //正则化
            if (dropoutState)
            {
                for (int inputIndex = 0; inputIndex < InputCount; inputIndex++)
                {
                    result.Add(new double[inputWidth, inputHeight]);
                }
                dropoutState = false;
                return(result);
            }
            //残差
            for (int i = 0; i < ConvolutionKernelWidth; i++)
            {
                for (int j = 0; j < ConvolutionKernelHeight; j++)
                {
                    //residual[i, j] = ActivationFunctionDerivative(OutputValue[i, j]) * (output[i, j] - OutputValue[i, j]);
                    //residual[i, j] = (output[i, j] - OutputValue[i, j]);//正确
                }
            }
            for (int inputIndex = 0; inputIndex < InputCount; inputIndex++)
            {
                double[,] tmpResultDelta = CnnHelper.ConvolutionFull(CnnHelper.MatrixRotate180(ShareWeight[inputIndex]), residual);//CNN标准
                //double[,] tmpResultDelta = CnnHelper.ConvolutionFull(ShareWeight[inputIndex], residual);//CNN例子
                result.Add(tmpResultDelta);
                //double[,] tmpDeltaWeight = CnnHelper.ConvolutionValid(residual, CnnHelper.MatrixRotate180(InputValue[inputIndex]));//CNN例子
                double[,] tmpDeltaWeight = CnnHelper.MatrixRotate180(CnnHelper.ConvolutionValid(residual, CnnHelper.MatrixRotate180(InputValue[inputIndex])));//CNN标准
                deltaWeight.Add(tmpDeltaWeight);
            }
            //计算偏置残差
            for (int i = 0; i < ConvolutionKernelWidth; i++)
            {
                for (int j = 0; j < ConvolutionKernelHeight; j++)
                {
                    deltaOffset += residual[i, j];
                }
            }
            //计算平均梯度

            /*
             * meanListDeltaWeight.Add(deltaWeight);
             * for (int inputIndex = 0; inputIndex < InputCount; inputIndex++)
             * {
             *  for (int i = 0; i < receptiveFieldWidth; i++)
             *  {
             *      for (int j = 0; j < receptiveFieldHeight; j++)
             *      {
             *          if (meanListDeltaWeight.Count > miniBatchSize)
             *          {
             *              meanDeltaWeight[inputIndex][i, j] -= meanListDeltaWeight[0][inputIndex][i, j] / miniBatchSize;
             *              meanDeltaWeight[inputIndex][i, j] += deltaWeight[inputIndex][i, j] / miniBatchSize;
             *              meanListDeltaWeight.RemoveAt(0);
             *          }
             *          else
             *          {
             *              meanDeltaWeight[inputIndex][i, j] = 0;
             *              foreach (var tmpShareWeight in meanListDeltaWeight)
             *              {
             *                  meanDeltaWeight[inputIndex][i, j] += tmpShareWeight[inputIndex][i, j] / meanListDeltaWeight.Count;
             *              }
             *          }
             *      }
             *  }
             * }
             * meanListDeltaOffset.Add(deltaOffset);
             * if (meanListDeltaOffset.Count > miniBatchSize)
             * {
             *  meanDeltaOffset -= meanListDeltaOffset[0] / miniBatchSize;
             *  meanDeltaOffset += deltaOffset / miniBatchSize;
             *  meanListDeltaOffset.RemoveAt(0);
             * }
             * else
             * {
             *  meanDeltaOffset = 0;
             *  foreach (var tmpShareOffset in meanListDeltaOffset)
             *  {
             *      meanDeltaOffset += tmpShareOffset / meanListDeltaOffset.Count;
             *  }
             * }
             * //*/
            //计算正确输入值
            for (int inputIndex = 0; inputIndex < InputCount; inputIndex++)
            {
                for (int i = 0; i < inputWidth; i++)
                {
                    for (int j = 0; j < inputHeight; j++)
                    {
                        //resultDelta[inputIndex][i, j] *= ActivationFunctionDerivative(InputValue[inputIndex][i, j]);
                        if (Standardization)
                        {
                            //反归一化每个结果
                            result[inputIndex][i, j] = result[inputIndex][i, j] * Math.Sqrt(variance) + mean;
                        }
                    }
                }
            }
            //更新权重和偏置
            UpdateWeight(deltaWeight, learningRate);
            UpdateOffset(deltaOffset, learningRate);
            //UpdateWeight(meanDeltaWeight, learningRate);
            //UpdateOffset(meanDeltaOffset, learningRate);
            //调试参数
            //debugResult = resultDelta;
            //debugResidual = residual;
            //debugDeltaWeight = deltaWeight;
            //debugDeltaOffset = deltaOffset;
            return(result);
        }