线性回归的从零开始实现

假如y_hat.shape为[2,1]而y.shape为[1,2],那么由于广播机制,y_hat - y 的shape是[2,2],这样就导致loss的值算的不正确。

因为规则导致去执行广播而不是报错,会导致很难发现这个错误,使用reshape是非常推荐的做法。

def squared_loss(y,y_hat):
return (y - y_hat) ** 2 / 2

def squared_loss(y,y_hat):
return (y.reshape(y_hat.shape) - y_hat) ** 2 / 2
的结果大相径庭 这是为什么

找到问题所在了
def squared_loss(y,y_hat):
#这里必须要要将y reshape一下 因为他是一个向量e.g. Size[10] 而y_hat是一个矩阵 e.g.Size[10,1] 如果缺少了这个操作 pytorch的广播机制会将其结果变成Size[10,10] 一定要小心!!!
return (y.reshape(y_hat.shape) - y_hat) ** 2 / 2

这里面传的参数是 ’列表‘ 而不是 ‘普通的变量’ 传递列表的时候就相当于别的语言的数组,你在函数内对传过来的数组操做同样改变了原数组的值,一个道理。如果传过来的是int型就改变不了了 因为传递的不是引用 而是copy

我认为“reshape()把梯度grad也带上一起reshape了”是不正确的。

我做了以下实验:

"""
注意看下面的代码,原size是[2,1], 仍reshape为[2,1]
如果你的说法是正确的,即reshape会涉及到w.grad的shape,那么此时w.grad的shape也不会改变
但是训练过程中会报相同的错误
"""
w = torch.zeros((2,1), requires_grad=True).reshape(2,1)

"""
注意看下面的代码,我们在reshape操作之后再进行requires_grad属性的设置
这样,在训练过程中不会报错
我们再回看上面一段代码,reshape操作是在requires_grad设置为True之后
所以一个合理的推测是,requires_grad设置为True之后,对w变量的很多操作都会被跟踪,
并建立起计算图。所以上面一段代码中的reshape操作被跟踪,对w的梯度产生了影响,而下面的就不会
"""
w = torch.zeros((1, 2)).reshape(2,1) # w的正确的size是[2,1]
w.requires_grad_(True)

大哥,params是函数参数啊,全局环境里的params是作为参数传递到函数里的。你说的函数内能直接访问外部环境变量是闭包,这是两码事

這個是為了不要累積到梯度吧,每次更新完都要清空一次

执行d2l.set_figsize()时报错
AttributeError: module ‘d2l’ has no attribute ‘set_figsize’
这是什么原因呢?

你没有在当前代码定义这个函数,不过这个函数在d2l里定义了,所以你可以.synthetic_data调用

你好,我在gitHub仓库中找到了关于本书习题的答案,希望这对你有所帮助
仓库链接:GitHub - datawhalechina/d2l-ai-solutions-manual: 《动手学深度学习》习题解答,在线阅读地址如下:

感谢,十分有帮助,找了好久, :grinning: :grinning: :grinning:

1. 如果我们将权重初始化为零,会发生什么。算法仍然有效吗?
w,b如果全是0,那么由于w*x+b恒为0。算法失效。
2. 假设试图为电压和电流的关系建立一个模型。自动微分可以用来学习模型的参数吗?
可以,简单的电路其实是常微分方程。其方程可以线性相加。
3. 能基于普朗克定律48使用光谱能量密度来确定物体的温度吗?
不懂
4. 计算二阶导数时可能会遇到什么问题?这些问题可以如何解决?
由于需要保存中间的梯度,可能会消耗大量资源,然后需要更多算力?不懂
5.为什么在squared_loss函数中需要使用reshape函数?
以书中例子为例,一个是(2,1)而另一个是(2,),维度不一样不能计算。
6. 尝试使用不同的学习率,观察损失函数值下降的快慢。
大致试了试0.001和1,如果太小(0.001)就下降的过慢,如果是1则会振荡。
7. 如果样本个数不能被批量大小整除,data_iter函数的行为会有什么变化?
会一直按batchsize去划分,但最终剩余样本不够分的时候会将这些作为一个batch