Bp神经网络的调参(下)

                                            Bp神经网络的调参(下)

    项目上一直比较忙,最近帮着封装模型,调试界面,所以停更了。刚开始一直忙着算法的事情,认为搭建完模型好像就什么事就没有了,结果:老师要求封装自己的模型,用界面的形式展示出来结果。说这么多,无非想说:搭建模型->封装模型->调试界面->AI芯片产品化,大概是做这个方向的一个思路吧。大家还记得我们上一篇说到什么来着的:
    你没记错,就是调参,上一次的调参工作对于大多数情况应该是可以应付的了,只要你的数据集不是那么的糟糕!否则你就更应该在数据集上下功夫,前面的文章中也提到了:特征工程直接决定你模型的成功与否,如果特征工程做不好,那么分类回归完全是瞎扯。这次我们主要对上次的结果进一步优化:比如速度的优化,准确率的优化等等。

                                                   第一部分.优化器优化网络

    什么是优化器???
    是不是那个。。。。。加速游戏进程的那个??


在这里插入图片描述

    兄弟,你有点优秀啊!!算了,我来解释下吧:你可以当作游戏加速器来理解,同样我们现在换成了神经网络,就是加速网络训练的那个,说到这里,你是不是想到了什么??对,就是我们上一篇的梯度下降优化算法,我们来回顾一下上一章的那个神秘人物:

train_step=tf.train.GradientDescentOptimizer(0.01).minimize(loss)

是不是似曾相识,说到优化器,tensorflow封装了很多优化器算法,所以选择优化器也就成了一个需要值得关注的地方,至于具体的有哪些,说实话,我没有一个个去使用过,再次贴上网上比较火的一张图:

在这里插入图片描述

在这里插入图片描述

我们这里选择的是adam优化器(对每个权值都计算自适应的学习速率),运行代码之后你会发现,使用adam优化器方法会比梯度下降的方法更快,意味着我们达到相同的准确率所需要的步伐大大减少。至于怎么改(基于上一篇文章调参上),如下:

 train_step=tf.train.AdamOptimizer(0.01).minimize(loss)

就这样,第一步的工作算是结束了。下面该如何改进网络呢??且听下回分解

                                              第二部分.优化网络结构

至于网络结构,之前的确实有点简单了,总不能指望一层网络就想达到自己宏伟的目标。俗话说:一个好汉三个帮呢,一层网络充其量顶多能做到那样了,再复杂任务面前,一层网络不得不低头啊。


在这里插入图片描述

现在我们搭建一个更复杂的网络,直接看代码吧:

import tensorflow as tf 
from tensorflow.examples.tutorials.mnist import input_data

#载入训练集
mnist=input_data.read_data_sets("MNIST_data",one_hot=True)

#每个批次的大小,相当于每次放入100张图片
batch_size=100
#计算一共多少批次
n_batch=mnist.train._num_examples//batch_size

#定义两个placeholder,[]里面代表定义其形状,由上可得NONE为100,因为每批送入100张图片,784代表把一张图片拉成784的向量
#行为100,列为784
x=tf.placeholder(tf.float32,[None,784])
y=tf.placeholder(tf.float32,[None,10])
lr=tf.Variable(0.001,dtype=tf.float32)
keep_prob=tf.placeholder(tf.float32)

#创建一个简单的神经网络
#使用这种初始化方法tf.truncated_normal比之前的效果是要好点的,使用的是正态分布的方法
W1=tf.Variable(tf.truncated_normal([784,500],stddev=0.1))
b1=tf.Variable(tf.zeros([500])+0.1)
L1=tf.nn.tanh(tf.matmul(x,W1)+b1)
#随机失活一些神经元,失活的概率用keep_prob控制,如果设置1,就是所有神经元失活,设置0.5就是一半神经元失活
L1_drop=tf.nn.dropout(L1,keep_prob)

W2=tf.Variable(tf.truncated_normal([500,300],stddev=0.1))
b2=tf.Variable(tf.zeros([300])+0.1)
L2=tf.nn.tanh(tf.matmul(L1_drop,W2)+b2)
L2_drop=tf.nn.dropout(L2,keep_prob)

W3=tf.Variable(tf.truncated_normal([300,10],stddev=0.1))
b3=tf.Variable(tf.zeros([10])+0.1)
prediction=tf.nn.softmax(tf.matmul(L2_drop,W3)+b3)

loss=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y,logits=prediction))

#使用梯度下降
train_step=tf.train.AdamOptimizer(lr).minimize(loss)

#初始化变量
init=tf.global_variables_initializer()
correct_prediction=tf.equal(tf.argmax(y,1),tf.argmax(prediction,1))

accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32))

with tf.Session() as sess:
    sess.run(init)
    for epoch in range(51):
        sess.run(tf.assign(lr,0.001*(0.95**epoch)))
        for batch in range(n_batch):
            #next_batch自动获取下100到200个图片,然后200到300的图片,并保存batch_xs,batch_ys中
            batch_xs,batch_ys=mnist.train.next_batch(batch_size)
            sess.run(train_step,feed_dict={x:batch_xs,y:batch_ys,keep_prob:1.0})
        learning_rate=sess.run(lr)               
        acc=sess.run(accuracy,feed_dict={x:mnist.test.images,y:mnist.test.labels,keep_prob:1.0})    
        print("Iter"+str(epoch)+",Testing Accuracy"+str(acc)+",learning_rate="+str(learning_rate))

    至于加入了什么呢??首先:我们给网络老哥找来了三位打手,网络层数增加了,打架当然更加是得心应手啦,最后赢得概率肯定也是巨大的吧。由此可以推出:更深的网络结构会对准确率的提升有着重要的意义。但是网络层数的加深,会导致过拟合的现象,这个可以由画图看出其变化,上一篇文章有画图的代码,很简单,拿过来照搬就是了。此时我们就用了dropout,让其中部分神经元不工作,这样曾减少参数的角度上减小了过拟合的发生。其次:初始化的方法变了,使用了正态分布的初始化方法,也是标准的方法。最后:我们的学习率进行了改进,当然这里还有decay这个参数,有时间我会补充上去的。最后的效果如何呢??这个靠你自己取跑一下了,我测试下来几次都在98%以上,画图还是上面那句话,依葫芦画瓢即可。
    这些基本就是我的调参心得:我认为最重要的参数还是从学习率入手,至于后面的加深网络结构这些方法,可以使用,但不要太过,你要知道,多一层网络,所多出来的参数是你无法想象的,尤其是你的数据特别多的时候,尤其需要注意网络架构的选择,以及画图判断是否产生了过拟合。神经网络在过拟合这个方面我jio得毕机器学习这块儿严重一点,注意神经元的个数,尽量根据自己的特征来选取,比如你有60个特征,我认为和输入相连接的第一个隐藏层取80个神经元就可以了,尤其是电脑配置不算好的,特别特别注意,否则那电脑发狂的声音绝对让你抓狂,哈哈哈O(∩_∩)O本章就到这里了,由于本屌丝时间不够,项目还在进行,这次就先写到这里啦!恳请大家指正不足。

### BP神经网络参数调整方法与最佳实践 对于BP神经网络而言,其性能高度依赖于多个因素的选择和设置,包括但不限于隐含层的数量、误差阈值以及学习速率等[^1]。为了有效调整这些参数并获得最优解,在实践中可以采用一系列策略和技术。 #### 使用自动化工具进行超参数调优 现代机器学习生态系统提供了丰富的库和支持工具来帮助自动完成这一过程。例如: - **scikit-optimize** 是一种基于贝叶斯优化原理构建起来的Python库,它能够有效地探索不同配置下的表现情况,并找到接近全局最优点的位置; - **Weights & Biases (W&B)** 不仅能追踪每一次训练试验的数据变化趋势,还集成了直观易懂的结果展示界面,使得研究人员更容易理解各个变量之间的相互影响关系; - **Ray Tune**, 作为一款分布式的超参搜索平台,兼容多种不同的寻优算法,适合大规模集群环境下的快速迭代开发工作流; - **Optuna** 则以其灵活性著称,允许开发者轻松集成到现有的项目当中去,同时支持多线程/进程并发执行机制以加速整个流程的速度; - 对于那些倾向于云端解决方案的人来说,谷歌推出的 **Vizier** 提供了一个强大的黑盒优化服务平台,专门针对复杂模型设计而成[^2]。 通过上述提到的各种手段相结合的方式来进行细致入微地调试,往往可以获得更加理想的效果。 #### 手动调节经验法则 除了借助外部软件外,还有一些通用的经验法则是值得借鉴的: - 隐含层数量不宜过多也不宜过少,通常情况下一层或两层就足以应对大多数应用场景的需求了; - 设置合理的初始权重范围有助于加快收敛速度,一般推荐使用较小的标准差随机初始化方案; - 学习率决定了梯度下降过程中步长大小,过高容易引起震荡发散现象而太低则可能导致陷入局部极小值难以自拔,因此需要根据具体问题特点灵活设定; - 动态调整学习率也是一种常见做法,比如当连续几轮损失函数几乎没有改善迹象时适当降低当前使用的数值; - 正则化技术(L1/L2正则项)、Dropout等措施可以在一定程度上防止过拟合的发生,提高泛化能力[^3]。 ```python import numpy as np from sklearn.neural_network import MLPClassifier # 创建一个多层感知机分类器实例 clf = MLPClassifier(hidden_layer_sizes=(10,), max_iter=500) # 调整一些重要的超参数 clf.learning_rate_init = 0.01 # 初始化学习率为0.01 clf.alpha = 0.0001 # L2惩罚系数设为0.0001 clf.momentum = 0.9 # 动量因子取值为0.9 clf.activation = 'relu' # 激活函数选用ReLU形式 # 训练模型... X_train, y_train = ... # 假设有已知样本特征矩阵X及标签向量y clf.fit(X_train, y_train) ```
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值