# 自动求导

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

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

``````import torch

# 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)")

# 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.

``````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 = []
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)
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()

print(a)

b = f(a)

b.backward()

q5：

y = torch.sin(x)

y.sum().backward()

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

[3x1²，3x2²，3x3²]，而不是9x**2

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

x = np.linspace(-3*np.pi, 3*np.pi, 100)

1 Like

%matplotlib inline
import numpy as np
from matplotlib_inline import backend_inline
from d2l import torch as d2l
from matplotlib import pyplot as plt

def use_svg_display(): #@save
“”“使用svg格式在Jupyter中显示绘图”“”
backend_inline.set_matplotlib_formats(‘svg’)

def set_figsize(figsize=(3.5, 2.5)): #@save
“”“设置matplotlib的图表大小”“”
use_svg_display()
d2l.plt.rcParams[‘figure.figsize’] = figsize

#@save
def set_axes(axes, xlabel, ylabel, xlim, ylim, xscale, yscale, legend):
“”“设置matplotlib的轴”“”
axes.set_xlabel(xlabel)
axes.set_ylabel(ylabel)
axes.set_xscale(xscale)
axes.set_yscale(yscale)
axes.set_xlim(xlim)
axes.set_ylim(ylim)
if legend:
axes.legend(legend)
axes.grid()

#@save
def plot(X, Y=None, xlabel=None, ylabel=None, legend=None, xlim=None,
ylim=None, xscale=‘linear’, yscale=‘linear’,
fmts=(‘-’, ‘m–’, ‘g-.’, ‘r:’), figsize=(3.5, 2.5), axes=None):
“”“绘制数据点”“”
if legend is None:
legend =

``````set_figsize(figsize)
axes = axes if axes else d2l.plt.gca()

# 如果X有一个轴，输出True
def has_one_axis(X):
return (hasattr(X, "ndim") and X.ndim == 1 or isinstance(X, list)
and not hasattr(X[0], "__len__"))

if has_one_axis(X):
X = [X]
if Y is None:
X, Y = [[]] * len(X), X
elif has_one_axis(Y):
Y = [Y]
if len(X) != len(Y):
X = X * len(Y)
axes.cla()
for x, y, fmt in zip(X, Y, fmts):
if len(x):
axes.plot(x, y, fmt)
else:
axes.plot(y, fmt)
set_axes(axes, xlabel, ylabel, xlim, ylim, xscale, yscale, legend)
``````

def function(x):
return np.sin(x)

def derivative(func, x):
h = 1e-7
return (func(x + h) - func(x - h)) / (2 * h)

x = np.arange(-5, 5, 0.001)
y = function(x)

y_derivative = derivative(function, x)

plot(x, [function(x), np.cos(x)], ‘x’, ‘f(x)’, legend=[‘f(x)’, ‘Tangent line (x=1)’])

import torch
import d2l

x = torch.arange(-10, 10, 0.05, requires_grad=True)
y = torch.sin(x)
y.backward(torch.ones_like(y))
d2l.torch.plot(x.detach(), [y.detach(), y_d],
‘x’, ‘f(x)’, legend=[‘f(x)=sin(x)’, “f’(x)=cos(x)”],figsize=[5,5])

from d2l import torch as d2l

from math import sin

x = torch.arange(-5, 5, 0.1)