1 层和块
- 单个神经网络:
- 一个输入
- 标量输出
- 一组相关参数,这些参数可以通过学习而优化
- 层:
- 一组输入
- 一组输出
- 一组可调参数
- 从编程的角度看,块由类来表示。通常需要定义一个将输入转换成输出的forward函数,并且必须存储任何必须的参数。
- 定义一个网络:256个单元和ReLU的全连接隐藏层,10个隐藏单元且不带激活函数的全连接输出层
- nn.Sequential是一种特殊的module,表示一个块,维护了一个由module组成的有序列表
- net(x)相当于net.call(x)
1 | import torch |
tensor([[ 0.0302, -0.1207, -0.0915, 0.0522, -0.3685, 0.0474, 0.0665, -0.0055,
-0.1445, -0.1954],
[ 0.0275, -0.1345, 0.0009, 0.0987, -0.4689, 0.0405, 0.0012, -0.0243,
-0.2954, -0.1414]], grad_fn=<AddmmBackward0>)
1.1 自定义块
- 每个块必须提供的功能:
- 数据输入forward函数得到输出
- 计算输出关于输入的梯度,通过backward函数
- 存储和访问前向传播计算所需要的参数
- 初始化模型参数
1 | class MLP(nn.Module): |
tensor([[ 0.2163, 0.0644, -0.1128, -0.2947, 0.0708, 0.0907, -0.0680, -0.0381,
-0.0843, 0.0921],
[ 0.2196, 0.0087, 0.0257, -0.1403, -0.0191, 0.0435, -0.1980, 0.0350,
0.0158, 0.0848]], grad_fn=<AddmmBackward0>)
1.2 顺序块
- 构建自己简化的Sequential类需要
- 将block逐个追加到列表中
- forward函数中,将输入按顺序传递
1 | class MySequential(nn.Module): |
tensor([[-0.1585, -0.0420, 0.3813, -0.3592, -0.0889, 0.0362, -0.0543, -0.0557,
-0.2022, 0.0183],
[-0.0438, -0.1248, 0.5774, -0.3087, -0.0576, -0.0479, 0.0954, -0.2362,
-0.2333, -0.1394]], grad_fn=<AddmmBackward0>)
1.3 在前向传播函数中执行代码
- 有时我们希望合并既不是上一层的结果也不是可更新参数的项,成为常数参数。
1 | class FixedHiddenMLP(nn.Module): |
tensor(-0.2985, grad_fn=<SumBackward0>)
1.4 效率
我们在一个高性能的深度学习库中进行了大量的字典查找、代码执行和许多其他的Python代码。Python的问题全局解释器锁是众所周知的。在深度学习环境中,我们担心速度极快的GPU可能要等到CPU运行Python代码后才能运行另一个作业。