tensorflow初探五之神经元函数——《Tensorflow技术解析与实战学习》笔记

神经元函数以及优化方法

这是需要牢记的内容,这里包含了激活函数、卷积函数、池化函数、分类函数、优化方法和批标准化的写法和简略介绍。

a. 激活函数

神经网络的非线性因素,神经网络可以解决非线性问题的关键。tensorflow中包含处处平滑的激活函数 sigmoid、 tanh、 elu、 softplus 和 softsign,也包括连续但不是处处可微的激活函数 relu、 relu6、 crelu 和 relu_x,以及随机正则化函数 dropout,常用的激活函数有四种 sigmoid、 tanh、 relu 和 softplus。

tf.nn.relu()
tf.nn.sigmoid()
tf.nn.tanh()
tf.nn.elu()
tf.nn.bias_add()
tf.nn.crelu()
tf.nn.relu6()
tf.nn.softplus()
tf.nn.softsign()
tf.nn.dropout() # 防止过拟合,用来舍弃某些神经元

简单介绍:

  • sigmoid适合作为输出层,求导简单。但是存在饱和去,很容易使得梯度消失。
  • tanh具有软饱和性,以0为中心,收敛速度比sigmoid快。
  • relu目前最受欢迎的激活函数,softplus可以看成其平滑版本。 relu定义为 f(x)=max(x,0)。softplus 定义为 f(x)=log(1+exp(x))。优点是可以能够更很地收敛,并提供了神经网络的稀疏表达能力。但是,随着训练的进行,部分输入会落到硬饱和区,导致对应的权重无法更新,称为“神经元死亡”


    常用激活函数
a = tf.constant([[1.0, 2.0], [1.0, 2.0], [1.0, 2.0]])
sess = tf.Session()
print(sess.run(tf.sigmoid(a)))
#[[0.7310586 0.880797 ]
# [0.7310586 0.880797 ]
#[0.7310586 0.880797 ]]

with tf.Session() as sess:
    b = tf.nn.relu(a)
    print(sess.run(b))
  • relu6是定义在 min(max(features, 0), 6)的
    tf.nn.relu6(features, name=None),以及 crelu,也就是 tf.nn.crelu(features, name=None)。
  • dropout函数:一个神经元将以概率 keep_prob 决定是否被抑制。如果被抑制,该神经元的输出就为 0;如果不被抑制,那么该神经元的输出值将被放大到原来的 1/keep_prob 倍。还有一个noise_shape参数,用于对dropout的方式进行约束。参考这个网址,说的很清楚
a = tf.constant([[-1.0, 2.0, 3.0, 4.0],[5,6,7,8]])
print(a.shape)
with tf.Session() as sess:
    b = tf.nn.dropout(a, 0.5, noise_shape = [2,1])#表示行之间相互独立,同一行的列是不独立的,要么同时为0,要么同时缩放。
    print(sess.run(b))

#(2, 4)
#[[-0.  0.  0.  0.]
 #[10. 12. 14. 16.]]
激活函数的选择

b.卷积函数

是在一批图像上扫描的二维过滤器。下面是常见的卷积函数。

tf.nn.convolution(input, filter, padding, strides=None,
dilation_rate=None, name=None, data_format=None)
tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None,
data_format= None, name=None)
tf.nn.depthwise_conv2d (input, filter, strides, padding, rate=None, name=None,
data_format=None)
tf.nn.separable_conv2d (input, depthwise_filter, pointwise_filter, strides, padding,
rate=None, name=None, data_format=None)
tf.nn.atrous_conv2d(value, filters, rate, padding, name=None)
tf.nn.conv2d_transpose(value, filter, output_shape, strides, padding='SAME',
data_format='NHWC', name=None)
tf.nn.conv1d(value, filters, stride, padding, use_cudnn_on_gpu=None,
data_format= None, name=None)
tf.nn.conv3d(input, filter, strides, padding, name=None)
tf.nn.conv3d_transpose(value, filter, output_shape, strides, padding='SAME', name=None)

c. 池化函数

池化函数一般跟在卷积函数的下一层。池化操作是利用一个矩阵窗口在张量上进行扫描,将每个矩阵窗口中的值通过取最大值或平均值来减少元素个数。每个池化操作的矩阵窗口大小是由 ksize 指定的,并且根据步长 strides决定移动步长。部分函数只能在GPU内执行,比如max_pool_with_argmax。

tf.nn.avg_pool(value, ksize, strides, padding, data_format='NHWC', name=None)
tf.nn.max_pool(value, ksize, strides, padding, data_format='NHWC', name=None)
tf.nn.max_pool_with_argmax(input, ksize, strides, padding, Targmax=None, name=None)
tf.nn.avg_pool3d(input, ksize, strides, padding, name=None)
tf.nn.max_pool3d(input, ksize, strides, padding, name=None)
tf.nn.fractional_avg_pool(value, pooling_ratio, pseudo_random=None, overlapping=None,deterministic=None, seed=None, seed2=None, name=None)
tf.nn.fractional_max_pool(value, pooling_ratio, pseudo_random=None, overlapping=None,deterministic=None, seed=None, seed2=None, name=None)
tf.nn.pool(input, window_shape, pooling_type, padding, dilation_rate=None, strides=None,name=None, data_format=None)

d.分类函数

tf.nn.sigmoid_cross_entropy_with_logits(logits, targets, name=None)
tf.nn.softmax(logits, dim=-1, name=None)
tf.nn.log_softmax(logits, dim=-1, name=None)
tf.nn.softmax_cross_entropy_with_logits(logits, labels, dim=-1, name=None)
tf.nn.sparse_softmax_cross_entropy_with_logits(logits, labels, name=None)
  1. tf.nn.sigmoid_cross_entropy_with_logits(logits, targets, name=None):
def sigmoid_cross_entropy_with_logits(logits, targets, name=None):
# 输入: logits:[batch_size, num_classes],targets:[batch_size, size].logits 用最后一层的输入即可
# 最后一层不需要进行 sigmoid 运算,此函数内部进行了 sigmoid 操作
# 输出: loss [batch_size, num_classes]

这个函数的输入要格外注意,如果采用此函数作为损失函数,在神经网络的最后一层不需要进行 sigmoid 运算。

  1. tf.nn.softmax(logits, dim=-1, name=None)计算 Softmax 激活,也就是 softmax = exp(logits) /reduce_sum(exp(logits), dim)。
  2. tf.nn.log_softmax(logits, dim=-1, name=None)计算 log softmax 激活,也就是 logsoftmax =logits - log(reduce_sum(exp(logits), dim))。
  3. tf.nn.softmax_cross_entropy_with_logits(_sentinel=None, labels=None, logits=None, dim=-1,name =None):
def softmax_cross_entropy_with_logits(logits, targets, dim=-1, name=None):
# 输入: logits and labels 均为[batch_size, num_classes]
# 输出: loss:[batch_size], 里面保存的是 batch 中每个样本的交叉熵
  1. tf.nn.sparse_softmax_cross_entropy_with_logits(logits, labels, name=None) :
def sparse_softmax_cross_entropy_with_logits(logits, labels, name=None):
# logits 是神经网络最后一层的结果
# 输入: logits: [batch_size, num_classes] labels: [batch_size],必须在[0, num_classes]
# 输出: loss [batch_size],里面保存是 batch 中每个样本的交叉熵

e.优化方法Optimizer

用于加速神经网络的训练。目前加速训练的优化方法基本基于梯度下降,只是细节上有差异。这里主要介绍八类优化器

  1. BGD法和SGD法:class tf.train.GradientDescentOptimizer
    批梯度下降法和随机梯度下降法。后者是将前者的batch拆分成更细小的batch,每次运行更新参数。前者对整个数据集的平均loss进行更新,耗时更长。后者存在的问题是容易陷入局部最优,需要手动调整学习率,尤其在训练时,我们常常想对常出现的特征更新速度很一些,而对不常出现的特征更新速度慢一些,而 SGD 在更新参数时对所有参数采用一样的学习率。

  2. Momentum 法Nesterov Momentum :class tf.train.MomentumOptimizer,
    这是为了解决学习率固定的问题而提出。标准的动量方式首先保留之前的更新向量,认为是初始速度,利用当前数据的梯度叠加上之前的结果,得到新的速度,并使用这个速度更新学习率。这样在下降初期,前后梯度方向一致时,能够加速学习;在下降的中后期,在局部最小值的附近来回震荡时,能够抑制震荡,加很收敛。
    Nesterov Momentum 法:直接使用之前的累加速度向量更新参数,计算更新参数之后的梯度方向,然后用这个梯度值修正速度,然后用这个速度计算新的参数

    Momentum 法

    Nesterov Momentum法

  3. Adagrad 法:class tf.train.AdagradOptimizer
    从这个方法开始的优化器都是自动调节学习速率的。如果本次更新时梯度大,学习率就衰减得很一些;如果这次更新时梯度小,学习率衰减得就慢一些

  4. Adadelta 法:class tf.train.AdadeltaOptimizer
    Adagrad 法仍然存在一些问题:其学习率单调递减,在训练的后期学习率非常小,并且需要手动设置一个全局的初始学习率。 Adadelta 法用一阶的方法,近似模拟二阶牛顿法,解决了这些问题。

  5. RMSprop 法:class tf.train.RMSPropOptimizer
    与 Momentum 法类似,通过引入一个衰减系数,使每一回合都衰减一定比例。在实践中,对循环神经网络(RNN)效果很好

  6. Adam 法:class tf.train.AdamOptimizer
    Adam 法根据损失函数针对每个参数的梯度的一阶矩估计和二阶矩估计动态调整每个参数的学习率。

批标准化

批标准化(batch normalization, BN)是为了克服神经网络层数加深导致难以训练而诞生的。通过引入批标准化来规范化某些层或者所有层的输入,从而固定每层输入信号的均值与方差。

批标准化一般用在非线性映射(激活函数)之前,对 x=Wu+b 做规范化,使结果(输出信号各个维度)的均值为 0,方差为 1。让每一层的输入分布在线性区间,加大了梯度,让模型更加大胆的进行梯度下降。
优点如下:

  • 加大探索的步长,加快收敛的速度;
  • 更容易跳出局部最小值;
  • 破坏原来的数据分布,一定程度上缓解过拟合。
    在遇到神经网络收敛速度很慢或梯度爆炸(gradient explode)等无法训练的情况下,都可以尝试用批标准化来解决。
# 计算 Wx_plus_b 的均值和方差,其中 axes=[0]表示想要标准化的维度
fc_mean, fc_var = tf.nn.moments(Wx_plus_b, axes=[0], )
scale = tf.Variable(tf.ones([out_size]))
shift = tf.Variable(tf.zeros([out_size]))
epsilon = 0.001
Wx_plus_b = tf.nn.batch_normalization(Wx_plus_b, fc_mean, fc_var, shift,scale, epsilon)
# 也就是在做:
# Wx_plus_b = (Wx_plus_b - fc_mean) / tf.sqrt(fc_var + 0.001)
# Wx_plus_b = Wx_plus_b * scale + shift
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容