# -*- coding: utf-8 -*-
"""
Created on Wed Mar 15 09:55:33 2023
@author: Shawn.Li
"""
import tensorflow as tf
# 创建一个张量,然后将张量转换为变量
# 因为张量是不可改变的,每次对张量的赋值计算就是对张量进行一次复制粘贴
# 要在原内存位置对张量数值进行修改,需要先将张量转换为变量
x = tf.range(4,dtype=tf.float32)
print(x)
x = tf.Variable(x)
print(x)
# 计算 y = x^T · x , 记录计算过程
# tensordot 是向量点乘,向量按元素相乘然后求和
# 与列向量转置再乘以列向量自身等价
# https://tensorflow.google.cn/api_docs/python/tf/gradients?hl=en
# 如果没有 persistent = True ,那么求导一次后T就会消解
# 带有这个标志位的要在计算的最后手动消解 T
with tf.GradientTape(persistent = True) as T:
y_dot = tf.tensordot(x,x,axes = 1)
y_mul = x*x
print(y_dot)
print(y_mul)
# 根据记录的计算过程,反向传播计算梯度
# 当计算链很长的时候,就应该特别关注梯度消失和梯度爆炸的问题,在循环网络中容易碰到
# 截断步长 和 正则化 都是可行的解决办法
y_dot_grad = T.gradient(y_dot,x)
print(y_dot_grad)
y_mul_grad = T.gradient(y_mul,x)
print(y_mul_grad)
del T
# 分离计算
# 把中间函数U当成一个常量计算,而不是一个关于x的变量
# 在记录计算过程时候,需要中断关于U的反向传播,把U当成是一个常量
print("分离计算")
with tf.GradientTape(persistent = True) as T:
y = x*x
u = tf.stop_gradient(y)
z = u * x
z_grad = T.gradient(z,x)
print(u)
print(z_grad)
del T
print("控制流的梯度计算")
def f(a):
b = 100*a
while tf.norm(b) < 1000:
b = 2*b
if tf.reduce_sum(b) > 0:
c = b
else:
c = 3* b
return c
a = tf.Variable(tf.random.normal(shape = ()))
with tf.GradientTape() as T:
d = f(a)
d_grad = T.gradient(d,a)
print(d_grad)
print(d/a)
tensorflow 自动微分
最新推荐文章于 2024-01-28 14:25:26 发布