一、完善常用概念和细节

1、神经元模型:

  之前的神经元结构都采用线上的权重w直接乘以输入数据x,用数学表达式即,但这样的结构不够完善。

  完善的结构需要加上偏置,并加上激励函数。用数学公式表示为:。其中f为激励函数。

  神经网络就是由以这样的神经元为基本单位构成的。

  

2、激活函数

  引入非线性激活因素,提高模型的表达力。

  常用的激活函数有:

  (1)relu函数,用 tf.nn.relu()表示

  

  (2)sigmoid函数,用 tf.nn.sigmoid()表示

  

  (3)tanh函数,用 tf.nn.tanh()表示

  

3、神经网络的复杂度

  可以用神经网络的层数和神经网络待优化的参数个数来表示

4、神经网络的层数

  层数=n个隐藏层 + 1个输出层

  注意:一般不计入输入层

5、神经网络待优化的参数

  神经网络所有参数w、b的个数

  举例:下图为神经网络示意图

  

  在该神经网络中,包含1个输入层、1个隐藏层和1个输出层,该神经网络的层数为2层。(不计入输入层)

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

二、神经网络优化

上一节讲了神经网络前向传播和后向传播大体框架,这一节讨论神经网络的优化问题。

1、损失函数(loss)

  用来表示预测值(y)与已知答案(y_)的差距。在训练神经网络时,通过不断改变神经网络中所有参数,使损失函数不断减小,从而训练出更高准确率的神经网络模型。

  常用的损失函数有:

  (1)均方误差(mse)

  之前的随笔有提到过,所谓均方误差就是n个样本的预测值y与已知答案y_之差的平方和,再求平均值

  数学公式为,在Tensorflow中表示为 tf.reduce_mean(tf.square(y-y_))

  在本篇文章中我们用一个预测酸奶日销量 y 的例子来验证神经网络优化的效果。x1、x2是影响日销量的两个因素。由于目前没有数据集,所以利用随机函数生成x1、x2,制造标准答案y_=x1+x2,为了更真实,求和后还添加了正负0.05的随机噪声。

  选择mse的损失函数,把自制的数据集喂入神经网络,构建神经网络,看训练出来的参数是否和标准答案y_ = x1+x2

  代码如下:

  1. import tensorflow as tf
  2. import numpy as np
  3.  
  4. BATCH_SIZE = 8
  5. SEED = 23455
  6.  
  7. # 构造数据集
  8. rdm = np.random.RandomState(SEED)
  9. X = rdm.rand(32,2)
  10. Y_ = [[x1+x2+(rdm.rand()/10.0-0.05)] for (x1, x2) in X] # rand()会构造0-1的随机数,/10之后构造0-0.1的随机数,0~0.1-0.05相当于构造了-0.05~+0.05的随机数,也就是我们需要的噪声
  11.  
  12. #1定义神经网络的输入、参数和输出,定义前向传播过程。
  13. x = tf.placeholder(tf.float32, shape=(None, 2))
  14. y_ = tf.placeholder(tf.float32, shape=(None, 1))
  15. w1= tf.Variable(tf.random_normal([2, 1], stddev=1, seed=1))
  16. y = tf.matmul(x, w1)
  17.  
  18. #2定义损失函数及反向传播方法。
  19. #定义损失函数为MSE,反向传播方法为梯度下降。
  20. loss_mse = tf.reduce_mean(tf.square(y_ - y))
  21. train_step = tf.train.GradientDescentOptimizer(0.001).minimize(loss_mse)
  22.  
  23. #3生成会话,训练STEPS轮
  24. with tf.Session() as sess:
  25. init_op = tf.global_variables_initializer()
  26. sess.run(init_op)
  27. STEPS = 20000
  28. for i in range(STEPS):
  29. start = (i*BATCH_SIZE) % 32
  30. end = (i*BATCH_SIZE) % 32 + BATCH_SIZE
  31. sess.run(train_step, feed_dict={x: X[start:end], y_: Y_[start:end]})
  32. if i % 500 == 0:
  33. print("After %d training steps, w1 is: " % (i))
  34. print(sess.run(w1), "\n")
  35. print("Final w1 is: \n", sess.run(w1))

最后的训练结果为:

  1. Final w1 is:
  2. [[0.98019385]
  3. [1.0159807 ]]

显然w1、w2是趋近于答案1的。这部分的NN和上一篇笔记没什么太多不一样的地方,只是训练了两个权重而已。 

  (2)自定义

上面的模型中,损失函数采用的是MSE,但根据事实情况我们知道,销量预测问题不是简单的成本和利润相等问题。如果预测多了,卖不出去,损失的是成本,反之预测少了,损失的是利润,现实情况往往利润和成本是不相等的。因此,需要使用符合该问题的自定义损失函数。

自定义损失函数数学公式为:loss = Σnf(y_,y)

到本问题中可以定义成分段函数:

用tf的函数表示为:loss = tf.reduce_sum(tf.where(tf.greater(y,y_),cost(y-y_),PROFIT(y_-y)))

现在假设酸奶成本为1元,利润为9元,显然希望多预测点,这样我们只需改变上面代码中的损失函数,指定一下cost和profit的值就可以了。代码训练结果为:

  1. Final w1 is:
  2. [[1.0296593]
  3. [1.0484141]]

显然要比单纯的y=x1+x2要多预测。

那么如果现在假设酸奶成本为9元,利润为1元,又会得到怎样的参数呢。训练结果为:

  1. Final w1 is:
  2. [[0.9600407]
  3. [0.9733418]]

显然比y=x1+x2要少预测。这是符合我们想法的。

因此,综上所述,采用自定义损失函数的方法可能更符合预测结果。

  (3)交叉熵(Cross Entropy)

表示两个概率分布之间的距离,交叉熵越大,说明两个概率分布距离越远,两个概率分布越相异;

交叉熵越小,说明两个概率分布距离越近,两个概率分布越相似。

交叉熵计算公式为:H(y_,y)=-Σy_ * log10 y

在tf中表示为:ce = -tf.reduce_mean(y_ * tf.log(tf.clip_by_value(y,1e-12,1.0)))     # 确保y<1e-12为1e-2,y>1为1

举一个数学的例子,比如标准答案y_=(1,0)。y1=(0.6,0.4 )  y2=(0.8,0.2),哪个更接近标准答案呢。

但是为了能够将输出变为满足概率分布在(0,1)上,我么们需要使用softmax函数

在tf中,一般让模型的输出经过softmax函数,进而获得输出分类的概率分布,再与标准答案对比,求得交叉熵,得到损失函数,并且有专门的函数。

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

cem = tf.reduce_mean(ce)

这也就代替了ce = -tf.reduce_mean(y_ * tf.log(tf.clip_by_value(y,1e-12,1.0)))    这句函数

2、学习率

上一篇笔记中有讨论过学习率的问题,得到的大致结论是:学习率过大,会导致待优化参数在最小值附近波动,不收敛;学习率过小,导致训练次数增大,收敛缓慢

在这里我们需要展开讨论有关学习率的问题。

(1)随机梯度下降算法更新参数

首先随机梯度下降方法更新参数的公式为:wn+1=wn - learning_rate * ▽  (▽表示损失函数关于参数的偏导)

如果参数初值为5,学习率为0.2,则参数更新情况为:

再举个例子,如果损失函数为loss=(w+1)2,画出函数图像为:

能看的出来,如果损失函数使用随机梯度下降优化器,loss的最小值应该是0,此时参数w为-1 。

(2)指数衰减学习率

        指数衰减学习率就是指学习率会随着训练轮数变化而实现动态更新,它不再是一个定值。

计算公式为:learning_rate = learning_rate_base *   learning_rate_decay global_step/learning_rate_step

这里面的概念:

learning_rate_base:学习率基数,一般认为和学习率初始值相等

learning_rate_decay:学习率衰减率,范围是(0,1)

global_step:运行了几轮batch_size

learning_rate_step:多少论更新一次学习率=总样本数/batch_size

在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)    # 其他的参数已经在上面提到过,最后一个参数staircase,当设置为True时,表示global_step/learning_rate_step取整数,学习率阶梯型衰减;若为False,学习率是一条平滑下降的曲线。

在代码中展示指数衰减学习率:

  1. #设损失函数 loss=(w+1)^2, 令w初值是常数10。反向传播就是求最优w,即求最小loss对应的w值
  2. #使用指数衰减的学习率,在迭代初期得到较高的下降速度,可以在较小的训练轮数下取得更有收敛度。
  3. import tensorflow as tf
  4.  
  5. LEARNING_RATE_BASE = 0.1 #最初学习率
  6. LEARNING_RATE_DECAY = 0.99 #学习率衰减率
  7. LEARNING_RATE_STEP = 1 #喂入多少轮BATCH_SIZE后,更新一次学习率,一般设为:总样本数/BATCH_SIZE
  8.  
  9. #运行了几轮BATCH_SIZE的计数器,初值给0, 设为不被训练
  10. global_step = tf.Variable(0, trainable=False)
  11. #定义指数下降学习率
  12. learning_rate = tf.train.exponential_decay(LEARNING_RATE_BASE, global_step, LEARNING_RATE_STEP, LEARNING_RATE_DECAY, staircase=True)
  13. #定义待优化参数,初值给10
  14. w = tf.Variable(tf.constant(10, dtype=tf.float32))
  15. #定义损失函数loss
  16. loss = tf.square(w+1)
  17. #定义反向传播方法
  18. train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss, global_step=global_step)
  19. #生成会话,训练40轮
  20. with tf.Session() as sess:
  21. init_op=tf.global_variables_initializer()
  22. sess.run(init_op)
  23. for i in range(40):
  24. sess.run(train_step)
  25. learning_rate_val = sess.run(learning_rate)
  26. global_step_val = sess.run(global_step) # global_step也要放在会话中运行,要不然怎么更新
  27. w_val = sess.run(w)
  28. loss_val = sess.run(loss)
  29. print("After %s steps: global_step is %f, w is %f, learning rate is %f, loss is %f" % (i, global_step_val, w_val, learning_rate_val, loss_val))

运行显示结果为

  1. After 0 steps: global_step is 1.000000, w is 7.800000, learning rate is 0.099000, loss is 77.440002
  2. After 1 steps: global_step is 2.000000, w is 6.057600, learning rate is 0.098010, loss is 49.809719
  3. After 2 steps: global_step is 3.000000, w is 4.674170, learning rate is 0.097030, loss is 32.196201
  4. After 3 steps: global_step is 4.000000, w is 3.573041, learning rate is 0.096060, loss is 20.912704
  5. After 4 steps: global_step is 5.000000, w is 2.694472, learning rate is 0.095099, loss is 13.649124
  6. After 5 steps: global_step is 6.000000, w is 1.991791, learning rate is 0.094148, loss is 8.950812
  7. After 6 steps: global_step is 7.000000, w is 1.428448, learning rate is 0.093207, loss is 5.897362
  8. After 7 steps: global_step is 8.000000, w is 0.975754, learning rate is 0.092274, loss is 3.903603
  9. After 8 steps: global_step is 9.000000, w is 0.611131, learning rate is 0.091352, loss is 2.595742
  10. After 9 steps: global_step is 10.000000, w is 0.316771, learning rate is 0.090438, loss is 1.733887
  11. After 10 steps: global_step is 11.000000, w is 0.078598, learning rate is 0.089534, loss is 1.163375
  12. After 11 steps: global_step is 12.000000, w is -0.114544, learning rate is 0.088638, loss is 0.784033
  13. After 12 steps: global_step is 13.000000, w is -0.271515, learning rate is 0.087752, loss is 0.530691
  14. After 13 steps: global_step is 14.000000, w is -0.399367, learning rate is 0.086875, loss is 0.360760
  15. After 14 steps: global_step is 15.000000, w is -0.503726, learning rate is 0.086006, loss is 0.246287
  16. After 15 steps: global_step is 16.000000, w is -0.589091, learning rate is 0.085146, loss is 0.168846
  17. After 16 steps: global_step is 17.000000, w is -0.659066, learning rate is 0.084294, loss is 0.116236
  18. After 17 steps: global_step is 18.000000, w is -0.716543, learning rate is 0.083451, loss is 0.080348
  19. After 18 steps: global_step is 19.000000, w is -0.763853, learning rate is 0.082617, loss is 0.055765
  20. After 19 steps: global_step is 20.000000, w is -0.802872, learning rate is 0.081791, loss is 0.038859
  21. After 20 steps: global_step is 21.000000, w is -0.835119, learning rate is 0.080973, loss is 0.027186
  22. After 21 steps: global_step is 22.000000, w is -0.861821, learning rate is 0.080163, loss is 0.019094
  23. After 22 steps: global_step is 23.000000, w is -0.883974, learning rate is 0.079361, loss is 0.013462
  24. After 23 steps: global_step is 24.000000, w is -0.902390, learning rate is 0.078568, loss is 0.009528
  25. After 24 steps: global_step is 25.000000, w is -0.917728, learning rate is 0.077782, loss is 0.006769
  26. After 25 steps: global_step is 26.000000, w is -0.930527, learning rate is 0.077004, loss is 0.004827
  27. After 26 steps: global_step is 27.000000, w is -0.941226, learning rate is 0.076234, loss is 0.003454
  28. After 27 steps: global_step is 28.000000, w is -0.950187, learning rate is 0.075472, loss is 0.002481
  29. After 28 steps: global_step is 29.000000, w is -0.957706, learning rate is 0.074717, loss is 0.001789
  30. After 29 steps: global_step is 30.000000, w is -0.964026, learning rate is 0.073970, loss is 0.001294
  31. After 30 steps: global_step is 31.000000, w is -0.969348, learning rate is 0.073230, loss is 0.000940
  32. After 31 steps: global_step is 32.000000, w is -0.973838, learning rate is 0.072498, loss is 0.000684
  33. After 32 steps: global_step is 33.000000, w is -0.977631, learning rate is 0.071773, loss is 0.000500
  34. After 33 steps: global_step is 34.000000, w is -0.980842, learning rate is 0.071055, loss is 0.000367
  35. After 34 steps: global_step is 35.000000, w is -0.983565, learning rate is 0.070345, loss is 0.000270
  36. After 35 steps: global_step is 36.000000, w is -0.985877, learning rate is 0.069641, loss is 0.000199
  37. After 36 steps: global_step is 37.000000, w is -0.987844, learning rate is 0.068945, loss is 0.000148
  38. After 37 steps: global_step is 38.000000, w is -0.989520, learning rate is 0.068255, loss is 0.000110
  39. After 38 steps: global_step is 39.000000, w is -0.990951, learning rate is 0.067573, loss is 0.000082
  40. After 39 steps: global_step is 40.000000, w is -0.992174, learning rate is 0.066897, loss is 0.000061

根据损失函数的公式,我们知道理论上w在-1时,loss取最小值为0.显然结果是符合理论的。

这里留下一个待解决的问题,改变指数衰减学习率公式中的几个参数, 会对训练次数,权重更新,学习率,损失值分别有什么影响?

3、滑动平均(影子)

滑动平均值(也有人称为影子值),记录了一段时间内模型中所有的参数w和b各自的平均值。使用影子值可以增强模型的泛化能力。就感觉是给参数加了影子,参数变化,影子缓慢跟随。

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

其中,影子初值 = 参数初值;衰减率 = min{moving_average_decay , (1+轮数)/(10+轮数) }

例如,moving_average_decay赋值为0.99,参数w设置为0,影子值为0

(1)    开始时,训练轮数为0,参数更新为1,则w的影子值为:

影子 = min(0.99,1/10)*0+(1-min(0.99,1/10))*1=0.9

(2)    当训练轮数为100时,参数w更新为10,则w的影子值为:

影子 = min(0.99,101/110)*0.9+(1– min(0.99,101/110)*10 = 0.826+0.818=1.644

(3)    当训练轮数为100时,参数w更新为1.644,则w的影子值为:

影子 = min(0.99,101/110)*1.644+(1– min(0.99,101/110)*10 = 2.328

(4)    当训练轮数为100时,参数w更新为2.328,则w的影子值为:

影子 = 2.956

用tensorflow函数可以表示为以下内容:(相关注释在完整代码中写)

ema = tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY, global_step)

ema_op = ema.apply(tf.trainable_variables())

with tf.control_dependencies([train_step, ema_op]):
                train_op = tf.no_op(name='train')

所以上面的例子用完整的滑动平均代码为:

  1. import tensorflow as tf
  2.  
  3. # 1. 定义变量及滑动平均类
  4. # 定义一个32位浮点变量,初始值为0.0 这个代码就是不断更新w1参数,优化w1参数,滑动平均做了个w1的影子
  5. w1 = tf.Variable(0, dtype=tf.float32)
  6. # 定义num_updates(NN的迭代轮数),初始值为0,不可被优化(训练),这个参数不训练
  7. global_step = tf.Variable(0, trainable=False)
  8. # 实例化滑动平均类,给衰减率为0.99,一般赋值为接近1的值
  9. MOVING_AVERAGE_DECAY = 0.99
  10. ema = tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY, global_step)
  11.  
  12. # ema.apply后的括号里是更新列表,每次运行sess.run(ema_op)时,对更新列表中的元素求滑动平均值。
  13. # ema.apply()函数实现对括号内参数求滑动平均
  14. # 在实际应用中会使用tf.trainable_variables()自动将所有待训练的参数汇总为列表
  15. # ema_op = ema.apply([w1])
  16. ema_op = ema.apply(tf.trainable_variables())
  17.  
  18. # 2. 查看不同迭代中变量取值的变化。
  19. with tf.Session() as sess:
  20. # 初始化
  21. init_op = tf.global_variables_initializer()
  22. sess.run(init_op)
  23. # 用ema.average(w1)获取w1滑动平均值 (要运行多个节点,作为列表中的元素列出,写在sess.run中)
  24. # 打印出当前参数w1和w1滑动平均值
  25. print("current global_step:", sess.run(global_step))
  26. print("current w1", sess.run([w1, ema.average(w1)]))
  27.  
  28. # 参数w1的值赋为1
  29. sess.run(tf.assign(w1, 1))
  30. sess.run(ema_op)
  31. print("current global_step:", sess.run(global_step))
  32. print("current w1", sess.run([w1, ema.average(w1)]))
  33.  
  34. # 更新global_step和w1的值,模拟出轮数为100时,参数w1变为10, 以下代码global_step保持为100,每次执行滑动平均操作,影子值会更新
  35. sess.run(tf.assign(global_step, 100))
  36. sess.run(tf.assign(w1, 10))
  37. sess.run(ema_op)
  38. print("current global_step:", sess.run(global_step))
  39. print("current w1:", sess.run([w1, ema.average(w1)]))
  40.  
  41. # 每次sess.run会更新一次w1的滑动平均值
  42. sess.run(ema_op)
  43. print("current global_step:", sess.run(global_step))
  44. print("current w1:", sess.run([w1, ema.average(w1)]))
  45.  
  46. sess.run(ema_op)
  47. print("current global_step:", sess.run(global_step))
  48. print("current w1:", sess.run([w1, ema.average(w1)]))

多次执行训练轮数为100的ema_op,观察影子值,运行结果为:

  1. current global_step: 0
  2. current w1 [0.0, 0.0]
  3. current global_step: 0
  4. current w1 [1.0, 0.9]
  5. current global_step: 100
  6. current w1: [10.0, 1.6445453]
  7. current global_step: 100
  8. current w1: [10.0, 2.3281732]
  9. current global_step: 100
  10. current w1: [10.0, 2.955868]
  11. current global_step: 100
  12. current w1: [10.0, 3.532206]
  13. current global_step: 100
  14. current w1: [10.0, 4.061389]
  15. current global_step: 100
  16. current w1: [10.0, 4.547275]
  17. current global_step: 100
  18. current w1: [10.0, 4.9934072]

能够看得出来,训练轮数不变的时候,影子值一直在逼近于10,说明影子值随参数的改变而改变。有一个“影子追随“的感觉。

4、正则化

正则化是解决神经网络过拟合的有效方法。自然要先提一下过拟合问题。

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

正则化:在损失函数中给每个参数w加上权重,引入模型复杂度指标,从而抑制模型噪声,减小过拟合。

           根据正则化的定义,我们可以得出新的损失函数值:、

loss = loss(y-y_) + regularizer* loss(w)               第一项是预测结果与标准答案的差距,第二项是正则化计算结果

正则化有两种计算方法:

(1)L1正则化:lossL1 = ∑|wi|  ,  tf函数表示为:loss(w) = tf.contrib.layers.l1_regularizer(regularizer)(w)

(2)L2正则化:lossL2 = ∑|wi|2 ,  tf函数表示为:loss(w) = tf.contrib.layers.l2_regularizer(regularizer)(w)

正则化实现用tensorflow可以表示为:

tf.add_to_collection('losses', tf.contrib.layers.l2_regularizer(regularizer)(w)

loss = cem + tf.add_n(tf.get_collection('losses'))        # cem即交叉熵损失函数的值

举例:

随机生成300个符合正态分布的点(x0,x1),当x02+x12<2 时,y_=1,标注为红色,x02+x12≥2时,y_=0,标注为蓝色。使用matplotlib模块分别画出无正则化和有正则化的拟合曲线

  1. import tensorflow as tf
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4.  
  5. BATCH_SIZE = 30
  6. seed = 2
  7. # 基于seed产生随机数
  8. rdm = np.random.RandomState(seed)
  9. # 随机数返回300行2列的矩阵,表示300组坐标点(x0,x1)作为输入数据集
  10. # randn()函数是从正态分布中返回样本值,rand()函数是从(0,1)中返回样本值
  11. X = rdm.randn(300, 2)
  12. # 从X这个300行2列的矩阵中取出一行,判断如果两个坐标的平方和小于2,给Y赋值1,其余赋值0
  13. # 作为输入数据集的标签(正确答案)
  14. Y_ = [int(x0 * x0 + x1 * x1 < 2) for (x0, x1) in X]
  15. # 遍历Y中的每个元素,1赋值'red'其余赋值'blue',这样可视化显示时人可以直观区分
  16. Y_c = [['red' if y else 'blue'] for y in Y_]
  17. # 对数据集X和标签Y进行shape整理,第一个元素为-1表示,随第二个参数计算得到,第二个元素表示多少列,把X整理为n行2列,把Y整理为n行1列
  18. X = np.vstack(X).reshape(-1, 2)
  19. Y_ = np.vstack(Y_).reshape(-1, 1)
  20. print(X)
  21. print(Y_)
  22. print(Y_c)
  23. # 用plt.scatter画出数据集X各行中第0列元素和第1列元素的点即各行的(x0,x1),用各行Y_c对应的值表示颜色(c是color的缩写)
  24. plt.scatter(X[:, 0], X[:, 1], c=np.squeeze(Y_c))
  25. plt.show()
  26.  
  27. # 定义神经网络的输入、参数和输出,定义前向传播过程
  28. def get_weight(shape, regularizer):
  29. w = tf.Variable(tf.random_normal(shape), dtype=tf.float32)
  30. tf.add_to_collection('losses', tf.contrib.layers.l2_regularizer(regularizer)(w))
  31. return w
  32.  
  33. def get_bias(shape):
  34. b = tf.Variable(tf.constant(0.01, shape=shape))
  35. return b
  36.  
  37. x = tf.placeholder(tf.float32, shape=(None, 2))
  38. y_ = tf.placeholder(tf.float32, shape=(None, 1))
  39.  
  40. w1 = get_weight([2, 11], 0.01)
  41. b1 = get_bias([11])
  42. y1 = tf.nn.relu(tf.matmul(x, w1) + b1)
  43.  
  44. w2 = get_weight([11, 1], 0.01)
  45. b2 = get_bias([1])
  46. y = tf.matmul(y1, w2) + b2
  47.  
  48. # 定义损失函数
  49. loss_mse = tf.reduce_mean(tf.square(y - y_))
  50. loss_total = loss_mse + tf.add_n(tf.get_collection('losses'))
  51.  
  52. # 定义反向传播方法:不含正则化
  53. train_step = tf.train.AdamOptimizer(0.0001).minimize(loss_mse)
  54.  
  55. with tf.Session() as sess:
  56. init_op = tf.global_variables_initializer()
  57. sess.run(init_op)
  58. STEPS = 40000
  59. for i in range(STEPS):
  60. start = (i * BATCH_SIZE) % 300
  61. end = start + BATCH_SIZE
  62. sess.run(train_step, feed_dict={x: X[start:end], y_: Y_[start:end]})
  63. if i % 2000 == 0:
  64. loss_mse_v = sess.run(loss_mse, feed_dict={x: X, y_: Y_})
  65. print("After %d steps, loss is: %f" % (i, loss_mse_v))
  66. # xx在-3到3之间以步长为0.01,yy在-3到3之间以步长0.01,生成二维网格坐标点
  67. xx, yy = np.mgrid[-3:3:.01, -3:3:.01]
  68. # 将xx , yy拉直,并合并成一个2列的矩阵,得到一个网格坐标点的集合
  69. grid = np.c_[xx.ravel(), yy.ravel()]
  70. # 将网格坐标点喂入神经网络 ,probs为输出
  71. probs = sess.run(y, feed_dict={x: grid})
  72. # probs的shape调整成xx的样子
  73. probs = probs.reshape(xx.shape)
  74. print("w1:\n", sess.run(w1))
  75. print("b1:\n", sess.run(b1))
  76. print("w2:\n", sess.run(w2))
  77. print("b2:\n", sess.run(b2))
  78.  
  79. plt.scatter(X[:, 0], X[:, 1], c=np.squeeze(Y_c))
  80. plt.contour(xx, yy, probs, levels=[.5])
  81. plt.show()
  82.  
  83. # 定义反向传播方法:包含正则化
  84. train_step = tf.train.AdamOptimizer(0.0001).minimize(loss_total)
  85.  
  86. with tf.Session() as sess:
  87. init_op = tf.global_variables_initializer()
  88. sess.run(init_op)
  89. STEPS = 40000
  90. for i in range(STEPS):
  91. start = (i * BATCH_SIZE) % 300
  92. end = start + BATCH_SIZE
  93. sess.run(train_step, feed_dict={x: X[start:end], y_: Y_[start:end]})
  94. if i % 2000 == 0:
  95. loss_v = sess.run(loss_total, feed_dict={x: X, y_: Y_}) # 与未正则化相比,这个地方的loss_mse换成了loss_total
  96. print("After %d steps, loss is: %f" % (i, loss_v))
  97.  
  98. xx, yy = np.mgrid[-3:3:.01, -3:3:.01]
  99. grid = np.c_[xx.ravel(), yy.ravel()]
  100. probs = sess.run(y, feed_dict={x: grid})
  101. probs = probs.reshape(xx.shape)
  102. print("w1:\n", sess.run(w1))
  103. print("b1:\n", sess.run(b1))
  104. print("w2:\n", sess.run(w2))
  105. print("b2:\n", sess.run(b2))
  106.  
  107. plt.scatter(X[:, 0], X[:, 1], c=np.squeeze(Y_c))
  108. plt.contour(xx, yy, probs, levels=[.5])
  109. plt.show()

分别画出有无正则化的图

  

右图加入了正则化,显然正则化模型的拟合曲线平滑,泛化能力强一点。

留下待解决问题,更改正则化参数,观察拟合变化?   

本人初学者,有任何错误欢迎指出,谢谢。

Tensorflow学习:(三)神经网络优化的更多相关文章

  1. TensorFlow学习笔记(二)深层神经网络

    一.深度学习与深层神经网络 深层神经网络是实现“多层非线性变换”的一种方法. 深层神经网络有两个非常重要的特性:深层和非线性. 1.1线性模型的局限性 线性模型:y =wx+b 线性模型的最大特点就是 ...

  2. tensorflow学习笔记——常见概念的整理

    TensorFlow的名字中已经说明了它最重要的两个概念——Tensor和Flow.Tensor就是张量,张量这个概念在数学或者物理学中可以有不同的解释,但是这里我们不强调它本身的含义.在Tensor ...

  3. TensorFlow学习笔记——深层神经网络的整理

    维基百科对深度学习的精确定义为“一类通过多层非线性变换对高复杂性数据建模算法的合集”.因为深层神经网络是实现“多层非线性变换”最常用的一种方法,所以在实际中可以认为深度学习就是深度神经网络的代名词.从 ...

  4. tensorflow学习笔记——使用TensorFlow操作MNIST数据(2)

    tensorflow学习笔记——使用TensorFlow操作MNIST数据(1) 一:神经网络知识点整理 1.1,多层:使用多层权重,例如多层全连接方式 以下定义了三个隐藏层的全连接方式的神经网络样例 ...

  5. tensorflow学习笔记——图像识别与卷积神经网络

    无论是之前学习的MNIST数据集还是Cifar数据集,相比真实环境下的图像识别问题,有两个最大的问题,一是现实生活中的图片分辨率要远高于32*32,而且图像的分辨率也不会是固定的.二是现实生活中的物体 ...

  6. tensorflow学习笔记——自编码器及多层感知器

    1,自编码器简介 传统机器学习任务很大程度上依赖于好的特征工程,比如对数值型,日期时间型,种类型等特征的提取.特征工程往往是非常耗时耗力的,在图像,语音和视频中提取到有效的特征就更难了,工程师必须在这 ...

  7. tensorflow学习笔记——使用TensorFlow操作MNIST数据(1)

    续集请点击我:tensorflow学习笔记——使用TensorFlow操作MNIST数据(2) 本节开始学习使用tensorflow教程,当然从最简单的MNIST开始.这怎么说呢,就好比编程入门有He ...

  8. 【零基础】神经网络优化之Adam

    一.序言 Adam是神经网络优化的另一种方法,有点类似上一篇中的“动量梯度下降”,实际上是先提出了RMSprop(类似动量梯度下降的优化算法),而后结合RMSprop和动量梯度下降整出了Adam,所以 ...

  9. TensorFlow学习笔记10-卷积网络

    卷积网络 卷积神经网络(Convolutional Neural Network,CNN)专门处理具有类似网格结构的数据的神经网络.如: 时间序列数据(在时间轴上有规律地采样形成的一维网格): 图像数 ...

随机推荐

  1. Nginx+tomcat 负载均衡

      一.系统版本 Nginx使用版本.tomcat使用版本: Nginx:nginx-1.10.2.tar.gz Java :Java version: 1.8.0_60, vendor: Oracl ...

  2. SharePoint 项目的死法(二)

    说实话, 做SharePoint项目或者任何信息化项目并不是个容易的事情, 但成功的IT项目对于一个企业来说也许意味着很多, 从我的观察来看, 大部分的成功的信息化项目给企业所带来的回报都远远超过其所 ...

  3. asp.net 练习 js 调用webservice

    using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...

  4. Shader 学习工具篇 可视化公式工具ZGrapher

    大家好,我是怒风,本篇介绍公式可视化公式工具ZGrapher,尝试通过可视化的方式分析一下Shader中应用的公式,以求帮助初学者快速理解Shader编程中的一些常用公式 本篇的目的两个, 第一,介绍 ...

  5. POJ 1185 炮兵阵地 (状态压缩DP)

    题目链接 Description 司令部的将军们打算在NM的网格地图上部署他们的炮兵部队.一个NM的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用& ...

  6. package.json安装依赖的箭头?

  7. Java并发编程(2) AbstractQueuedSynchronizer的内部结构

    一 前言 虽然已经有很多前辈已经分析过AbstractQueuedSynchronizer(简称AQS,也叫队列同步器)类,但是感觉那些点始终是别人的,看一遍甚至几遍终不会印象深刻.所以还是记录下来印 ...

  8. JavaScript中函数参数的值传递和引用传递

    结论: 对于数字.字符串等基本类型变量,是将它们的值传递给了函数参数,函数参数的改变不会影响函数外部的变量. 对于数组和对象等是将对象(数组)的变量的值传递给了函数参数,这个变量保存的指向对象(数组) ...

  9. 如何调整Linux内核启动中的驱动初始化顺序-驱动加载优先级

    Linux内核为不同驱动的加载顺序对应不同的优先级,定义了一些宏: include\linux\init.h #define pure_initcall(fn) __define_initcall(& ...

  10. Linux学习笔记-Linux系统简介

    Linux学习笔记-Linux系统简介 UNIX与Linux发展史 UNIX是父亲,Linux是儿子. UNIX发行版本 操作系统 公司 硬件平台 AIX IBM PowerPC HP-UX HP P ...