TensorFlow损失函数、优化器API及其在简单卷积网络上的比较

Loss

1. L2损失

tf.nn.l2_loss(t, name=None)

output = sum(t ** 2) / 2

2. 交叉熵损失

C = − 1 n ∑ x [ y ln ⁡ a + ( 1 − y ) ln ⁡ ( 1 − a ) ] C=-\frac{1}{n}\sum_{x}[y\ln a +(1-y)\ln(1-a)] C=n1x[ylna+(1y)ln(1a)]
a是经过sigmoid激活的 a = σ ( ∑ j w j x j + b ) a=\sigma (\sum_{j}w_jx_j + b) a=σ(jwjxj+b),在0到1之间
交叉熵为什么能作为代价函数?
首先,它是非负的,加号里的每一项都是负的,整个式子前面是负的,负负得正
其次,实际输出值很接近期望输出值时,交叉熵会非常接近0
它有均方代价函数不具备的特征,能够避免学习速率降低的问题
TensorFlow四个交叉熵函数

tf.nn.sigmoid_cross_entrogy_with_logits
tf.nn.softmax_cross_entrogy_with_logits
tf.nn.sparse_softmax_cross_entrogy_with_logits
tf.nn.weighted_cross_entrogy_with_logits
(1)
tf.nn.sigmoid_cross_entrogy_with_logits(logits, targets, name=None)
	# logits: 网络模型中的W*X矩阵,不需要经过sigmoid
	# targets: 标签值,可包含多个1或0,和logits的shape相同

不能用于多分类问题,例如一个实际取值范围为0-4,目标标签y也是0-4,实际取值经过sigmoid后取值范围变为0-1,ln(.)是负的,公式中(1-y)会出现负数,而且-yln(a)有可能会非常大

(2)

对于单目标多分类问题,分类之间是独立且互斥的,这时候就要用 softmax的交叉熵函数

  • 先看softmax激活:
tf.nn.softmax(logits, dim=-1, name=None)
	# logits:Tensor
	# dim: 默认为-1,最后一个维度

softmax = exp(logits) / reduce_sum(exp(logits), dim)
softmax输出0-1之间的概率分布

  • logsoftmax激活:
tf.nn.log_softmax(logits, dim=-1, name=None)

logsoftmax = logits - log(reduce_sum(exp(logits), dim))

  • softmax交叉熵损失:
tf.nn.softmax_cross_entrogy_with_logits(logits, labels, dim=-1, name=None)

注意:只适合单目标二分类或者多分类问题
对于多分类问题,我们需要对输入进行编码,例如我们的年龄分为5类,人工编码为0,1,2,3,4,因为输出值是5维特征,因此我们需要人工做onehot encoding,分别编码为00001,00010,00100,01000,10000,作为函数的输入

(3)
tf.nn.sparse_softmax_cross_entrogy_with_logits(logits, labels, name=None)
	# logits: shape=[batch_size, num_classes]
	# labels: shape=[batch_size, num_classes] num_classes从0开始编码

softmax_cross_entrogy_with_logits的易用版本,对于CIFAR-10、ImageNet都是多类单标签问题,label都是0,1,2,3,…每次转成onehot encoding比较麻烦,使用sparse_softmax_cross_entrogy_with_logits,TensorFlow内部进行编码

(4)
tf.nn.weights_cross_entrogy_with_logits(targets, logits, pos_weight, name=None)

let x = logits, z = targets q = pos_weights
softmax_cross_entrogy_with_logits的拓展版,pos_weight的目的是增加或者减少正样本在算Cross Entropy的损失,原理:在正样本算出的值前面乘以一个系数

loss = qz * -log(sigmoid(x)) + (1 - z) *  -log(1 - sigmoid(x))
    	 =(1 - z) * x + (1 +  (q - 1) * z) *   log(1 + exp( - x))

Optimizer

两个作用:计算损失的梯度,将梯度应用到变量的更新中去
Optimizer是一个基类:class tf.train.Optimizer
使用的时候,需要实例化它的一个子类,如下面的例子:

# 传入学习率参数创建一个优化器类的对象实例
opt = GradientDescentOptimizer(learning_rate=0.1)
# 添加一系列操作节点到计算图最小化cost来更新变量
opt_op = opt.minimize(cost, var_list=<list of variables>)  # 传入损失函数和变量列表,var_list不传的话更新的是所有的变量

用处理的梯度更新模型参数
调用minimize()有两个连续步骤:计算梯度,应用到变量上,如下:

  1. 使用comepute_gradients()计算梯度
  2. 使用apply_gradients()把处理过的梯度用来更新varibles

如果想在应用在变量之前对梯度做一些特别处理时,需要在这两步之间再加上一些处理:

  1. 使用comepute_gradients()计算梯度
  2. 根据需求对计算出的梯度做一些处理
  3. 使用apply_gradients()把处理过的梯度用来更新varibles

例子:

# 传入学习率参数创建一个优化器类的对象实例
opt = GradientDescentOptimizer(learning_rate=0.1)
# 计算梯度 
# grads_and_vars是一个元组列表(变量所对应的梯度, 变量)
grads_and_vars = opt.compute_gradients(loss, <list of variables>)
# 对梯度元组中的每一个值进行操作
capped_grads_and_vars = [(MyCapper(gc[0]), gv[1]) for gv in grads_and_vars]
# 用新的梯度更新参数
opt.apply_gradients(capped_grads_and_vars) 

优化器子类:

10个

tf.train.GradientDescentOptimizer()
tf.train.ProximalGradientDescentOptimizer()
tf.train.AdagradOptimizer()
tf.train.ProximalAdagradOptimizer()
tf.train.AdagradDAOptimizer()
tf.train.AdadeltaOptimizer()
tf.train.AdamOptimizer()
tf.train.RMSPropOptimizer()
tf.train.FtrlOptimizer()
tf.train.MomentumOptimizer()

这篇也有讲:https://blog.csdn.net/fzp95/article/details/83018744

比较

conv+relu+maxpool+linear_fc
tf.train.GradientDescentOptimizer()
在这里插入图片描述
tf.train.ProximalGradientDescentOptimizer()
在这里插入图片描述
tf.train.AdagradOptimizer()
在这里插入图片描述
tf.train.ProximalAdagradOptimizer()
在这里插入图片描述
tf.train.AdagradDAOptimizer()
在这里插入图片描述
tf.train.AdadeltaOptimizer() 在小网络上表现很差
在这里插入图片描述
tf.train.AdamOptimizer() 学习率选取很重要,不能太小,也不能太大,合适的学习率优化效果好。
在这里插入图片描述
tf.train.FtrlOptimizer() 最优学习率为0.1 不能太小
在这里插入图片描述
tf.train.MomentumOptimizer() 对于小学习率能够快速下降
在这里插入图片描述
tf.train.RMSPropOptimizer() 对学习率变化不太敏感 而且优化效果好
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值