深度学习——TensorFlow的梯度下降实战

在之前的学习中,我们对TensorFlow有了一定的了解,甚至能对其中的一些基本库进行熟练的搭配调用,所以接下来,我们进行梯度下降的实战。

梯度下降

关于梯度下降,我们之前已经学习过了,
有需要可以观看我之前的博客:AI学习——线性回归和梯度下降

关于梯度下降的实战,我们这次主要实现求出两个函数的最小值:

  1. 一元二次函数
  2. 二元四次函数

战斗开始

知己知彼,百战不殆。
在战争开始之前,我们需要了解我们的对手,首先是我们将要面临的第一个敌人——一元二次函数 y = x 2 + 3 y=x^2+3 y=x2+3
我们都是高智商人才,这种简单的式子在我们看来简直就是秒杀题目,我们不难求出,当x等于0时,该一元二次函数取得最小值为3。

虽然我们能够很轻易地直接求出其结果,但作为计算机,似乎并没有那么简单,作为一个简单的计算机,哪怕是再简单的题目,也得按照计算图的流程,通过链式法则来求出所有参数,然后不断迭代,达到最优的结果

关于计算图链式法则的相关知识,可以观看我之前的博客:
AI学习——自动微分算法

  • 求一元二次函数的最小值——代码如下:
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
x = np.arange(-6, 6, 0.1)
y = x**2 + 3
plt.plot(x,y)
plt.show()
x = tf.constant([6.]) # init
for step in range(200):# loop 200 times
    with tf.GradientTape() as tape: # gradient
        tape.watch([x]) # add to gradient list
        y = x**2+3 # feedforward
    grads = tape.gradient(y, [x])[0] 
    x -= 0.01*grads  # lr=0.01
    if step % 20 == 19: # print min
        print ('step {}: x = {}, f(x) = {}'.format(step, x.numpy(), y.numpy()))

在这里插入图片描述
从代码中我们可以看到,其核心就在于这几行:

with tf.GradientTape() as tape: # gradient
        tape.watch([x]) # add to gradient list
        y = x**2+3 # feedforward
    grads = tape.gradient(y, [x])[0] 

短短几行就能实现我们想要达成的梯度下降,tensorflow真的很方便

  • 求二元四次函数的最小值——代码如下:

这是我们今天要求解的第二个问题,求二元四次函数的最小值:
y = ( x 0 2 + x 1 − 11 ) 2 + ( x 0 + x 1 2 − 7 ) 2 y=(x_0^2+x_1-11)^2+(x_0+x_1^2-7)^2 y=(x02+x111)2+(x0+x127)2

import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
def himmelblau(x): # himmelblau 
    return (x[0] ** 2 + x[1] - 11) ** 2 + (x[0] + x[1] ** 2 - 7) ** 2
x = np.arange(-6, 6, 0.1)
y = np.arange(-6, 6, 0.1)
print('x,y range:', x.shape, y.shape)
X, Y = np.meshgrid(x, y) # generate x-y points
print('X,Y maps:', X.shape, Y.shape)
Z = himmelblau([X, Y]) # compute Z
fig = plt.figure('himmelblau')
ax = fig.gca(projection='3d')
ax.plot_surface(X, Y, Z)
ax.view_init(60, -30)
ax.set_xlabel('x')
ax.set_ylabel('y')
plt.show()
x = tf.constant([4., 0.]) # init
for step in range(200):# loop 200 times
    with tf.GradientTape() as tape: # gradient
        tape.watch([x]) # add to gradient list
        y = himmelblau(x) # feedforward
    grads = tape.gradient(y, [x])[0] 
    x -= 0.01*grads  # lr=0.01
    if step % 20 == 19: # print min
        print ('step {}: x = {}, f(x) = {}'.format(step, x.numpy(), y.numpy()))

在这里插入图片描述

终极挑战——sin函数拟合

关于sin函数的拟合,我们已经不是第一次面对了,在以前的学习中,他对我来说就是一座大山,但是如今,我也不是曾经的我了。

import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
x = np.linspace(0, 2*np.pi, 20).reshape((-1,1))
y = tf.Variable(np.sin(x))
x = tf.Variable(x)
w1 = tf.Variable(np.random.random((1,100))*2-1)
b1 = tf.Variable(np.random.random((100,))*2-1)
w2 = tf.Variable(np.random.random((100,1))*2-1)
for step in range(100000):# loop 200 times
    with tf.GradientTape(persistent=True) as tape: # 默认只算一次梯度
        tape.watch([w1,b1,w2]) # add to gradient list
        out = tf.sigmoid((x@w1+b1))@w2 # feedforward
        loss = tf.reduce_sum(tf.square(out - y))  # 计算每个样本的MSE
    grads = tape.gradient(loss, [w1,b1,w2])
    w1 = w1 - 0.01 * grads[0]
    b1 = b1 - 0.01 * grads[1]
    w2 = w2 - 0.01 * grads[2]
    if step % 20 == 19: # print min
        print ('step {}: Loss = {}'.format(step, loss.numpy()))

x_test = np.linspace(0,np.pi*2,100).reshape((-1,1))
x_test = tf.constant(x_test)
y_test = tf.constant(np.sin(x_test))
y_pred = (tf.sigmoid((x_test@w1+b1))@w2).numpy()
plt.plot(x.numpy(),y.numpy(),'*')
plt.plot(x_test,y_test,x_test,y_pred)
plt.show()

在这里插入图片描述
利用tensorflow很轻松地就将其拟合出来了,结果不是非常完美,但作为一个简单的神经网络,能够达到这个效果我觉得是非常不错的了,接下来我们缩小点的个数,争取用更少的点实现sin函数的拟合

  • 五个点拟合sin函数
    在不对代码做任何改进的情况下,直接用五个点进行拟合,我们得到的结果非常的糟糕:
    在这里插入图片描述
    面对这种情况,我们还是有很多办法解决:
  1. 增加训练的迭代次数,有效果但是效果不明显,甚至无法改善
  2. 改变学习率,这一步通常会和改变迭代次数一起进行,同样会有效果,但是很难拟合出我们想要的结果,而且常常效率低下
  3. 增加神经网络的层数,让其复杂化,这是我们之前在研究BPNN算法时使用过的方法,很实用,效果也非常明显
  4. 增加正则化,为我们的损失函数增加一个正则化,让其更加稳定

这次我们选择第四个办法,增加正则化,同时改变我们的学习率,并且增加迭代次数作为辅助,看看是否能够获得我们想要的效果,或者得到一个趋于我们的目标的效果:

在这里插入图片描述

从效果来看,还不错。

小结

关于深度学习的学习,已经开展了两个月了,我们解决了很多当时我们以为无法解决的困难,也翻过了很多我们以为无法翻越的高山,那些以为走不完的路,跨过去后再回头看看,发现也不过如此。
在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值