tensorflow2实现梯度下降

梯度下降(手写代码实现)参见:
https://www.malaoshi.top/show_1EF4G05NJ24L.html

概述

tensorflow2中,通过 tf.GradientTape() 实现自动微分求导,通过tf.keras.optimizers包下的优化器实现梯度下降

所以,使用tensorflow2实现梯度下降,非常简单

代码

导入模块

import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np

实现损失函数

由于损失函数较为复杂,为了便于理解,这里定义一个简单的函数,模拟损失函数

# 损失函数
def loss_fun(x):
    return (x-50)**2

绘制损失函数图像

x_arr=np.linspace(0,100,101)
y_arr=loss_fun(x_arr)

x_arr,y_arr

plt.plot(x_arr,y_arr)

执行如下图:

定义一个初始点

该点在函数图像上任意取一点即可

# 定义一个初始点
init_x = tf.constant(3.0)
init_y=loss_fun(init_x)
init_x,init_y

绘制函数图像和初始点

plt.plot(x_arr,y_arr)
plt.scatter(init_x.numpy(),init_y.numpy())

执行如下:

实现求导函数

tensorflow2通过 tf.GradientTape() 实现自动微分求导

def grads(x):
    with tf.GradientTape() as tape:
#         tape.watch(x)
        result=loss_fun(x)
    #由于sources是list类型,所以gradients也是list类型
    gradients=tape.gradient(target=result,sources=[x])
#     print("cg:%s,x:%s"%(cg,x))
#     print("gradients:",gradients)
    return gradients

注意: 由于tape.gradient()传入[x],所以返回值gradients是list类型

详见:tape.gradient()函数

测试求导函数

x = tf.Variable(3.0)
grads(x)

执行结果:

[<tf.Tensor: id=72, shape=(), dtype=float32, numpy=-94.0>]

运算过程:
函数(x-50)**2的导数是2(x-50),代入x=3,结果为:-94

梯度下降

通过 tf.keras.optimizers.Adam 实现梯度下降


points=[]
adam=tf.keras.optimizers.Adam(1)
temp_x=tf.Variable(init_x)
last_x=tf.Variable(init_x)

for i in range(200):
    last_x.assign(temp_x)
    last_y=loss_fun(last_x)
    points.append((last_x.numpy(),last_y.numpy()))

    g=grads(temp_x)
#     梯度下降,此时temp_x已经修改。
#     由于g是list类型,所以要做zip()处理,转成[(g,v)],详见adam文档
    adam.apply_gradients(zip(g,[temp_x]))
    print("第%s次:::x=%s,last_x=%s,导数=%s"%(i,temp_x.numpy(),last_x.numpy(),g))
    """
    r=loss_fun(temp_x)-last_y
    if abs(r)<0.001:
        print('r:',r)
        break
    """
print("最小值x:",temp_x)
print("最小值y:",loss_fun(temp_x))

绘制历史点图像

points_l=list(zip(*points))
plt.plot(x_arr,y_arr)
# 绘制将历史点
plt.scatter(points_l[0],points_l[1],color='blue')
# 绘制初始点
plt.scatter(init_x.numpy(),init_y.numpy(),color='red')
# 极值点
plt.scatter(temp_x.numpy(),loss_fun(temp_x.numpy()),color='red')

感谢

https://blog.csdn.net/xierhacker/article/details/53174558


原文出处:/show_1EF4grPGjcvs.html