博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Tensorflow笔记_神经网络优化
阅读量:5753 次
发布时间:2019-06-18

本文共 16930 字,大约阅读时间需要 56 分钟。

 一:神经元模型

# 神经元模型:神经元模型用公式表示为::?(∑????? + ?),   其中 f 表示为激活函数,神经网络是以神经元为基本单位构成

# 激活函数:引入非线性激活因素,提高模型的表达能力

常用的激活函数有

# 激活函数relutf.nn.relu()# 激活函数sigmoldtf.nn.sigmold()# 激活函数tanhtf.nn.tanh()

# 神经网络的复杂度:

1:可用神经网络的层数和神经网络中待优化的参数个数表示

2:计算神经网络层数一般不计算输入层

3:神经网络的层数 = 隐藏层数 + 1个输出层

4:神经网络待优化参数 = 神经网络中所有参数w的个数 + 所有参数b的个数

例如:

  

# 神经网络的层数 = 1个隐藏层 + 一个输出层,所以该神经网络的层数为2层

# 神经网络的待优化参数:第一层参数用三行四列的二阶张量表示(具有12个线上权重w)再加上4个偏置b,第二层参数是四行两列的二阶张量(具有8个线上权重w),再加上2个偏置b,该神经网络总参数 = 3*4+4 + 4*2+2 = 26

 二:神经网络的优化

1:损失函数 loss

2:学习率 learing_rate

3:滑动平均 ema

4:正则化 regularization

## 神经网络优化-损失函数

用预测值 y 与已知答案 y_ 的差距,再训练神经网络的过程中,通过不断的改变神经网络中所有参数,使损失函数不断减小,训练出更高准确率的神经网络模型

神经网络优化目标:找到某条参数,使得y和y_无限接近,也就是它们的差距loss最小

常用的损失函数:

  1:均方误差

  2:自定义

  3:交叉熵

# 均方误差mse:n个样本的预测值y与已知答案y_之差的平方和,再求平均值,公式表示为如下

均方误差再Tensorflow中的表示

loss_mse = tf.reduce_mean(tf.square(y_ - y))

 

 # 用下面的例子来理解损失函数

  预测酸奶日销量 y,x1 和 x2 是影响日销量的两个因素。

  建模前应提前采集的数据有:一段时间内,每日的 x1 因素、x2 因素和销量 y_。采集的数据量越大越好。

  在本例中用销量预测产量,最优的产量应该等于销量。由于目前没有数据集,所以拟造了一套数 据集。利用 Tensorflow 中函数随机生成 x1、 x2,制造标准答案 y_ = x1 + x2,为了更真实,求和后还加了正负 0.05 的随机噪声

# 损失函数使用均方误差的方法

#coding:utf-8# 导入模块 生成数据集import tensorflow as tfimport numpy as npBATCH_SIZE = 8SEED = 23455        # 保证生成的随机数一样rdm = np.random.RandomState(SEED)X = rdm.rand(32,2)Y_ = [[x1 + x2 + (rdm.rand()/10.0-0.05)] for (x1,x2) in X]#1 定义神经网络参数和输入,输出,定义向前传播的过程x = tf.placeholder(tf.float32, shape=(None,2))y_ = tf.placeholder(tf.float32, shape=(None,1))w1 = tf.Variable(tf.random_normal([2,1], stddev=1, seed=1))y = tf.matmul(x, w1)    # 定义一输出结果y #2 定义损失函数反向传播的方法 # 定义损失函数为均方误差,反向传播的方法为梯度下降loss_men = tf.reduce_mean(tf.square(y_-y))train_step = tf.train.GradientDescentOptimizer(0.001).minimize(loss_men)#3 生成会话 训练STEPS轮with tf.Session() as sess:    init_op = tf.global_variables_initializer()    sess.run(init_op)    STEPS = 20000        for i in range(STEPS):        start = (i*BATCH_SIZE) % 32        end = start + BATCH_SIZE        sess.run(train_step,feed_dict={x: X[start:end],y_ : Y_[start:end]})        if i % 500 == 0:            print "After %d training steps,w1 is " %(i)            print sess.run(w1),"\n"    print "Final w1 is :\n",sess.run(w1) # 输出结果 Final w1 is: [[0.98019385]   [1.01598072]] 通过使损失函数不断的降低,神经网络模型最终得到的参数 w1 = 0.98;w2 = 1.02,所以销量的预测结果为y = 0.98*x1 + 1.02*x2, 在生成数据集时,我们设置的标准答案为 y = x1+x2,所以神经网络预测的结果和标准答案非常的接近,说明预测正确

 # 自定义损失函数:根据问题的实际情况,定制合理的损失函数

对于预测酸奶日销量问题,如果预测销量大于实际销量则会损失成本;如果预测销量小于实际销量则 会损失利润。在实际生活中,往往制造一盒酸奶的成本和销售一盒酸奶的利润是不等价的。因此,需 要使用符合该问题的自定义损失函数。

自定义损失函数为::loss = ∑??(y_, y)

将损失定义成分段函数:

    

上方损失函数表示:若预测的结果y小于标准答案 y_,损失函数为利润乘以预测结果y和标准答案y_之差;如果预测的结果y大于标准答案y_,损失函数为成本乘以预测结果y与标准答案之差

利用Tensorflow表示为:

loss = tf.reduce_sum(tf.where(tf.greater(y,y_),COST(y-y_),PROFIT(y_-y)))

 # 将酸奶的成本定为1元,利润定为9元,则制造成本小于酸奶的利润,所以希望预测的记过y多一些,代码代码如下

#coding:utf-8# 导入模块 生成数据集import tensorflow as tfimport numpy as npBATCH_SIZE = 8SEED = 23455    COST = 1        # 成本PROFIT = 9      # 利润rdm = np.random.RandomState(SEED)X = rdm.rand(32,2)Y_ = [[x1 + x2 + (rdm.rand()/10.0-0.05)] for (x1,x2) in X]#1 定义神经网络参数和输入,输出,定义向前传播的过程x = tf.placeholder(tf.float32, shape=(None,2))y_ = tf.placeholder(tf.float32, shape=(None,1))w1 = tf.Variable(tf.random_normal([2,1], stddev=1, seed=1))y = tf.matmul(x, w1)    # 定义一输出结果y# 定义损失函数反向传播方法# 定义损失函数,使得预测少了损失大,于是模型因该偏向多的方向预测loss = tf.reduce_sum(tf.where(tf.greater(y, y_),(y - y_)*COST,(y_ - y)*PROFIT))train_step = tf.train.GradientDescentOptimizer(0.001).minimize(loss_men) #3 生成会话 训练STEPS轮with tf.Session() as sess:    init_op = tf.global_variables_initializer()    sess.run(init_op)    STEPS = 20000        for i in range(STEPS):        start = (i*BATCH_SIZE) % 32        end = start + BATCH_SIZE        sess.run(train_step,feed_dict={x: X[start:end],y_ : Y_[start:end]})        if i % 500 == 0:            print "After %d training steps,w1 is " %(i)            print sess.run(w1),"\n"    print "Final w1 is :\n",sess.run(w1) # 输出结果 Final w1 is: [[1.02965927]   [1.0484432]] 神经网络最终的参数为w1 = 1.03;w2 = 1.05,销量的预测结果为 y = 1.03*x1 + 1.05*x2,可以看出使用自定义损失函数预测的结果 大于采用均方误差预测的结果,自定义更符合实际需求

 

 # 将酸奶的成本定为9元,利润定为1元,则制造的成本大于利润,所以希望y小一些。代码如下

# 导入模块 生成数据集import tensorflow as tfimport numpy as npBATCH_SIZE = 8SEED = 23455    COST = 9        # 成本PROFIT = 1      # 利润rdm = np.random.RandomState(SEED)X = rdm.rand(32,2)Y_ = [[x1 + x2 + (rdm.rand()/10.0-0.05)] for (x1,x2) in X]#1 定义神经网络参数和输入,输出,定义向前传播的过程x = tf.placeholder(tf.float32, shape=(None,2))y_ = tf.placeholder(tf.float32, shape=(None,1))w1 = tf.Variable(tf.random_normal([2,1], stddev=1, seed=1))y = tf.matmul(x, w1)    # 定义一输出结果y# 定义损失函数反向传播方法# 定义损失函数,使得预测少了损失大,于是模型因该偏向多的方向预测loss = tf.reduce_sum(tf.where(tf.greater(y, y_),(y - y_)*COST,(y_ - y)*PROFIT))train_step = tf.train.GradientDescentOptimizer(0.001).minimize(loss_men) #3 生成会话 训练STEPS轮with tf.Session() as sess:    init_op = tf.global_variables_initializer()    sess.run(init_op)    STEPS = 20000        for i in range(STEPS):        start = (i*BATCH_SIZE) % 32        end = start + BATCH_SIZE        sess.run(train_step,feed_dict={x: X[start:end],y_ : Y_[start:end]})        if i % 500 == 0:            print "After %d training steps,w1 is " %(i)            print sess.run(w1),"\n"    print "Final w1 is :\n",sess.run(w1)# 输出结果Final w1 is:[[0.96004069]  [0.97334176]]神经网络最终的参数为w1 = 0.96;w2 = 0.97,销量的预测结果为 y = 0.96*x1 + 0.97*x2,可以看出使用自定义损失函数预测的结果小于采用均方误差预测的结果,自定义更符合实际需求

 

# 交叉熵

表示两个概率分布之间的距离,交叉熵越大,两个概率分布的距离就越远,两个概率分布越相异;交叉熵越小,两个概率分布距离越相近,两个概率分布越相似

交叉熵计算公式:?(?_ , ?) = −∑?_ ∗ ??? ?

在Tensorflow中表示为:

ce= -tf.reduce_mean(y_* tf.log(tf.clip_by_value(y, 1e-12, 1.0)))

 

例如:两个神经网络模型解决二分类问题中,已知标准答案为 y_ = (1, 0),第一个神经网络模型预测结果为 7 y1=(0.6, 0.4),第二个神经网络模型预测结果为 y2=(0.8, 0.2),判断哪个神经网络模型预测的结果更接近标准答案。

根据交叉熵的计算公式得:

  H1((1,0),(0.6,0.4)) = -(1*log0.6 + 0*log0.4) ≈ -(-0.222 + 0) = 0.222

  H2((1,0),(0.8,0.2)) = -(1*log0.8 + 0*log0.2) ≈ -(-0.097 + 0) = 0.097

由于 0.222>0.097,所以预测结果 y2 与标准答案 y_更接近,y2 预测更准确。

 # softmax函数:

将n分类的n个输出(y1,y2,y3....yn)变为满足以下概率分布要求的函数

    ∀? ?(? = ?) ∈ [?, ?] 且∑? ? (? = ?) = 1

softmax函数表示为:

    

softmax函数的作用:在n分类中,模型会有n个输出,即y1,y2,y3...,yn,其中yi表示第i中情况出现的可能性大小,将n个输出经过sofmax函数,可得到符合概率分布的分类结果

在Tensorflow中,一般先让模型的输出经过softmax函数,得到输出分类的概率分布,再与标准答案进行对比,求出交叉熵,得到损失函数,用Tensorflow实现如下

ce = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y, labels=tf.argmax(y_, 1))cem = tf.reduce_mean(ce)

 

## 神经网络优化--学习率

学习率:表示每次更新的幅度大小,学习率过大,会导致优化参数在最小值附近波动,不收敛;学习率过小,会导致待优化的参数收敛缓慢

在训练过程中,参数的更新向着损失函数梯度下降的方向

参数更新的公式为 ??+? = ?? − ????????_????▽

  wn+1:更新后的参数

  wn:当前参数

  learning_rate:学习率

  ▽:损失函数的梯度(导数)

 例如:损失函数为loss = (w+1),梯度时损失函数的导数为▽ = 2w+2,如果参数的初值为5,学习率为0.2,则参数和损失函数的更新如下

1次 参数w:5 5 - 0.2 * (2 * 5 + 2) = 2.6
2次 参数w:2.6 2.6 - 0.2 * (2 * 2.6 + 2) = 1.16
3次 参数w:1.16 1.16 – 0.2 * (2 * 1.16 + 2) = 0.296
4次 参数w:0.296  

 

 

 

损失函数loss = (w + 1)2  的图像为:

从上图可以看出,损失函数loss的最小值在(-1,0)处,这时损失函数的导数为0,得到最终参数w=-1,代码如下

#coding:utf-8#设置损失函数 loss=(w+1)^2 令w的初始值为5 反向传播就是求最优w 即求最小的loss 对应的wimport tensorflow as tf# 定义待优化的参数W的初始值为5W = tf.Variable(tf.constant(5, dtype=tf.float32))  # 定义损失函数loss = tf.square(W+1) #定义反向传播的方法(0.2为学习率)train_step = tf.train.GradientDescentOptimizer(0.2).minimize(loss) # 生成会话, 训练40轮with tf.Session() as sess:    init_op = tf.global_variables_initializer()    sess.run(init_op)    for i in range(40):        sess.run(train_step)        w_val = sess.run(W)        loss_val = sess.run(loss)        print "After %s steps: W is %f,  loss is %f " % (i,w_val,loss_val) # 最终结果:随着损失函数的值减小,w无限趋近于-1,模型计算推测出最优参数w = -1

 

 # 学习率的设置

学习率过大:参数震荡不收敛;学习率小了:收敛速度慢

指数衰减学习率:学习率随着训练轮数的变化而动态更新

学习率的计算公式

在Tensorflow中表示为:

global_step = tf.Variable(0, trainable=False)learning_rate = tf.train.exponential_decay(LEARNING_RATE_BASE,global_step,   LEARNING_RATE_STEP, LEARNING_RATE_DECAY,  staircase=True/False)
LEARNING_RATE_BASE:学习率的初始值
global_step:标记当前训练的轮数,为不可训练参数
LEARNING_RATE_DECAY:学习率的衰减率 若 staircase 设置为 True 时,表示 global_step/learning rate step 取整数,学习 率阶梯型衰减; 若 staircase 设置为 false 时,学习率会是一条平滑下降的曲线。

 例子:将学习率的初值设置为0.1,将学习率衰减率设置为0.99,BATCH_SIZE设置为1(表示喂入一轮更新一次学习率)

#coding:utf-8#设置损失函数 loss=(w+1)^2 令w的初始值为5 反向传播就是求最优w 即求最小的loss 对应的wimport tensorflow as tfLEARNING_RATE_BASE = 0.1    # 最初的学习率LEARNING_RATE_DECAY = 0.99  # 学习率衰减率LEARNING_RATE_BASE = 1      # 喂入多少轮BATCH_SIZE后,更新一次学习率,一般设置为:总样本数/BATCH_SIZE# 运行了几轮BATCH_SIZE的计数器,初值为0,设为不被训练global_step = tf.Variable(0, trainable=False)# 定义指数下降学习率learning_rate = tf.train.exponential_decay(LEARNING_RATE_BASE,global_step,  LEARNING_RATE_STEP, LEARNING_RATE_DECAY,  staircase=True)# 定义待优化的参数W的初始值为10W = tf.Variable(tf.constant(10, dtype=tf.float32))  # 定义损失函数loss = tf.square(W+1) #定义反向传播的方法(0.2为学习率)train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss,global_step=global_step) # 生成会话, 训练40轮tf.Session() as sess:    init_op = tf.global_variables_initializer()    sess.run(init_op)    for i in range(40):        ess.run(train_step)        w_val = sess.run(W)        loss_val = sess.run(loss)        print "After %s stps: W is %f,  loss is %f " % (i,w_val,loss_val)

 ## 神经网络优化--滑动平均

1:滑动平均:记录一段时间内模型中所有参数w和b各自的平均值。利用滑动平均可以增强模型的泛化能力

2:针对所有的参数进行优化:w和b

3:像是给参数加了影子,参数变化,影子缓慢追随

4:滑动平均(影子)的计算公式:

  影子 = 衰减率 * 影子 + ( 1 - 衰减率 ) * 参数

  影子初值 = 参数初值

  衰减率 = min { MOVING_AVERAGE_DECAY,(1 + 轮数) / (10 + 轮数) }

在Tensorflow中函数表示为:

ema = tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY,global_step) # 其中  MOVING_AVERAGE_DECAY表示滑动平均的衰减率,是个超参数,一般附一个较大的值(接近1的值) # global_step:当前训练了多少轮
ema_op = ema.apply(tf.trainable_variables())# 其中,ema.apply()函数实现对括号内参数求滑动平均,tf.trainable_variables()函数实现把所有待训练参数汇总为列表。
with tf.control_dependencies([train_step, ema_op]):    train_op = tf.no_op(name='train')# 该函数实现将滑动平均和训练过程同步运行

 计算滑动平均例子:

在神经网络模型中,将 MOVING_AVERAGE_DECAY 设置为 0.99,参数 w1 设置为 0,w1 的滑动平均值设置为 0 1:开始时,轮数 global_step 设置为 0,参数 w1 更新为 1,则 w1 的滑动平均值为:  w1 滑动平均值=min(0.99,1/10)*0+(1– min(0.99,1/10)*1 = 0.92:当轮数 global_step 设置为 100 时,参数 w1 更新为 10,以下代码 global_step 保持为 100,每次执行滑动平均操作影子值更新,则滑动平均值变为:  w1 滑动平均值=min(0.99,101/110)*0.9+(1– min(0.99,101/110)*10 = 0.826+0.818=1.6443:再次运行,参数 w1 更新为 1.644,则滑动平均值变为:  w1 滑动平均值=min(0.99,101/110)*1.644+(1– min(0.99,101/110)*10 = 2.3284:再次运行,参数 w1 更新为 2.328,则滑动平均值:  w1 滑动平均值=2.95

计算滑动平均代码如下:

#coding:utf-8import tensorflow as tf# 定义变量及滑动平均类# 定义一个32为的浮点变量,初始值为0.0 这个代码不断的变更w1参数,优化w1的参数,滑动平均做了个w1的影子w1 = tf.Variable(0,dtype=tf.float32)#定义num_updates(NN的迭代轮数)初始的值为0不可被优化(不可被训练),这个参数不参与训练gloable_step = tf.Variable(0,trainable=False)#实例滑动平均类,给删减率为0.99,当前轮数为 gloable_stepMOVING_AVERAGE_DECAY = 0.99ema = tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY,gloable_step)# ema.apply后的括号中是更新列表  每次运行rsess,run(ema_op)  时 对更新列表中的元素求滑动平均值# 在实际的应用中 会使用tf.trainable_variables() 自动将所有待训练的参数汇总为列表ema_op = ema.apply(tf.trainable_variables())with tf.Session() as sess:    # 初始化    init_op = tf.global_variables_initializer()    sess.run(init_op)        # 用ema.average(w1获取w1的滑动平均值  (要运行多个节点 作为列表中的元素列出,写在sess.run中)    #打印出当前参数w1 和w1的滑动平均值    print sess.run([w1,ema.average(w1)])    #参数w1的值赋为1    sess.run(tf.assign(w1,1))    sess.run(ema_op)    print sess.run([w1,ema.average(w1)])    # 更新step 和w1的值 模拟出100轮迭代后 w1的值变为10    sess.run(tf.assign(gloable_step, 100))    sess.run(tf.assign(w1,10))    sess.run(ema_op)    print sess.run([w1,ema.average(w1)])    # 每次执行sess.run会更新一次w1的滑动平均值    sess.run(ema_op)    print sess.run([w1,ema.average(w1)])    sess.run(ema_op)    print sess.run([w1,ema.average(w1)])    sess.run(ema_op)    print sess.run([w1,ema.average(w1)])    sess.run(ema_op)    print sess.run([w1,ema.average(w1)])     sess.run(ema_op)    print sess.run([w1,ema.average(w1)])    sess.run(ema_op)    print sess.run([w1,ema.average(w1)])

 ## 神经网络优化--正则化

过拟合:神经网络模型在训练数据集上准确率较高,在新的数据进行预测或分类时准确率较低,说明模型的泛型差

利用正则化来缓解过拟合:正则化在损失函数中引入模型复杂度指标,利用给W加权值,弱化了训练数据的噪声(一般不对b进行正则化)

使用正则化后,损失函数 loss 变为亮相之和:

  loss = loss(y 与 y_) + REGULARIZER*loss(w)

  loss(y 与 y_) :模型中所有参数的损失函数,如交叉熵,均方误差

  REGULARIZER:用超参数 REGULARIZER 给出参数w在总loss中的比例,即正则化的权重

  loss(w):其中 w 表示需要正则化的参数

正则化的计算方法

1:L1 正则化: ?????? = ∑? | ?? |

在Tensorflow中表示为“

loss(w) = tf.contrib.layers.l1_regularizer(REGULARIZER)(w)

 2:L2 正则化: ?????? = ∑? | ?? | 2 

在Tensorflow中表示为

loss(w) = tf.contrib.layers.l2_regularizer(REGULARIZER)(w)

 用Tensorflow实现正则化:

ce = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y, labels=tf.argmax(y_, 1))cem = tf.reduce_mean(ce)tf.add_to_collection('losses', tf.contrib.layers.l2_regularizer(regularizer)(w))loss = cem + tf.add_n(tf.get_collection('losses'))

 例子:

用 300 个符合正态分布的点 X[x0, x1]作为数据集,根据点 X[x0, x1]计算生成标注 Y_,将数据集 标注为红色点和蓝色点。

标注规则为:当 x0 2 + x1 2 < 2 时,y_=1,标注为红色;当 x0 2 + x1 2 ≥2 时,y_=0,标注为蓝色。

我们分别用无正则化和有正则化两种方法,拟合曲线,把红色点和蓝色点分开。在实际分类时, 如果前向传播输出的预测值 y 接近 1 则为红色点概率越大,接近 0 则为蓝色点概率越大,输出的预 测值 y 为 0.5 是红蓝点概率分界线。

 代码如下:

#coding:utf-8import tensorflow as tfimport numpy as npimport matplotlib.pyplot as pltBATCH_SIZE = 30seed = 2# 基于seed产生随机数rdm = np.random.RandomState(seed)# 随机数返回300行2列的急诊,表示300组坐标(x0,x1)作为输入数据集X = rdm.randn(300,2)# 从X这个300行2列的矩阵中取出一行,判断如果两个坐标的平方和小于2,给Y赋值1,其余赋值为0Y_ = [int(x0 * x0 + x1*x1 < 2) for (x0,x1) in X]# 遍历y中的每个元素,1赋值为red,其余赋值为blueY_c = [['red' if y else "blue"] for y in Y_]# 对数据集X和标签Y进行shape整理,第一个元素为-1表示,随机第二个参数计算得到,第二个元素表示多少列,把X整理为n行2列,把Y整理为n行1列X = np.vstack(X).reshape(-1,2)Y_ = np.vstack(Y_).reshape(-1,1)print (X)print (Y_)print (Y_c)# 用plt.scatter画出数据集X隔行中的第0列元素和第1列元素的点即隔行的(x0x1),用Y_c对应的值表示颜色plt.scatter(X[:,0],X[:,1],c=np.squeeze(Y_c))plt.show()# 定义神经网络的输入输出参数,定义向前传播的过程def get_weight(shqpe,regularizer):    W = tf.Variable(tf.random_normal(shqpe),dtype=tf.float32)    tf.add_to_collection('losses', tf.contrib.layers.l2_regularizer(regularizer)(W))    return Wdef get_bias(shape):    b = tf.Variable(tf.constant(0.01,shape=shape))    return bx = tf.placeholder(tf.float32,shape=(None,2))y_ = tf.placeholder(tf.float32,shape=(None,1))w1 = get_weight([2,11],0.01)b1 = get_bias([11])y1 = tf.nn.relu(tf.matmul(x,w1)+b1)w2 = get_weight([11,1],0.01)b2 = get_bias([1])y = tf.matmul(y1,w2)+b2# 定义损失函数loss_mse = tf.reduce_mean(tf.square(y-y_))loss_total = loss_mse + tf.add_n(tf.get_collection('losses'))# 定义反向传播方法:不含正则化train_step = tf.train.AdamOptimizer(0.0001).minimize(loss_mse)with tf.Session() as sess:    init_op = tf.global_variables_initializer()    sess.run(init_op)    STEPS = 40000    for i in range(STEPS):        start = (i*BATCH_SIZE) % 300        end = start + BATCH_SIZE        sess.run(train_step,feed_dict={x:X[start:end],y_:Y_[start:end]})        if i % 2000 == 0:            loss_mse_v = sess.run(loss_mse,feed_dict={x:X,y_:Y_})            print ("After %d steps,loss is :%f" %(i,loss_v))    # xx在-3到3之间以步长为0.01,yy在-3到3之间以步长为0.01,生成二维网络坐标点            xx,yy = np.mgrid[-3:3:.01,-3:3:.01]        # 将xx,yy拉直,合并成一个2列的矩阵,得到一个网络坐标点集合    grid = np.c_[xx.ravel(),yy.ravel()]        # 将网络坐标点喂入伸进网络,probs为输出    probs = sess.run(y,feed_dict={x:grid})        # probs的shape调整成xx的样子    probs = probs.reshape(xx.shape)    print ("w1:\n",sess.run(w1))    print ("b1:\n",sess.run(b1))    print ("w2:\n",sess.run(w2))plt.scatter(X[:,0],X[:,1],c=np.squeeze(Y_c))plt.contour(xx,yy,probs,lecels=[.5])plt.show()# 定义反向传播的方法:包含正则化train_step = tf.train.AdamOptimizer(0.0001).minimize(loss_total)with tf.Session() as sess:    init_op = tf.global_variables_initializer()    sess.run(init_op)    STEPS = 40000    for i in range(STEPS):        start = (i*BATCH_SIZE) % 300        end = start + BATCH_SIZE        sess.run(train_step,feed_dict={x:X[start:end],y_:Y_[start:end]})        if i % 2000 == 0:            loss_v = sess.run(loss_total,feed_dict={x:X,y_:Y_})            print ("After %d steps,loss is :%f" %(i,loss_v))    xx,yy = np.mgrid[-3:3:.01,-3:3:.01]    grid = np.c_[xx.ravel(),yy.ravel()]    probs = sess.run(y,feed_dict={x:grid})    probs = probs.reshape(xx.shape)    print ("w1:\n",sess.run(w1))    print ("b1:\n",sess.run(b1))    print ("w2:\n",sess.run(w2))    print ("b2:\n",sess.run(b2))plt.scatter(X[:,0],X[:,1],c=np.squeeze(Y_c))plt.contour(xx,yy,probs,lecels=[.5])plt.show()

执行代码,效果如下图所示

然后执行无正则化的训练过程,将途中红色点和蓝色点分开,如下图所示

最后执行有正则化的训练过程,将红色点和蓝色点分开,生成的曲线如下图所示

对比无正则化与有正则化的训练结果,可以看出有正则化模型的拟合曲线平滑,模型具有更好的泛化能力

## 搭建模块化神经网络八股

# 前向传播的目的:搭建网络,设计网络结构,由输入到输出,搭建完整的网络结构

描述前向创博的过程需要定义三个函数:

定义第一个函数:forward(),该函数完成网络结构的设计,从输入到输出搭建完整的网络结构,实现前向传播的过程。其中参数x为输入,regularzer为正则化的权重,返回值为预测分类或则是结果y

def forward(x,regularizer):    w =     b =     y =     return y

第二个函数 :get_weight()对参数 w 设定。该函数中,参数 shape 表示参数 w 的形状,regularizer 表示正则化权重,返回值为参数 w。其中,tf.variable()给 w 赋初值,tf.add_to_collection()表 示将参数 w 正则化损失加到总损失 losses 中,返回w

def get_weight(shape, regularizer):    w = tf.Variable()    tf.add_to_collection('losses',     tf.contrib.layers.l2_regularizer(regularizer)(w))    return w

 第三个函数: get_bias()对参数 b 进行设定,其实就是某层中b的个数。该函数中,参数 shape 表示参数 b 的形状,返回值为参数 b。其中,tf.variable()表示给 b 赋初值,返回b

def get_bias(shape):    b = tf.Variable()    return b

 # 反向传播:训练网络,优化网络参数

函数 backward()中,placeholder()实现对数据集 x 和标准答案 y_占位,forward.forward()实现前向 传播的网络结构,参数 global_step 表示训练轮数,设置为不可训练型参数。 20 在训练网络模型时,常将正则化、指数衰减学习率和滑动平均这三个方法作为模型优化方法。

def backward( ):     x = tf.placeholder( )    y_ = tf.placeholder( )    y = forward.forward(x, REGULARIZER)    global_step = tf.Variable(0, trainable=False)    loss =

 

 以上的内容在之前都有体现,这里不再指出...

 本笔记整理自:慕课Tensorflow笔记

转载于:https://www.cnblogs.com/Doaoao/p/10700323.html

你可能感兴趣的文章
Android 最简单的自定义Dialog之一
查看>>
磨刀不误砍柴 - 配置适合工作学习的桌面环境
查看>>
Java笔记-反射机制(一)
查看>>
redux v3.7.2源码解读与学习之 applyMiddleware
查看>>
【React】为什么我不再使用setState?
查看>>
Git原理与高级使用(3)
查看>>
从JDK源码看Writer
查看>>
Express 结合 Webpack 实现HMRwi
查看>>
基于protobuf的RPC实现
查看>>
坚信每个人都能成为品牌
查看>>
JAVA的对象复制
查看>>
jquery要怎么写才能速度最快?(转)
查看>>
cisco设备IOS上传、备份、设置启动IOS
查看>>
打开Office报错
查看>>
我的友情链接
查看>>
AsyncTask简易使用
查看>>
关于PHP sessions的超时设置
查看>>
HAProxy负载均衡原理及企业级实例部署haproxy集群
查看>>
开源中国动弹客户端实践(三)
查看>>
Win 8创造颠覆性体验:预览版关键更新
查看>>