神经网络调参的一些补充

1、激活函数与损失函数选择

输出层的激活函数
  神经网络需要根据情况改变输出层的激活函数。一般而言,回归问题用恒等函数,分类问题用softmax函数。机器学习大致可以分为分类问题和回归问题。分类问题是数据属于哪一个类别的问题。比如,区分图像中的人是男性还是女性的问题就是分类问题。而回归问题是根据某个输入预测一个(连续的)数值问题。比如,根据一个人的图像预测这个人的体重的问题就是回归问题
在这里插入图片描述
激活函数和初始化方法对应
  ReLu. 当使用ReLu激活函数时, 需要使用正态分布的初始化方法,给参数加一点噪声,来打破完全对称并且避免0梯度。有时还需要给偏置附上一些小的非0值来避免dead neuron,比如0.1。2. Softmax. 当使用Softmax激活函数时,因为Sigmoid在0附近最敏感,梯度最大,所以可以将权重W和偏置b全部初始化为0.
性能指标链接:https://tensorflow.google.cn/api_docs/python/tf/keras/metrics/MeanSquaredError
介绍常见的激活函数
sigmoid函数,tanh函数,ReLU函数
在这里插入图片描述
可以看出,当激活函数为线性激活函数时,输出 y^ 不过是输入特征 x 的线性组合(无论多少层),而不使用神经网络也可以构建这样的线性组合。而当激活函数为非线性激活函数时,通过神经网络的不断加深,可以构建出各种有趣的函数。

2、tensorflow激活函数和初始化方法

官网:https://www.tensorflow.org/tutorials
训练用keras 部署用tensorflow
tensorflow激活函数
ReLU:leaky ReLU:ELU;Relu6;Swish等

tensorflow初始化方法

 - tf.constant_initializer() 常数初始化Constant
 - tf.ones_initializer() 全1初始化Ones
 - tf.zeros_initializer() 全0初始化Zeros
 - tf.random_uniform_initializer() 均匀分布初始化RandomUniform
 - tf.random_normal_initializer() 正态分布初始化RandomNormal
 - tf.truncated_normal_initializer() 截断正态分布初始化TruncatedNormal
 - tf.uniform_unit_scaling_initializer() 这种方法输入方差是常数UniformUnitScaling
 - tf.variance_scaling_initializer() 自适应初始化VarianceScaling
 - tf.orthogonal_initializer() 生成正交矩阵Orthogonal
 - glorot_uniform_initializer = GlorotUniform     Xavier 均匀分布初始化
 - glorot_normal_initializer = GlorotNormal      Xavier 正态分布初始化
 - identity_initializer = Identity   单位矩阵

tensorflow和keras参数相同,但是结果不一致,可能的原因:可能是初始化方法不同,tensorflow根据我们定义的初始化变量初始化,但是keras使用它自己的。

3、Tensorflow 2.0+与Keras的联系与应用

  2.0 跳过了那个需要写sess的过程,直接学习了函数式model定义以及Keras。与Keras更好的结合,避免了很多我们重复造轮子的过程。
  Keras事实上是一个高级别的Python神经网络框架,能够在Tensorflow上运行的一款高级的API框架,它拥有着丰富的数据封装和一些先进的模型实现,避免了“重复造轮子”。
(1)Keras Model(非常关键)
  神经网络的核心就是model。任何一个神经网络的主要设计思想和功能都集中在model中。Keras的加入使得model的定义更加简单了。其中,最简单的就是序列模型Sequential model,它由多个网络层堆叠而成,顺序执行,一层一层逻辑关系非常清晰,易于构建和理解。但是现在我们在解决实际应用场景中的问题的时候会发现,很多问题并不能简单地解决,可能大部分时间我们现在要想在现有基础上进一步改进,都需要制作更庞大复杂的模型。这时候就应该使用Keras的函数式格式来定义functional model,它可以支持我们构建任意结构的神经网络图。
(2)Functional model函数式模型(重点)
  Sequential 顺序模型对于问题解释程度较差缺乏自由度,所以如果想要实现更为复杂的模型仅仅使用Sequential model就显得不太够,如果想要定义复杂模型(比如多输出模型、有向无环图或者具有共享层的模型)就应该使用Keras提供的函数式Functional model定义法。
  第一次接触这种写法会感觉很奇怪,但是习惯之后就发现其实还是很好理解的,只不过传参的过程和调用的目标现在具有更好的自由度,它在形式上非常类似于传统的编程,只需要建立模型导入输出和输出“形式参数”即可。如果之前学过tensorflow_v1可以近似将其理解为一种新格式的“占位符”(其实是为输入提前申请了一个张量空间),在这里也给出一个简单的小例子代码:(注释是我之前做案例的时候加的,懒得删掉了,对于理解也有帮助)

# 使用Input类进行初始化输入,根据输入数据的大小将输入的数据维度做成[28,28,1]
input_data = tf.keras.Input([28, 28, 1])  # 与之前v1不同的是batch_size不需要设置了,tensorflow2.3自己能识别
# 首先是一个32个3*3核的卷积层,补零,激活函数也不用自己再写了,直接封装在里面了使用relu,并且用input_data初始化了整个卷积类
conv = tf.keras.layers.Conv2D(filters=32, kernel_size=3, padding="SAME", activation=tf.nn.relu)(input_data)
# 然后是使用BatchNormalization正则化类作为正则化工具也被用作各个层之间的联结(减小模型过拟合可能,并增强模型泛化能力)
conv = tf.keras.layers.BatchNormalization()(conv)
# 然后接一个64个3*3核的卷积层,补零,激活函数为relu(特别备注一下tensorflow2.0对于kernel_size=3有自己封装好的优化效果,尽量多用3)
conv = tf.keras.layers.Conv2D(filters=64, kernel_size=3, padding="SAME", activation=tf.nn.relu)(conv)
# 然后进行一次最大值池化(也是为了降低过拟合,增加模型泛化能力)
conv = tf.keras.layers.MaxPool2D(strides=[1, 1])(conv)
# 然后再接一个128*3*3的卷积层,补零,激活函数为relu
conv = tf.keras.layers.Conv2D(128, 3, padding="SAME", activation=tf.nn.relu)(conv)
# 然后接一个Flatten层将数据压扁(平整化)成全连接神经网络能使用格式
flat = tf.keras.layers.Flatten()(conv)
# 然后接一个全连接层隐藏层设置128个神经元,激活函数使用relu(全连接层的目标是对卷积后的结果进行最终分类)
dense = tf.keras.layers.Dense(128, activation=tf.nn.relu)(flat)
# 将特征提取为10个输出维度进行最终分类使用softmax激活函数进行特征归一化
output_data = tf.keras.layers.Dense(10, activation=tf.nn.softmax)(dense)
# 定义好卷积神经网络的起止结点(即执行刚才定义好的模型从input_data开始到output_data结束,可以理解为规定模型定义部分的上下界)
model = tf.keras.Model(inputs=input_data, outputs=output_data)

  它包含很多与我们之前说的Sequential model不同的地方,出现了很多我们之前不了解的参数和方法,现在我们选择其中必要的部分进行讲解。
该链接详细解释了各层的意义:http://okgoes.cn/blog/detail?blog_id=24051

4、Keras提供两种学习率适应方法,可通过回调函数实现

(1)LearningRateScheduler

keras.callbacks.LearningRateScheduler(schedule)

  该回调函数是学习率调度器.,参数schedule:函数,该函数以epoch号为参数(从0算起的整数),返回一个新学习率(浮点数)

import keras.backend as K
from keras.callbacks import LearningRateScheduler
 
def scheduler(epoch):
    # 每隔100个epoch,学习率减小为原来的1/10
    if epoch % 100 == 0 and epoch != 0:
        lr = K.get_value(model.optimizer.lr)
        K.set_value(model.optimizer.lr, lr * 0.1)
        print("lr changed to {}".format(lr * 0.1))
    return K.get_value(model.optimizer.lr)
 
reduce_lr = LearningRateScheduler(scheduler)
model.fit(train_x, train_y, batch_size=32, epochs=300, callbacks=[reduce_lr])

(2)ReduceLROnPlateau

keras.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=10, verbose=0, mode='auto', epsilon=0.0001, cooldown=0, min_lr=0)

  当评价指标不在提升时,减少学习率
  当学习停滞时,减少2倍或10倍的学习率常常能获得较好的效果。该回调函数检测指标的情况,如果在patience个epoch中看不到模型性能提升,则减少学习率
参数

  • monitor:被监测的量
  • factor:每次减少学习率的因子,学习率将以lr = lr*factor的形式被减少
  • patience:当patience个epoch过去而模型性能不提升时,学习率减少的动作会被触发
  • mode:‘auto’,‘min’,‘max’之一,在min模式下,如果检测值触发学习率减少。在max模式下,当检测值不再上升则触发学习率减少。
  • epsilon:阈值,用来确定是否进入检测值的“平原区”
  • cooldown:学习率减少后,会经过cooldown个epoch才重新进行正常操作
  • min_lr:学习率的下限

代码

from keras.callbacks import ReduceLROnPlateau
reduce_lr = ReduceLROnPlateau(monitor='val_loss', patience=10, mode='auto')
model.fit(train_x, train_y, batch_size=32, epochs=300, validation_split=0.1, callbacks=[reduce_lr])

Anaconda、TensorFlow安装和Pycharm配置
https://zhuanlan.zhihu.com/p/77494679

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值