d2l自动微分练习

1. 为什么计算二阶导数比一阶导数的开销要更大?

简单来说就是会造成梯度维数的增大,标量对向量的求导是一个向量,在此基础上再对向量求导就会变成一个矩阵,进一步的会变成张量。

2. 在运行反向传播函数之后,立即再次运行它,看看会发生什么。

运行时异常,之前的结果已经被释放,而且给出了提示,说要使用retain_graph=True就能够保证结果不被释放。

RuntimeError: Trying to backward through the graph a second time, but the saved intermediate results have already been freed. Specify retain_graph=True when calling backward the first time.

3. 在控制流的例子中,我们计算d关于a的导数,如果我们将变量a更改为随机向量或矩阵,会发生什么?

RuntimeError: grad can be implicitly created only for scalar outputs
梯度的计算只针对标量,然后如果是向量则先使用sum()然后再进行计算梯度。

4. 重新设计一个求控制流梯度的例子,运行并分析结果。

待讨论。

5. 使 f ( x ) = sin ⁡ ( x ) f(x)=\sin(x) f(x)=sin(x),绘制 f ( x ) f(x) f(x) d f ( x ) d x \frac{df(x)}{dx} dxdf(x)的图像,其中后者不使用 f ′ ( x ) = cos ⁡ ( x ) f'(x)=\cos(x) f(x)=cos(x)

%matplotlib inline
import matplotlib.pylab as plt
from matplotlib.ticker import FuncFormatter, MultipleLocator
import numpy as np

# 让x打满区间,事实上是创建了-3π到3π的100个点
x = np.linspace(-3 * np.pi,3 * np.pi,100)
# 构建一个tensor,存放梯度,存放中间结果
x1= torch.tensor(x, requires_grad=True)
# 定义函数y
y = torch.sin(x1)
y.sum().backward()
x1.grad
# 在此已经得出了x的对应的点的导数值
# 现在开始画出图像
f,ax=plt.subplots(1)
# 画出sin
ax.plot(x,np.sin(x),label="sin()")
# 画出sin的梯度
ax.plot(x,x1.grad,label="gradient of sin(x)")
# 设置标签
ax.legend(loc='upper center', shadow=True)
plt.show()

sin与它的梯度

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Elong_Hu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值