代价函数为二次函数的时候,代价函数对梯度的关系
https://blog.csdn.net/weixin_40170902/article/details/80032669
具体参见这篇博客,在某种情况下,会因为梯度原因导致训练速度降低,但是交叉熵函数不会因为梯度原因导致训练速度降低。所以在神经网络中,我们一般使用交叉熵函数
tensorflow有4种交叉熵函数,分别是
tf.nn.sigmoid_cross_entropy_with_logits()
tf.nn.softmax_cross_entropy_with_logits()
tf.nn.sparse_softmax_cross_entropy_with_logits()
tf.nn.weighted_cross_entropy_with_logits()
下面依次讲解这4个代价函数:
tf.nn.sigmoid_cross_entropy_with_logits(_sentinel=None,labels=None, logits=None, name=None)
先对输入利用sigmoid函数非线性激励,然后再跟labels做交叉熵运算。
_sentinel:
本质上是不用的参数,不用填
labels:
一个数据类型是float32或float64的参数,所以为np.array类型
logits:
sigmoid函数的输入,非线性激励后,与labels函数做交叉熵运算。
labels与logits的形状相同,而logits的形状为[batch_size,num_class],所以在情感分类任务中,需要把每个标签也转化为np.array([num_class])
output:
output的形状是[batch_size,num_class]
该函数的测试代码:
def test_cost():
# tf.nn.sigmoid_cross_entropy_with_logits(_sentinel=None, labels=None, logits=None, name=None)
labels = np.array(np.random.randint(0, 10, (10, 3)), dtype=np.float32)
logits = np.array(np.random.normal(1, 20, (10, 3)), dtype=np.float32)
res = tf.nn.sigmoid_cross_entropy_with_logits(labels=labels, logits=logits)
return res
with tf.Session()as sess:
c = test_cost()
sess.run(tf.global_variables_initializer())
print(sess.run(c))
在对话里面,为什么变量初始化在函数调用后面呢???因为只有调用了函数,才能得到张量,这个时候才能进行变量初始化,如果说变量初始化在前面,函数调用在后面,会报错说函数没有初始化
输出为:
[[ 2.48860626e+01 -2.09091187e+01 4.11162415e+01]
[-1.47755556e+01 1.55431000e+02 -1.31396704e+01]
[-6.10552406e+01 -2.04666916e+02 1.15143036e+02]
[ 1.37671219e+02 7.82263489e+01 2.25617237e+01]
[-9.78405609e+01 -9.69136047e+00 -3.09753156e+00]
[-2.95480385e+01 -3.72452278e+01 -1.24654533e+02]
[ 3.42413216e+01 1.84216938e+01 3.61496210e-02]
[ 1.21285134e-15 -3.51373520e+01 -6.85558271e+00]
[ 2.38742905e+01 1.30307244e-03 -5.83097339e-01]
[ 2.17306328e+01 2.78768764e-09 -1.14777908e+02]]
tf.nn.softmax_cross_entropy_with_logits(_sentinel=None, labels=None, logits=None, dim=-1, name=None)
_sentinel:
本质上是不用的参数,不用填
labels:
一个数据类型是float32或float64的参数,是一个有效的概率,sum(labels)=1, one_hot=True(向量中只有一个值为1.0,其他值为0.0),
形状和logits相同
为dense one_hot表示方式
logits:
sigmoid函数的输入,非线性激励后,与labels函数做交叉熵运算。形状为[batch_size,num_classes]
output:
[batch_size]
测试代码
def test_cost():
labels = np.array(np.random.randint(0, 10, (10, 3)), dtype=np.float32)
logits = np.array(np.random.normal(1, 20, (10, 3)), dtype=np.float32)
res = tf.nn.softmax_cross_entropy_with_logits(labels=labels, logits=logits)
return res
with tf.Session()as sess:
c = test_cost()
sess.run(tf.global_variables_initializer())
print(sess.run(c))
(由于是测试,所以labels不是one-hot的表示方式)
输出
[370.70007 42.095367 226.87238 162.13567 136.59497 476.9732
321.2365 156.32648 207.51561 293.26514 ]
我们先来提一下softmax和sigmoid分别做激励函数的时候这两个函数的输出,sigmoid_cross_entropy_with_logits的输出为[batch,num_class],
softmax_cross_entropy_with_logits的输出为[batch],
为什么是这样,我自己认为是因为sotfmax的结果有实际的概率意义,所以算交叉熵的时候做了求和运算,但是sigmoid的输出没有实际的实际的概率意义,所以算交叉熵的时候没有做求和运算,这导致两个函数的输出shape不同。
tf.nn.sparse_softmax_cross_entropy_with_logits(_sentinel=None,labels=None,logits=None, name=None)
_sentinel:
本质上是不用的参数,不用填
labels:
shape为[batch_size],labels[i]是{0,1,2,……,num_classes-1}的一个索引, type为int32或int64
logits:一个数据类型(type)是float32或float64;
shape:[batch_size,num_classes]
output:
形状为[batch_size]
sparse_softmax_cross_entropy_with_logits与softmax_cross_entropy_with_logits的计算方式一样,唯一不同的是labels的表示方法
1.4 tf.nn.weighted_cross_entropy_with_logits(targets,logits, pos_weight, name=None)
计算具有权重的sigmoid交叉熵
与sigmoid_cross_entropy_with_logits()类似,唯一不同的是有个权重向量
权重向量的shape可以是[1,num_class]或者是[batch_size,num_class]或者是[num_class]
测试代码:
def test_cost():
# tf.nn.sigmoid_cross_entropy_with_logits(_sentinel=None, labels=None, logits=None, name=None)
labels = np.array(np.random.randint(0, 10, (10, 3)), dtype=np.float32)
logits = np.array(np.random.normal(1, 20, (10, 3)), dtype=np.float32)
pos = np.array(np.random.normal(1, 20, (3,)), dtype=np.float32)
res = tf.nn.weighted_cross_entropy_with_logits(targets=labels, logits=logits, pos_weight=pos)
return res
with tf.Session()as sess:
c = test_cost()
sess.run(tf.global_variables_initializer())
print(sess.run(c))
参考:
https://blog.csdn.net/sunlin972913894/article/details/82770588
https://blog.csdn.net/weixin_40170902/article/details/80032669