提交 2ae5494b 编写于 作者: W wizardforcel

dl5 done

上级 848e84e0
......@@ -22,7 +22,7 @@
| 第二课 | [咸鱼](https://github.com/Watermelon233) |
| 第三课 | [咸鱼](https://github.com/Watermelon233) |
| 第四课 | |
| 第五课 | |
| 第五课 | [飞龙](https://github.com/wizardforcel) |
| 第六课 | |
| 第七课 | |
| 第八课 | |
......@@ -46,4 +46,5 @@
* dl1.md √
* dl2.md √
* dl3.md √
* dl5.md √
* dl10.md √
......@@ -76,9 +76,9 @@ pd.crosstab(top_r.userId, top_r.movieId, top_r.rating, aggfunc=np.sum)
我们如何处理新用户或新电影 - 我们是否需要重新训练模型? 我们现在没有时间来讨论这个问题,但基本上你需要有一个新的用户模型或最初会使用的新电影模型,随着时间的推移你需要重新训练模型。
### **简单的Python版本[** [**26:03**](https://youtu.be/J99NV9Cr75I%3Ft%3D26m3s) **]**
### 简单的 Python 版本 [[26:03](https://youtu.be/J99NV9Cr75I%3Ft%3D26m3s)]
这应该看起来很熟悉了。 我们通过选择随机ID集来创建验证集。 `wd`是L2正则化的权重衰减, `n_factors`是我们想要的嵌入矩阵有多大。
这应该看起来很熟悉了。 我们通过选择随机 ID 集来创建验证集。 `wd`是 L2 正则化的权重衰减, `n_factors`是我们想要的嵌入矩阵有多大。
```py
val_idxs = get_cv_idxs(len(ratings))
......@@ -86,7 +86,7 @@ wd = 2e-4
n_factors = 50
```
我们从CSV文件创建模型数据对象:
我们从 CSV 文件创建模型数据对象:
```py
cf = CollabFilterDataset.from_csv(path, 'ratings.csv', 'userId', 'movieId', 'rating')
......@@ -100,12 +100,12 @@ learn.fit(1e-2, 2, wds=wd, cycle_len=1, cycle_mult=2)
```
```py
learn.fit(1e-2, 2, wds=wd, cycle_len=1, cycle_mult=2)
learn.fit(1e-2, 2, wds=wd, cycle_len=1, cycle_mult=2)
```
![](../img/1_Xl9If92kjaI5OEIxKyNLiw.png)
输出MSE
输出 MSE
由于输出是均方误差,你可以通过以下方式获取 RMSE:
......@@ -113,7 +113,7 @@ learn.fit(1e-2, 2, wds=wd, cycle_len=1, cycle_mult=2)
math.sqrt(0.765)
```
输出约为0.88,优于0.91的基准。
输出约为 0.88,优于 0.91 的基准。
你可以通过常规方式获得预测:
......@@ -121,7 +121,7 @@ math.sqrt(0.765)
preds = learn.predict()
```
你也可以使用seaborn `sns`(建立在`matplotlib`之上):
你也可以使用 seaborn `sns`(建立在`matplotlib`之上):
```py
y = learn.data.val_y
......@@ -130,7 +130,7 @@ sns.jointplot(preds, y, kind='hex', stat_func=None)
![](../img/1_cXAU8huHFkxKbJjZUwwxIA.png)
### **使用 Python 的点乘**
### 使用 Python 的点乘
![](../img/1_kSUYsjtdLbyn2SqW9cKiHA.jpeg)
......@@ -143,7 +143,7 @@ a = T([[1., 2], [3, 4]])
b = T([[2., 2], [10, 10]])
```
当我们在numpy或PyTorch中的张量之间有一个数学运算符时,它将逐元素运算,假设它们都具有相同的维数。 下面是你如何计算两个向量的点积(例如`(1,2)·(2,2)= 6` - 矩阵`a``b`的第一行):
当我们在 numpy 或 PyTorch 中的张量之间有一个数学运算符时,它将逐元素运算,假设它们都具有相同的维数。 下面是你如何计算两个向量的点积(例如`(1,2)·(2,2)= 6` - 矩阵`a``b`的第一行):
```py
(a*b).sum(1)
......@@ -155,7 +155,7 @@ b = T([[2., 2], [10, 10]])
'''
```
### 构建我们的第一个自定义层(即 PyTorch 模块)[ [33:55](https://youtu.be/J99NV9Cr75I%3Ft%3D33m55s) ]
### 构建我们的第一个自定义层(即 PyTorch 模块)[[33:55](https://youtu.be/J99NV9Cr75I%3Ft%3D33m55s)]
我们通过创建一个扩展`nn.Module`并覆盖`forward`函数的 Python 类来实现它。
......@@ -177,7 +177,7 @@ model(a,b)
'''
```
### 建造更复杂的模块[ [41:31](https://youtu.be/J99NV9Cr75I%3Ft%3D41m31s) ]
### 建造更复杂的模块 [[41:31](https://youtu.be/J99NV9Cr75I%3Ft%3D41m31s)]
这个实现对`DotProduct`类有两个补充:
......@@ -215,7 +215,7 @@ class EmbeddingDot(nn.Module):
return (u*m).sum(1)
```
请注意, `__init__`是一个现在需要的构造函数,因为我们的类需要跟踪“状态”(多少部电影,多少用户,多少因子等)。 我们将权重初始化为 0 到 0.05 之间的随机数,你可以在这里找到关于权重初始化的标准算法的更多信息,“Kaiming Initialization”(PyTorch 有 He 初始化实用函数,但是我们试图从头开始) [[4658](https://youtu.be/J99NV9Cr75I%3Ft%3D46m58s)] 。
请注意, `__init__`是一个现在需要的构造函数,因为我们的类需要跟踪“状态”(多少部电影,多少用户,多少因子等)。 我们将权重初始化为 0 到 0.05 之间的随机数,你可以在这里找到关于权重初始化的标准算法的更多信息,“Kaiming Initialization”(PyTorch 有 He 初始化实用函数,但是我们试图从头开始) [[46:58](https://youtu.be/J99NV9Cr75I%3Ft%3D46m58s)] 。
`Embedding`不是张量而是**变量** 。 变量执行与张量完全相同的操作,但它也可以自动微分。 要从变量中拉出张量,请调用`data`属性。 所有张量函数都有尾随下划线的变体(例如`uniform_` ),将原地执行。
......@@ -269,7 +269,7 @@ class EmbeddingDotBias(nn.Module):
return res
```
`squeeze`是 PyTorch 版本的广播 [[1:04:11](https://youtu.be/J99NV9Cr75I%3Ft%3D1h4m11s)] 请参阅机器学习课程或[ numpy 文档](https://docs.scipy.org/doc/numpy-1.13.0/user/basics.broadcasting.html),来获取更多信息。
`squeeze`是 PyTorch 版本的广播 [[1:04:11](https://youtu.be/J99NV9Cr75I%3Ft%3D1h4m11s)] 请参阅机器学习课程或[ numpy 文档](https://docs.scipy.org/doc/numpy-1.13.0/user/basics.broadcasting.html),来获取更多信息。
我们可以压缩评级,使其在 1 到 5 之间吗?是!通过 sigmoid 函数进行预测将导致数字位于 1 和 0 之间。因此,在我们的情况下,我们可以将其乘以 4 并加 1 - 这将导致 1 到 5 之间的数字。
......@@ -348,7 +348,7 @@ A Jupyter Widget
* 增加/减少隐藏层数和激活个数
* 增加/减少正则化
### 训练循环中发生了什么? [[1:33:21](https://youtu.be/J99NV9Cr75I%3Ft%3D1h33m21s)]
### 训练循环中发生了什么?[[1:33:21](https://youtu.be/J99NV9Cr75I%3Ft%3D1h33m21s)]
目前,我们正在将权重更新传递给 PyTorch 的优化器。 优化器有什么作用? 什么是`momentum`
......@@ -425,16 +425,16 @@ avg_loss = avg_loss * avg_mom + loss * (1-avg_mom)
### **一些直觉**
* 我们计算了梯度平方的指数加权移动平均值,取其平方根,并将学习率除以它。
* 渐变平方总是积极的。
* 梯度平方总是正的。
* 当梯度的方差很大时,梯度平方将很大。
* 当梯度恒定时,梯度平方将很小。
* 如果渐变变化很大,我们要小心并将学习率除以大数(减速)
* 如果梯度变化很大,我们要小心并将学习率除以大数(减速)
* 如果梯度变化不大,我们将通过将学习率除以较小的数字来采取更大的步骤
* **自适应学习率** - 跟踪梯度平方的平均值,并使用它来调整学习率。 因此,只有一种学习风格,但如果梯度是恒定的,每个时期的每个参数都会得到更大的跳跃; 否则会跳得更小。
* 有两个瞬间 - 一个用于渐变,另一个用于渐变平方(在PyTorch中,它被称为beta,它是两个数字的元组)
* **自适应学习率** - 跟踪梯度平方的平均值,并使用它来调整学习率。 因此,只有一种学习风格,但如果梯度是恒定的,每个迭代的每个参数都会跳跃得更大;否则会跳得更小。
* 有两个参数 - 一个用于梯度,另一个用于梯度平方(在 PyTorch 中,它被称为 beta,它是两个数字的元组)
### AdamW [[2:11:18](https://youtu.be/J99NV9Cr75I%3Ft%3D2h11m18s)]
当参数多于数据点时,正则化变得很重要。 我们以前见过 Dropout ,权重衰退是另一种正则化。 权重衰减(L2正则化)通过将平方权重(权重衰减乘数乘以)加到损失中来惩罚大权重。 现在损失函数想要保持较小的权重,因为增加权重会增加损失; 因此,只有当损失提高超过罚款时才这样做。
当参数多于数据点时,正则化变得很重要。 我们以前见过 Dropout ,权重衰减是另一种正则化。 权重衰减(L2 正则化)通过将权重平方(乘以权重衰减因子)加到损失中来惩罚大权重。 现在损失函数想要保持较小的权重,因为增加权重会增加损失;因此,只有当损失的改善超过惩罚时才这样做。
问题在于,由于我们将平方权重添加到损失函数,这会影响梯度的移动平均值和Adam的平方梯度的移动平均值。 这导致当梯度变化很大时减少权重衰减量,并且当变化很小时增加权重衰减量。 换句话说,“惩罚大权重,除非渐变变化很大”,这不是我们想要的。 AdamW从损失函数中删除了权重衰减,并在更新权重时直接添加它。
问题在于,由于我们将权重平方添加到损失函数,这会影响梯度的移动平均值和 Adam 的梯度平方的移动平均值。 这导致当梯度变化很大时减少权重衰减量,并且当变化很小时增加权重衰减量。 换句话说,“惩罚大权重,如果梯度变化不大”,这不是我们想要的。 AdamW 从损失函数中删除了权重衰减,并在更新权重时直接添加它。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册