自动求导

牛的兄弟 ,你说的很清楚 牛的兄弟 ,你说的很清楚

问问为什么x不使用detach函数会报错?

2.5.4中d.backward()应该是d.sum().backward()吧

第5题,不使用d2l封装的函数

import torch

# x.grad.zero_()

# x = torch.rand(2, 4, requires_grad = True)
x = torch.linspace(0, 2 * torch.pi, 100,  requires_grad = True)  # 生成100
y = torch.sin(x)
y.sum().backward()

import numpy as np
import matplotlib.pyplot as plt

from matplotlib_inline import backend_inline

plt.figure(figsize=(8, 8))

plt.plot(x.detach().numpy(), y.detach().numpy(), "-", label="sin(x)")
plt.plot(x.detach().numpy(), x.grad.detach().numpy(), "r--", label="cos(x)")

# x1 = torch.linspace(0, 2 * torch.pi, 200)
# plt.plot(x1.numpy(), torch.zeros_like(x1).numpy(), "--", label="0")

plt.legend(loc='upper left')

# 添加标签和标题
plt.xlabel('X')
plt.ylabel('f(x)')

# 显示图表

plt.show()

I think it’s wrong in some sense.Because of the reshape method does not change the datatype,q still is a tensor.

第5题使用TensorFlow

import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
def f(a):
    c = tf.math.sin(a)
    return c

a_values = tf.range(-10.0, 10.0, 0.1)  

f_values = []
dx_values = []
with tf.GradientTape(persistent=True) as t:
    for a in a_values:
        a_tensor = tf.constant(a, dtype=tf.float32)
        t.watch(a_tensor)
        y = f(a_tensor)
        f_values.append(y)
        dy_dx = t.gradient(y, a_tensor)
        dx_values.append(dy_dx)

plt.plot(a_values, f_values, label='f(x)')
plt.plot(a_values, dx_values, '--',label='f(x)')
plt.xlabel('x')
plt.legend()
plt.grid()
plt.show()

q4:
def f(a):

b = a*2

if a.norm() > 100:

b = a**2

else:

b = a**3

return b.sum()

a = torch.arange(100,104.,requires_grad=True)

print(a)

b = f(a)

b.backward()

a.grad

q5:
x = torch.arange(0,4.,0.1,requires_grad=True)

y = torch.sin(x)

y.sum().backward()

plot(x, [y, x.grad], ‘f(x)’, ‘x’)

(一个粗浅的理解)pytorch不支持对非标量进行backward。sum可以理解为对f(x)增加了一个复合函数,z=sum(y), 而 dz/dy 是一个单位向量或者单位矩阵,这样不影响最终的结果。

这里z=y.sum(),所以z相对于x的导数应该是
[3x1²,3x2²,3x3²],而不是9x**2

pytorch中这种一维的tensor全都看作列向量,所以结果就是一个列向量