读写文件
加载和保存张量
123456789import torchfrom torch import nnfrom torch.nn import functional as Fx = torch.arange(4)torch.save(x, 'x-file')x2 = torch.load('x-file')x2
1tensor([0, 1, 2, 3])
可以存储一个张量列表,然后把它们读回内存:
1234y = torch.zeros(4)torch.save([x, y], 'x-files')x2, y2 = torch.load('x-files')(x2, y2)
1(tensor([0, 1, 2, 3]), tensor([0., 0., 0., 0.]))
可以写入或读取从字符串映射到张量的字典:
1234mydict = {'x': x, 'y': y}torch.save(mydict, 'mydict')my ...
自定义层
不带参数的层
CenteredLayer类要从其输入中减去均值,要构建它只需继承基础层类并实现前向传播功能。
12345678910111213import torchimport torch.nn.functional as Ffrom torch import nnclass CenteredLayer(nn.Module): def __init__(self): super().__init__() def forward(self, X): return X - X.mean()layer = CenteredLayer()layer(torch.FloatTensor([1, 2, 3, 4, 5]))
1tensor([-2., -1., 0., 1., 2.])
可以将层作为组件合并到构建更复杂的模型中:
1234net = nn.Sequential(nn.Linear(8, 128), CenteredLayer())Y = net(torch.rand(4, 8))Y.mean()
1tensor(3.2596e-09, grad_fn ...
参数管理
首先关注具有单隐藏层的多层感知机:
123456import torchfrom torch import nnnet = nn.Sequential(nn.Linear(4, 8), nn.ReLU(), nn.Linear(8, 1))X = torch.rand(size=(2, 4))net(X)
12tensor([[0.2631], [0.2516]], grad_fn=<AddmmBackward>)
参数访问
从已有模型中访问参数。 当通过Sequential类定义模型时, 可以通过索引来访问模型的任意层。如下所示可以检查第二个全连接层的参数:
1print(net[2].state_dict())
1OrderedDict([('weight', tensor([[ 0.2981, -0.1294, -0.3337, -0.1456, -0.0394, -0.1074, -0.1130, -0.0029]])), ('bias', tensor([0.3518]))])
参数名称允许唯一标识每个参数 ...
层和块
回顾多层感知机
12345678import torchfrom torch import nnfrom torch.nn import functional as Fnet = nn.Sequential(nn.Linear(20, 256), nn.ReLU(), nn.Linear(256, 10))X = torch.rand(2, 20)net(X)
1234tensor([[ 0.0074, 0.2389, -0.0171, -0.0982, 0.0142, 0.0451, 0.0927, 0.0901, 0.1494, -0.0729], [-0.0737, 0.2144, -0.0660, -0.0879, -0.0225, -0.0036, 0.1327, 0.0922, 0.2136, -0.0358]], grad_fn=<AddmmBackward>)
nn.Sequential定义了一种特殊的Module
自定义块
MLP类继承了表示块的类,实现只需要提供自己的构造函数( ...
模型初始化和激活函数
让训练更加稳定
目标:让梯度值在合理的范围内,比如 [1×10−6,1×103][1\times10^{-6},1\times10^3][1×10−6,1×103]
常用方法:
将乘法变成加法(ResNet、LSTM)
归一化(梯度归一化、梯度裁剪)
合理的权重初始和激活函数
让每层的方差是一个常数
将每层的输出和梯度都看作随机变量,让它们的均值和方差都保持一致
正向:
E[hit]=0Var[hit]=a∀i,t\mathbb{E}\left[h_{i}^{t}\right]=0\quad\operatorname{Var}\left[h_{i}^{t}\right]=a\quad \forall i, t
E[hit]=0Var[hit]=a∀i,t
反向:
E[∂ℓ∂hit]=0Var[∂ℓ∂hit]=b∀i,t\mathbb{E}\left[\frac{\partial \ell}{\partial h_{i}^{t}}\right]=0 \quad \operatorname{Var}\left[\frac{\partial \ell}{\partial ...
数值稳定性
神经网络的梯度
考虑有如下 ddd 层的神经网络
ht=ft(ht−1) and y=ℓ∘fd∘…∘f1(x)\mathbf{h}^{t}=f_{t}\left(\mathbf{h}^{t-1}\right) \quad \text { and } \quad y=\ell \circ f_{d} \circ \ldots \circ f_{1}(\mathbf{x})
ht=ft(ht−1) and y=ℓ∘fd∘…∘f1(x)
计算损失 ℓ\ellℓ 关于参数 Wt\mathbf{W}^{t}Wt 的梯度
∂ℓ∂Wt=∂ℓ∂hd∂hd∂hd−1…∂ht+1∂ht∂ht∂Wt\frac{\partial \ell}{\partial \mathbf{W}^{t}}=\frac{\partial \ell}{\partial \mathbf{h}^{d}} \frac{\partial \mathbf{h}^{d}}{\partial \mathbf{h}^{d-1}} \ldots \frac{\partial \mathbf{h}^{t+1}}{\partial \math ...
Dropout
动机
一个好的模型需要对输入数据的扰动鲁棒
使用有噪音的数据相等价于 Tikhonov 正则
Dropout:在层之间加入噪音
无偏差的加入噪音
对 x\mathbf{x}x 加入噪音得到 x′\mathbf{x}^{\prime}x′,希望 E[x′]=x\mathbf{E}\left[\mathbf{x}^{\prime}\right]=\mathbf{x}E[x′]=x
Dropout 对每个元素进行如下扰动:
xi′={0 with probablity pxi1−p otherise x_{i}^{\prime}= \begin{cases}0 & \text { with probablity } p \\ \frac{x_{i}}{1-p} & \text { otherise }\end{cases}
xi′={01−pxi with probablity p otherise
E[xi′]=0⋅p+xi1−p⋅(1−p)=xi\mathbf{E}\left[\mathbf{x}_{i}^{\prime}\right]=0\cdot p+ ...
权重衰退
使用均方范数作为硬性限制
通过限制参数值的选择范围来控制模型容量
minℓ(w,b) subject to ∥w∥2≤θ\min \ell(\mathbf{w}, b) \text { subject to }\|\mathbf{w}\|^{2} \leq \theta
minℓ(w,b) subject to ∥w∥2≤θ
通常不限制偏移 bbb(限不限制都差不多)
小的 θ\thetaθ 意味着更强的正则项
使用均方范数作为柔性限制
对每个 θ\thetaθ 都可以找到 λ\lambdaλ 使得目标函数等价于:
minℓ(w,b)+λ2∥w∥2\min \ell(\mathbf{w}, b)+\frac{\lambda}{2}\|\mathbf{w}\|^{2}
minℓ(w,b)+2λ∥w∥2
可以通过拉格朗日乘子来证明
超参数 λ\lambdaλ 控制了正则项的重要程度,λ=0\lambda=0λ=0 无作用,λ→∞,w∗→0\lambda\rarr\infin,\mathbf{w}^*\rarr0λ→∞,w∗→0
参数更新法则
计算梯度:
∂∂w(ℓ(w,b)+ ...
写在2022年寒假开头
今天是 2022 年 1 月 16 日,昨天白天刚从杭州回到了天津,所以今天算是寒假正式开始的第一天。
大三上学期终于结束,所有课的成绩还没有完全出,但已出的成绩都还不错。
剩下没出的四门里面,操作系统和计算机网络是最重要的也是这个学期花费精力最多的课,平时学的比较认真,考试考的也还可以,所以最后的总评应该会不错。Java 应用技术这门平时就学的没那么认真了,最后的考试考的也不太好,所以总评应该不高。软件工程管理这门课我是组长,我们组最后项目的完成度也算高,应该也会有不错的成绩。大三上这个学期一共选了 32.5 学分,是前五个学期以来最高的,整个学期结束之后也有点如释重负的感觉,因为下学期就已经没什么课了。下学期大家都开始自谋出路了吧,工作、出国、考研、保研……
这个学期其实过的比较混乱,生活作息很不健康,学期中其实就有了从寒假开始好好管理自己的生活的念头,昨天回到家之后又听老妈讲了瞒了我很久的家中变故,老爸的身体情况不容乐观,我在对未来感到迷茫的同时也更坚定了管理好自己的生活的决心。于是今天花了一些时间用 Notion 做了一张个人觉得还比较好看的寒假计划表。
目前还只是 ...
External Sorting
Introduction
Quicksort on a disk is not simple
To get a[i] on internal memory — O(1)O(1)O(1)
To get a[i] on hard disk — device-dependent
find the track
find the sector
find a[i] and transmit
If only one tape drive is available to perform the external sorting, then the tape access time for any algorithm will be Ω(N2)\Omega(N^2)Ω(N2)
Tool: Mergesort
To simplify
Store data on tapes (can only be accessed sequentially)
Can use at least 3 tape drives
Q: Given 10,000,000 records of 128 bytes ...