Ejemplo n.º 1
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);
        }