一、 第一章 深度学习和pytorch库简介
1、 深度学习是近似复杂的、非线性的过程。
2、 机器学习:依赖特征工程;深度学习:自动寻找表征
3、 张量:它是一个多维数组
4、 Pytorch的2个核心:
(1) 提供了张量以及torch模块提供的库
(2) 张量可以跟踪对其执行操作的能力,以及计算导数
5、 pytorch核心模块位于torch.nn中
二、 第二章 预训练模型
1、 预定义模型位于:torchvision.models
三、 第三章 从张量开始
1、中间表征序列:深度神经网络在不同阶段学习将数据从一种形式转换成另一种形式,这意味着每个阶段转换的数据可以被认为是一个中间表征序列。它是将输入与前一层神经元的权重结合的结果。
2、 python数组/numpy数组/pytorch张量在存储上的区别:
(1) python数组是非连续内存
(2) numpy数组和pytorch张量是连续内存
3、 神经网络计算数据的类型:32位浮点数
4、 张量的默认数据类型:32位浮点数
5、 Transpose()和permute()的区别:
(1) transpose()是2个维度之间进行交换
(2) permute()可以是多个维度之间进行交换
6、 张量的存储视图:张量中的值被分配到由torch.Storage实例所管理的连续内存中,该存储区是一维数组。一个pytorch的tensor实例是一个Storage实例的视图,该实例根据偏移量和每个维度的步长对该存储区进行索引。
7、 就地修改存储值:操作名称以下划线结尾,该操作改变了源张量。任何不带下划线的方法都不会改变源张量,而是返回一个新的张量。
8、 转置:不会分配新的内存,只是创建一个新的Tensor实例,该实例具有与原始张量不同的步长顺序。
9、 连续张量:在pytorch中一些张量操作只对连续张量起作用,比如view()操作,这时可以通过contiguous()使连续。
10、 numpy和张量互操作性:他们的存储共享相同的底层缓冲区。
四、 第四章 使用张量表征真实数据
1、 连续值、序数值和分类值:
(1) 连续值:数字表示,严格排序,不同值之间的差异具有严格的意义。
(2) 序数值:严格排序,但值之间的固定关系不再适用
(3) 分类值:排序无意义,只是枚举值
五、 第五章 学习的机制
1、 损失函数:一种对训练样本中要修正的错误进行优先处理的方法,因此参数更新会导致对高权重样本的输出进行调整,而不是对损失较小的其他样本的输出进行调整。
2、 梯度下降:计算各参数的损失变化率,并在减小损失变化率的方向上修改各参数。
3、 链式法则:先计算损失对于其输入(模型的输出)的导数,再乘模型对参数的导数。
4、 Grad属性:requires_grad=True参数,这个参数告诉pytorch跟踪对params进行操作后产生的张量的整个系谱树,任何将params作为祖先的张量都可以访问从params到那个张量调用的函数链。
5、 累加梯度函数:backward()操作将导致导数在grad属性(叶节点上)累加。
6、 训练的基本步骤以及演进示例:
(1) 基本步骤:
构建模型
计算损失
根据损失反向计算梯度
根据梯度更新参数
(2) 演进之原始算法
Def model(t_u, w, b):
Return w * t_u + b
W, b = params
T_p = model(t_u, w, b)
Loss = loss_fn(t_p, t_c)
Grad = grad_fn(t_u, t_c, t_p, w, b)
Params -= learning_rate * grad
(3) 演进之grad属性
If params.grad is not None:
Params.grad.zero_()
T_p = model(t_u, *params)
Loss = loss_fn(t_p, t_c)
Loss.backward()
With torch.no_grad():
Params -= learning_rate * params.grad
(4) 演进之梯度下降优化器
Optimizer = optim.SGD([params], lr=learning_rate)
T_p = model(t_u, *params)
Loss = loss_fn(t_p, t_c)
Loss.backward()
Optimizer.step()
7、 训练损失无减小的原因:
(1) 模型有问题,模型可能过于简单
(2) 数据有问题,数据可能没有有意义的信息
六、 第六章 使用神经网络拟合数据
1、 神经网络与线性模型最大差异:非线性的激活函数
2、 激活函数的作用:
(1) 非线性操作,允许输出函数在不同的值上有不同的斜率,这是线性函数无法做到的。
(2) 在网络的最后一层,它的作用是将前面的线性运算的输出集中到给定的范围内
3、 激活函数的特性:
(1) 激活函数是非线性的。在没有激活函数的情况下,重复应用(w * x + b)会导致相同仿射线性的函数。非线性使得整个网络能够逼近更复杂的函数。
(2) 激活函数是可微的,因此可以通过它计算梯度。
(3) 至少有一个敏感范围,对输入的变化会导致输出产生相应的变化。
(4) 包含许多不敏感(饱和)的范围,即输入的变化导致输出的变化很小或没有变化。
4、 使用__call__()而不是forward():
直接使用forward()会有很多hook不能被正确调用。
七、 第七章 从图像学习
1、 tramforms.Compose()与nn.Sequential区别:
前者连接变换,后者连接模型
2、 Dataset类:torch.utils.data.Dataset加载数据集,需要重写__len__()和__getitem__()函数。
3、 DataLoader类:torch.utils.data.DataLoader,从数据集中采样小批量
八、 第八章 使用卷积进行泛化
1、 线性模型的不足:将二维图像当作一维来处理,一个输出特征=所有像素 * 一组特征权重的加权和,无法解决局部性问题,即我们希望计算一个像素与其相邻像素的加权和,而不是与图像中其他像素的加权和。此外,没有一个自然的方法来整合全连接层的平移不变性。
2、 卷积的作用:局部性,平移不变性。体现在核函数上,移动时保持不变(平移不变),小矩阵(局部的)。
3、 卷积核:把一个多通道图像转换成另一个多通道图像,其中不同的通道对应不同的特征,例如一个通道代表平均值,一个通道代表垂直边缘。
4、 深度和池化:
(1) 目的:网络如何设置可以看到更大范围的图像,比如有些对象需要横跨几个像素
(2) 方法一:使用大的卷积核,缺点是很大的卷积会收敛到旧的全连接层(没有局部性),仿射变化失去了卷积所有优良性质。
(3) 方法二:在一个卷积之后堆叠另一个卷积,同时在连续卷积之间对图像进行下采样,这样就可以包含尽量多的像素信息。
5、 最大池化好处:在检测到某些特征时,往往具有很高的幅值。我们确保所发现的特征在下采样之后仍然存在,而以较弱的响应为代价。
6、 保存模型:
Torch.save():只保存权重,不保存模型结构,使用时需要重新加载模型定义。
7、 参数权重惩罚:正则化。它是为了减小模型本身的权重,从而限制训练对它们增长的影响。换句话说,这是对较大权重的惩罚。这使得损失更平滑,并且从拟合单个样本中获得的收益相对较少。
8、 不太依赖于单一输入:dropout。将网络每轮训练迭代中的神经元随机部分清零,使得模型中的神经元在过拟合过程中协调记忆过程的机会更少。位置:下一个线性或卷积模块之前。
9、 保持激活检查:批量归一化。将输入重新调整到网络的激活状态,从而使小批量具有一定的理想分布。位置:激活函数之前。
九、 其他
1、 detach():返回一个新tensor,从当前计算图中分离出来,但是仍然指向原变量的存放位置,不同之处使require_grad为false。
2、 pytorch两种模式:
(1) model.train():启用BN和Dropout,保证BN层能够用到每一批均值和方差
(2) model.eval():不启用BN和Dropout.
3、 过拟合的表现:模型在训练集上表现很好,而在验证集上表现很差。训练模型的目标是教它识别我们感兴趣的类的一般特性。当模型开始学习训练集的特定属性时,会发生过拟合,模型开始失去泛化能力。