损失函数
损失函数的作用是:用于描述模型预测值与真实值的差距大小,通过真实值与预测值来指导模型的收敛方向。如果损失函数没有使用正确,这是一个非常严重的问题,他会导致最终都难以训练出正确的模型。毕竟我们在做梯度下降的时候需要找到的是最小损失值,求损失值得方法都是错的,再怎么搞都是南辕北辙。可以换一种简单点理解就是,损失函数得到的损失值越小就表示我们的预测值越接近真实值。
既然这么重要,那看看都有那些损失函数吧!
均值平方差(Mean Squared Error ,MSE)
又称为均方误差,数理统计中表示为:参数估计值与参数真实值之差平方的期望值。公式:
M
S
E
=
1
n
∑
i
=
1
n
(
a
b
s
e
r
v
d
e
i
−
p
r
e
d
i
c
t
e
d
i
)
2
MSE=\frac{1}{n}\sum_{i=1}^{n}(abservde_{i}-predicted_{i})^{2}
MSE=n1i=1∑n(abservdei−predictedi)2
均方误差的值越小,表明模型越好,类似的损失函数还有
- 均方根误差RMSE,对MSE进行开方操作即可,公式:
M S E = 1 n ∑ i = 1 n ( a b s e r v d e i − p r e d i c t e d i ) 2 MSE=\sqrt{\frac{1}{n}\sum_{i=1}^{n}(abservde_{i}-predicted_{i})^{2}} MSE=n1i=1∑n(abservdei−predictedi)2 - 平均绝对值误差MSD,对一个真实值与预测值之差的绝对值取平均,公式:
M S E = 1 n ∑ i = 1 n ∣ a b s e r v d e i − p r e d i c t e d i ∣ MSE=\frac{1}{n}\sum_{i=1}^{n}|abservde_{i}-predicted_{i}| MSE=n1i=1∑n∣abservdei−predictedi∣
tensorflow中的均值平方差
由于tensorflow中没有直接的代码实现均值平方差的函数,所以我们可以按照公式来写一下。
logits代表标签纸,outputs表示预测值
MSE = tf.reduce_mean(tf.pow(tf.sub(logits,outputs),2.0))
MSE = tf.reduce_mean(tf.square(tf.sub(logits,outputs)))
MSE = tf.reduce_mean(tf.square(logits - outputs))
另外拓展的两个损失函数可以写成:
Rmse = tf.sqrt(tf.reduce_mean(tf.pow(tf.sub(logits,outputs),2.0)))
msd = tf.reduce_mean(tf.complex_abs(tf.sub(logits,outouts)))
交叉熵(crossentropy)
一般用于分类问题,表达的意思是:预测输入样本属于某一类的概率。公式(其中y表示真实值分欸(0或1),a表示预测值):
c
=
−
1
n
∑
x
[
y
l
n
a
+
(
1
−
y
)
l
n
(
1
−
a
)
]
c = -\frac{1}{n}\sum_{x} [ylna+(1-y)ln(1-a)]
c=−n1x∑[ylna+(1−y)ln(1−a)]
交叉熵也是值越小,代表预测结果越准。
tensorflow中的交叉熵
根据公式自定义的交叉熵实现
cross_entropy = -(input_labels * tf.log(output) + (1 - input_labels) * tf.log(1 - output))
loss = tf.reduce_mean(cross_entropy)
#另一种写法
loss = -tf.reduce_sum(labels*tf.log(logits),1)
tensorflow中给出的激活函数与交叉熵结合的函数:
- Sigmoid交叉熵
- softmax交叉熵
- Sparee交叉熵
- 加权Sigmoid交叉熵
tf.nn.sigmoid_cross_entropy_with_logits(logits,targets,name-None)#targets表示需要待激活的值
tf.nn.softmax_cross_entropy_with_logits(logits,labels,name-None)#labels与logits的结构需要一致
tf.nn.sparse_softmax_cross_emtropy_with_logits(logits,labels,name=None)#真实值和预测值不需要进行独热编码,但要求分类的个数一定要从0开始
tf.nn.weighted_cross_entropy_with_logits(logits,targets,pos_weight,name-None)#targets表示需要待激活的值,pos_weight为权重
关于使用损失函数需要注意的问题
要使用损失函数,我们首先要保证预测值与真实值的数据分布是一样的,举个例子:通过sigmoid激活后得到的预测值值域为(0,1),那么我们也必须要保证真实值与他一样,这时可以对真实值做归一化处理,使得他们的数据分布一样。通俗来说,总得让他们的样式是一样的。
损失函数的使用选择受限于输入标签数据的数据类型。
- 当输入为实数、无界的值,使用平方差较为合适。
- 当输入为位矢量(即分类标志)时,使用交叉熵较为合适。
写在最后
还有一些还没有接触到的损失函数,后续接触到再续写吧。边探索边记录,遇见更多精彩,愿我们一起前行!