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

## 梯度下降

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

### 战斗开始

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
y = x**2+3 # feedforward
if step % 20 == 19: # print min
print ('step {}: x = {}, f(x) = {}'.format(step, x.numpy(), y.numpy()))


with tf.GradientTape() as tape: # gradient
y = x**2+3 # feedforward


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

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

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
y = himmelblau(x) # feedforward
if step % 20 == 19: # print min
print ('step {}: x = {}, f(x) = {}'.format(step, x.numpy(), y.numpy()))



### 终极挑战——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: # 默认只算一次梯度
out = tf.sigmoid((x@w1+b1))@w2 # feedforward
loss = tf.reduce_sum(tf.square(out - y))  # 计算每个样本的MSE
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()


• 五个点拟合sin函数
在不对代码做任何改进的情况下，直接用五个点进行拟合，我们得到的结果非常的糟糕：

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

## 小结

• 1
点赞
• 3
收藏
觉得还不错? 一键收藏
• 0
评论
12-11 1458
03-03 1394
07-05 957
09-10
04-16 776
09-07 624
04-02 282
09-27 823
10-01 60
02-11 1232
02-20 1040
03-28 7215

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

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助

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