private void Forward(TensorOld input, int sampleIndex, int filterIndex) { var filterOff = Filters.GetRawOffset(filterIndex, 0, 0, 0); Parallel.For(0, outRows, row => { var startRow = row * RowStride; Parallel.For(0, outColumns, col => { var startCol = col * ColumnStride; var sum = 0d; for (int i = 0; i < FilterRows; i++) { var filterStart = i * filterRowLength; var inputOff = input.GetRawOffset(sampleIndex, startRow + i, startCol, 0); for (int j = 0; j < filterRowLength; j++) { sum += input.values[inputOff + j] * Filters.values[filterStart + j]; } } ForwardOutput.SetValueFast(sum + Bias.values[filterIndex], sampleIndex, row, col, filterIndex); }); }); }
private void ComputeDerivative() { var derData = Derivative.GetRawValues(); var outData = ForwardOutput.GetRawValues(); Parallel.For(0, sampleNumber, sampleIndex => { var outStart = ForwardOutput.GetRawOffset(sampleIndex, 0); Parallel.For(0, categoryNumber, i => { var derStart = Derivative.GetRawOffset(sampleIndex, i, 0); for (int j = 0; j < categoryNumber; j++) { if (i == j) { derData[derStart + j] = outData[(int)(outStart + i)] * (1 - outData[(int)(outStart + j)]); } else { derData[derStart + j] = -outData[(int)(outStart + i)] * outData[(int)(outStart + j)]; } } }); }); }
private void ComputeCrossEntropy(TensorOld y, TensorOld yHat) { var foreoutData = ForwardOutput.GetRawValues(); for (int i = 0; i < sampleNumber; i++) { //取出一个样本及其对应的Label y.GetByDim1(i, yBuff); yHat.GetByDim1(i, yHatBuff); //计算交叉熵 foreoutData[i] = Functions.CrossEntropy(yBuff, yHatBuff); } Array.Copy(y.values, 0, BackwardOutput.values, 0, y.ElementCount); }
public override double GetLoss(TensorOld y, TensorOld yHat) { var outData = ForwardOutput.GetRawValues(); var result = 0d; for (int i = 0; i < y.shape[0]; i++) { //取出一个样本及其对应的Label y.GetByDim1(i, yBuff); yHat.GetByDim1(i, yHatBuff); //计算交叉熵 result += Functions.CrossEntropy(yBuff, yHatBuff); } return(result / sampleNumber); }
private void ComputeCrossEntropy(TensorOld y, TensorOld yHat) { var forwardoutData = ForwardOutput.GetRawValues(); var backwardoutData = BackwardOutput.GetRawValues(); for (int i = 0; i < sampleNumber; i++) { //取出一个样本及其对应的Label y.GetByDim1(i, yBuff); yHat.GetByDim1(i, yHatBuff); //计算交叉熵 forwardoutData[i] = Functions.CrossEntropy(yBuff, yHatBuff); //计算损失函数关于输入的导数 Derivatives.CrossEntropy(yBuff, yHatBuff, derBuff); Array.Copy(derBuff, 0, backwardoutData, i * derBuff.Length, derBuff.Length); } }
/// <summary> /// 获取最近一次Forward的所有样本Loss的平均值。 /// 通过ForwardOutput可以获取每个样本的Loss /// </summary> /// <returns>Loss平均值</returns> public double GetLoss() { return(ForwardOutput.Mean()); }
public override double GetAccuracy() { return(Math.Sqrt(ForwardOutput.Mean())); }