/// <summary> /// 获取梯度列表,同时为了简化运算同时输出损失列表 /// </summary> /// <param name="data"></param> /// <returns>第一个为梯度列表,第二个为损失列表</returns> public Tuple <Tensor[], Tensor[]> GetGradientList(ProcessData data) { Tensor[] gradientList = new Tensor[this.Count]; Tensor[] lossList = new Tensor[this.Count]; List <Tensor> pushes = this.GetAllOutputs(data.Data); Tensor loss; //这里对softmax层进行了特别对待处理,应该如何统一化? if (layers[layerCount - 1].Sign == LayerSign.SoftMaxLayer)//反射是否开销太大了? { loss = data.Label - pushes[this.layerCount - 1]; } else { loss = LossFunc.Loss(data.Label, pushes[this.layerCount - 1]); } Tensor nextWeight = TensorBuilder.FromMatrix(Matrix <double> .Build.DenseIdentity(data.Label[0, 0].RowCount)); LayerSign nextType = LayerSign.Nothing; for (int i = this.layerCount - 1; i >= 2; i--) { (gradientList[i], loss) = layers[i].GetGradient(loss, pushes[i - 1], nextWeight, nextType); lossList[i] = loss; //loss = layers[i].ComputeLoss(loss, pushes[i - 1], nextWeight); nextWeight = layers[i].Weight; nextType = layers[i].Sign; } (gradientList[1], loss) = layers[1].GetGradient(loss, pushes[0], nextWeight, nextType); lossList[1] = loss; //loss = layers[1].ComputeLoss(loss, pushes[0], nextWeight); nextWeight = layers[1].Weight; nextType = layers[1].Sign; (gradientList[0], lossList[0]) = layers[0].GetGradient(loss, data.Data, nextWeight, nextType); return(new Tuple <Tensor[], Tensor[]>(gradientList, lossList)); }
protected override void ApplyLossFunction(ref float score, float label, ref double loss) { loss = LossFunction.Loss(score, label); }
protected override void ApplyLossFunction(ref VBuffer <float> score, float label, ref VBuffer <Double> loss) { VBufferUtils.PairManipulator <Float, Double> lossFn = (int slot, Float src, ref Double dst) => dst = LossFunction.Loss(src, label); VBufferUtils.ApplyWith(ref score, ref loss, lossFn); }