Pycharm2019+Tensorflow2.0 学习文档(八):自动微分机制

目录

一、利用梯度磁带求导

二,利用梯度磁带和优化器求最小值


​​​​​​​

参考文献

神经网络2通常依赖反向传播求梯度来更新网络参数,求梯度过程中通常是一件非常复杂而且容易出错的事情。而深度学习框架可以帮助我们自动完成这种求梯度的运算。

Tensorflow 一般使用梯度磁带 tf.GradientTape 来记录正向运算过程,然后反播磁带自动得到梯度值。

这种利用tf.GradientTape求取微分的方法叫做TensorFlow的自动微分机制。

一、利用梯度磁带求导

import tensorflow as tf
import numpy as np

# f(x) = a*x**2 + b*x + c 的导数

x = tf.Variable(0.0, name="x", dtype=tf.float32)
a = tf.constant(1.0)
b = tf.constant(-2.0)
c = tf.constant(1.0)

with tf.GradientTape() as tape:
    y = a * tf.pow(x, 2) + b * x + c

dy_dx = tape.gradient(y, x)
print(dy_dx)

# 对张量也可以求导,需要增加 watch
with tf.GradientTape() as tape:
    tape.watch([a, b, c])
    y = a * tf.pow(x, 2) + b * x + c

dy_dx, dy_da, dy_db, dy_dc = tape.gradient(y, [x, a, b, c])
print(dy_da)
print(dy_dc)
print(dy_db)
print(dy_dx)

# 也可以求二阶导数
with tf.GradientTape() as tape2:
    with tf.GradientTape() as tape1:
        y = a * tf.pow(x, 2) + b * x + c
    dy_dx = tape1.gradient(y, x)
dy2_dx2 = tape2.gradient(dy_dx, x)

print(dy2_dx2)


# 可以在autograph中使用
@tf.function
def f(xx):
    aa = tf.constant(1.0)
    bb = tf.constant(-2.0)
    cc = tf.constant(1.0)

    # 自变量转换成tf.float32
    xx = tf.cast(xx, tf.float32)
    with tf.GradientTape() as tape3:
        tape3.watch(xx)
        yy = aa * tf.pow(xx, 2) + b * xx + c
    dyy_dxx = tape3.gradient(yy, xx)
    return dyy_dxx, yy


tf.print(f(tf.constant(0.0)))
tf.print(f(tf.constant(1.0)))

二,利用梯度磁带和优化器求最小值

# 利用梯度磁带和优化器求最小值
# 求f(x)=a*x**2 + b*x + c 最小值
# optimizer.apply_gradients

x = tf.Variable(0.0, name="x", dtype=tf.float32)
a = tf.constant(1.0)
b = tf.constant(-2.0)
c = tf.constant(1.0)

# SGD 随机梯度下降算法
optimizer = tf.keras.optimizers.SGD(learning_rate=0.01)
for _ in range(1000):
    with tf.GradientTape() as tape:
        y = a * tf.pow(x, 2) + b * x + c
    dy_dx = tape.gradient(y, x)
    optimizer.apply_gradients(grads_and_vars=[(dy_dx,x)])

tf.print("y = ", y, ";, x =", x)

#  使用 optimizer.minimize
#  求f(x)=a*x**2 + b*x + c 最小值
#  optimizer.minimize相当于先用tape求gradient,再 apply_gradient

x = tf.Variable(0.0, name="x", dtype=tf.float32)


# 注意f() 无参数
def f():
    a_my = tf.constant(1.0)
    b_my = tf.constant(-2.0)
    c_my = tf.constant(1.0)
    y_my = a_my * tf.pow(x, 2) + b_my * x + c
    return y_my


optimizer = tf.keras.optimizers.SGD(learning_rate=0.01)
for _ in range(1000):
    optimizer.minimize(f, [x])

tf.print("y = ", y, ";, x =", x)

#  方法3:
#  在 autograph 中
#  求f(x)=a*x**2 + b*x + c 最小值
#  使用 optimizer.apply_gradients

x = tf.Variable(0.0, name="x", dtype=tf.float32)
optimizer = tf.keras.optimizers.SGD(learning_rate=0.01)


@tf.function
def minimizef():
    a_c = tf.constant(1.0)
    b_c = tf.constant(-2.0)
    c_c = tf.constant(1.0)
    # 注意autograph时使用tf.range(1000)而不是range(1000)
    for _ in tf.range(1000):
        with tf.GradientTape() as tape4:
            y_v = a * tf.pow(x, 2) + b * x + c
            dyv_dx = tape4.gradient(y_v, x)
            optimizer.apply_gradients(grads_and_vars=[(dyv_dx, x)])

    y_v = a_c * tf.pow(x, 2) + b * x + c
    return y_v


tf.print(minimizef())
tf.print(x)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值