2021SC@SDUSC
在深度学习中,损失函数是用来衡量一组参数好坏的函数,其衡量方式是比较网络输出和真实输出的差异。损失函数并不使用测试数据来衡量网络的性能,损失函数用来指导训练过程,使得网络的参数向损失降低的方向改变。损失函数特性1. 当网络的输出值和真实值一致时,损失为0,真实输出和网络输出越不一致时值越大;2. 损失函数要求是凸函数,容易可导。需要根据输出的变化而平滑的变化,如果不容易求导会导致训练过程缓慢。使用损失函数的具体步骤为1. 用随机值初始化前向计算公式的参数;2. 代入样本,计算输出的预测值;3. 用损失函数计算预测值和标签值(真实值)的误差;4. 根据损失函数的导数,沿梯度最小方向将误差回传,修正前向计算公式中的各个权重值;5. 回到第2步,直到损失函数值达到一个满意的值就停止迭代。
神经网络中常用的损失函数为均方差函数(主要用于回归)和交叉熵函数(主要用于分类)。二者都是非负函数,极值在底部,用梯度下降法可以求解。PaddleOCR的损失函数在PaddleOCR-release-2.2->ppocr->losses->cls_loss.py。
# copyright (c) 2019 PaddlePaddle Authors. All Rights Reserve.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from paddle import nn
class ClsLoss(nn.Layer):
def __init__(self, **kwargs):
super(ClsLoss, self).__init__()
self.loss_func = nn.CrossEntropyLoss(reduction='mean')
def forward(self, predicts, batch):
label = batch[1]
loss = self.loss_func(input=predicts, label=label)
return {'loss': loss}
在ClsLoss的__init__函数中我们可以看出PPOCR的方向分类器所使用的的损失函数为CrossEntropyLoss(),交叉熵损失函数。该损失函数结合了nn.LogSoftmax()和nn.NLLLoss()两个函数。它非常适合使用在分类训练中。在训练过程中,对于每个类分配权值,可选的参数权值应该是一个1D张量。交叉熵主要是用来判定实际的输出与期望的输出的接近程度。Pytorch中计算的交叉熵用以下图中的公式计算:
pytorch中的CrossEntropyLoss()函数其实就是把输出结果进行sigmoid(将数据设置到0-1之间),随后再放到传统的交叉熵函数中,就会得到结果。代码如下:
class CrossEntropyLoss(fluid.dygraph.Layer):
def __init__(self,
weight=None,
ignore_index=-100,
reduction='mean',
soft_label=False,
axis=-1,
use_softmax=True,
name=None):
super(CrossEntropyLoss, self).__init__()
self.weight = weight
self.reduction = reduction
self.ignore_index = ignore_index
self.soft_label = soft_label
self.axis = axis
self.use_softmax = use_softmax
self.name = name
def forward(self, input, label):
ret = paddle.nn.functional.cross_entropy(
input,
label,
weight=self.weight,
ignore_index=self.ignore_index,
reduction=self.reduction,
soft_label=self.soft_label,
axis=self.axis,
use_softmax=self.use_softmax,
name=self.name)
return ret