【资源】
1. 课程主页 2. 教材 - 具体 3. 讨论论坛 4. Pytorch讨论论坛
4. d2l-ai具体课程资源内容 :slides、
【笔记others】
task01:代码函数解释、
【课程学习记录】
02、DL介绍
图片分类(ImageNet)、物体检测与分割(检测:物体是什么?在什么地方;分割:某个像素是属于谁)、样式迁移(piscart里的滤镜类似操作)、人脸合成、文字生产图片、文字生成gpt3、无人驾驶笔记
案例研究:广告点击(触发广告->点击率预估->排序=点击率x竞价)
QA:
关于模型的可解释性(黑盒之痛)、自然语言相对于DL 还有很多需要做
03、安装
1、Pytorch配置:来来回回在不同电脑上安装了好几次Pytorch 一直稀里糊涂 今天终于独立安装成功一次!虽然还没有完全理解 但也将好不容易成功一次的流程记录下来★有效指南√
先设置清华镜像:
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
pip config set install.trusted-host https://pypi.tuna.tsinghua.edu.cn
然后查看pip设置的镜像源,空就是默认设置
pip config list
若成功则显示:
global.index-url=‘https://pypi.tuna.tsinghua.edu.cn/simple’
install.trusted-host=‘https://pypi.tuna.tsinghua.edu.cn’
因为我已经安装了Anaconda所以直接从环境配置开始(都是在Anaconda Prompt下操作的)
①查看anaconda中的python版本:先激活anaconda环境,再查看python版本号(3.8.8)
conda activate
python -V
conda create -n pytorch python=3.8
②进入pytorch环境,查看都有啥
conda activate pytorch
pip list
③进Pytorch官网 选择运行命令(我目前是CPU)
pip3 install torch torchvision torchaudio
④验证是否安装成功(pytorch环境下)
python
import torch
2、d2l安装√、
pip install jupyter d2l torch torchvision
d2l-ai记事本 直接下载压缩包然后解压更方便
3、想进入其他盘(F)进行操作两步
cd /d F:
jupyter notebook
04-05、数据操作/预处理+线代
1、搜罗笔记:数据特征+线代+求导★、
2、矩阵(换个角度 有新认识) eg.特征向量:不被矩阵改变方向的向量
3、张量
张量是DL的数据结构 :神经网络中的输入、输出和变换都是用张量表示的,因此神经网络编程大量使用张量,张量是神经网络使用的主要数据结构. | 张量是多维数组或者简称n维数组。我们之所以说张量是一种统称(generalization),是因为我们对n的所有值都使用张量这个词,就像:标量是0维张量、向量是一维张量、矩阵是二维张量、n维数组是n维张量。张量允许我们去掉这些特定的项,只需使用n来标识我们正在处理的维数。| 关于张量的维数要注意的一点是,它不同于我们在向量空间中引用向量维数时的意思。张量的维数并不能告诉我们张量中有多少分量(components)
张量的阶、轴和形状 ☆:张量的阶rank是指张量中的维数。假设我们有一个二阶张量。这意味着:我们有一个矩阵or我们有一个二维数组or我们有一个二维张量。 | 张量的阶告诉我们访问(引用)张量数据结构中的特定数据元素需要多少个索引。|| 也可以通过观察张量的轴axis来建立阶的概念。| Eg.假设有个张量是一个2阶的张量,这意味着这个张量有2个维度,或者等价于张量有 2 个轴。每个轴的长度告诉我们每个轴上有多少个索引可用…(链接里具体的例子★)…对于张量,最后一个轴的元素总是数字。每隔一个轴将包含n维数组。这就是我们在这个例子中看到的,但是这个思想是通用的。 | 张量的阶告诉我们一个张量有多少轴,这些轴的长度使我们得到一个非常重要的概念,即张量的形状。|| 张量的形状由每个轴的长度决定,所以如果我们知道给定张量的形状,那么我们就知道每个轴的长度,这就告诉我们每个轴上有多少索引可用。| 在PyTorch中,张量的大小和形状是一样的。| 如torch.Size([3,3])张量的形状是3 x 3,说明这个2阶张量的每个轴的长度都是3,这意味着我们有三个沿着每个轴可用的索引。|| 另外,当我们对神经网络进行编程时,我们必须经常执行的一种操作叫做重构reshape.
4、代码运行中的一个报错
那就在定义的时候声明float32
A = torch.arange(20,dtype=torch.float32).reshape(5,4)
5、对按特定轴求和的一个补充★
06-07、矩阵计算(求导)、自动求导
1、梯度
梯度:与等高线正交,且指向变换大的方向
两个向量求导结果是个矩阵
2、自动求导
DL中一般对标量求导而不是对矩阵/向量求导,因为loss是标量
08-线性回归+基础优化算法
笔记:task01、task01、task01、笔记√、笔记2、
1、线性模型
main:买房=>线性模型(单层神经网络)=>衡量预估质量(平方损失)=>训练数据(XY)=>参数学习(训练损失|最小化损失得w*b*)=>显示解
线性模型可以看作是单层神经网络(带权重的只有一层|把输入层和权重放在一起)
有了模型就要开始做预测了 => 衡量预估质量(保留1/2是为了之后运算/求导方便运算)
总结:
(1)线性回归是对n维输入的加权,外加偏差;
(2)使用平方损失来衡量预测值和真实值的偏差;
(3)线性回归有显示界[这堂课只有线性回归有显示解(easy| 但ML for NP complete NP套餐)];
(4)线性回归可以看作是单层神经网络(是最简单的神经网络)
2、基础优化算法
梯度下降=>小批量梯度下降=>
η:学习率,超参数需要人为指定,表示沿着这个方向走多长/远 η+3link、η、
在实际中很少直接使用梯度下降,而是使用小批量梯度下降|BGD-SGD-MBGD
选择批量大小:不能太小,因为每次计算量太小,不适合并行来最大利用计算资源;不能太大,因为会导致内存消耗增加,浪费计算,例如如果所有样本都是相同的
总结:
(1)梯度下降通过不断沿着反梯度方向更新参数求解(不需要知道显示解的样子,只要能够不断求导就行了);
(2)小批量随机梯度下降时深度学习默认的求解算法;
(3)两个重要的超参数是批量大小和学习率。
3、线性回归的代码实现
%matplotlib inline:可以将matplotlib的图表直接嵌入到Notebook之中,或者使用指定的界面库显示图表,它有一个参数指定matplotlib图表的显示方式。%matplotlib inline 可以在Ipython编译器里直接使用,功能是可以内嵌绘图,并且可以省略掉plt.show()这一步。介绍2、使用和作用、
报错UsageError: unrecognized arguments: 解决方法:删掉注释
根据带有噪声的线性模型构造一个人造数据集,构造人造数据集的好处是我们知道真实的w和b
带解释笔记√、
(1)生成训练样本
torch.normal用法 ↓ 、torch.rand/randn/normal/linespace、
torch.normal(means, std, out=None)
# means (Tensor) – 均值
# std (Tensor) – 标准差
# out (Tensor) – 可选的输出张量
torch.matmul是tensor的乘法,输入可以是高维的;当输入是都是二维时,就是普通的矩阵乘法,和tensor.mm函数用法相同。|| torch的几种乘法
pytorch绘制图像:定义set_figsize函数来设置图表大小。注意,这里我们直接使用d2l.plt,因为导入语句from matplotlib import pyplot as plt已在前言中标记为保存到d2l包中。
detach()分离出数值,不再含有梯度
scatter()函数最后的一个1是绘制点直径的大小,如果改成50会看到一个个点非常粗
总的来说 生成第二个特征features[:,1]
和labels
的散点图,可以直观观察到两者之间的线性关系
(2)写一个函数 来每次读取一个小批量
· 只是indices这个list被打乱了,features和labels都是顺序的,用循环才能随机地放进去
· min的作用 不让访问越界 list超出会报错,out of index
· 通过 yield,创建生成器 我们不再需要编写读文件的迭代类,就可以轻松实现文件读取
· 实现:给一些样本标号,每次随机选取b个样本返回,参与计算
(3)定义模型
初始化模型参数wb => 定义模型 => 定义损失函数 =>定义优化算法 =>
(4)训练过程
设定超参数 => for循环epoch 下 每次先扫一下 然后评价一下进度
4、线性回归的简洁实现
通过使用DL框架来简洁实现 线性回归模型 生成数据集(使用pytorchz中nn/数据预处理模块来简洁实现)
torch.utils实现数据自由读取、官方手册、(找书链接|书栈网)
读取训练集需要使用到2个类:(1)torch.Dataset/data.TensorDataset(2)torch.DataLoader
09-Softmax回归+损失函数+图片分类数据集
1、softmax回归其实是一个分类模型
回归 vs 分类:回归估计一个连续值;分类预测一个离散识别
MNIST:手写数字识别(10类)、ImageNet:自然物体分类(1000类)
Kaggle上的分类问题:将人类蛋白质显微镜图片分成28类、将恶意软件分成9个类别、将恶意的Wikipedia评论分成7类(对文字进行分类)...
对于分类来说,我们并不关心实际的值,而更关心对于正确类别的置信度是不是特别大(Oy>>Oi)
总结:
(1)softmax回归是一个多类分类模型(虽然我叫回归但是我是分类问题哦!)
(2)使用softmax操作子得到每个类的预测置信度(非负且和为1)
(3)使用交叉熵来衡量预测和标号的区别(作为损失函数)
softmax:把所有输入拉到0~1之间区域,使得y1+...+yk成为一个概率
2、损失函数
损失函数:衡量预测值与真实值之间的区别
L2 loss 均方误差 MSE
蓝色:y=0,变换预测值y' 得到的函数(二次函数)
绿色:似然函数(高斯分布)
橙色:损失函数的梯度(一次函数)、梯度下降时 是在负梯度方向更新参数->导数决定如何更新参数 eg如图当预测值与实际值相差较远时,梯度较大,参数更新较多;当预测值靠近实际值,靠近0,梯度较小,则对参数更新的幅度也越来越小。but并非完全理想,离原点较远时并不一定想要那么大的梯度。
L1 loss 平均绝对值误差 MAE
蓝/绿/橙、特点:当真实值与预测值相差较大时梯度也永远是常数,权重更新也不会特别大,从而带来稳定性上的好处、缺点:±0的不平滑性(±1)使得到达优化末期的时候变得不稳定
Huber's Robust Loss 平滑平均绝对误差
使用MAE用于训练神经网络的一个大问题就是,它的梯度始终很大,这会导致使用梯度下降训练模型时,在结束时遗漏最小值。对于MSE,梯度会随着损失值接近其最小值逐渐减少,从而使其更准确。|| 在这些情况下,Huber损失函数真的会非常有帮助,因为它围绕的最小值会减小梯度。而且相比MSE,它对异常值更具鲁棒性。因此,它同时具备MSE和MAE这两种损失函数的优点。不过,Huber损失函数也存在一个问题,我们可能需要训练超参数δ,而且这个过程需要不断迭代。|| 相比平方误差损失,Huber损失对于数据中异常值的敏感性要差一些。在值为0时,它也是可微分的。它基本上是绝对值,在误差很小时会变为平方值。误差使其平方值的大小如何取决于一个超参数δ,该参数可以调整。当δ~ 0时 Huber损失会趋向于MAE;当δ~ ∞(很大的数字)Huber损失会趋向于MSE。
3、图片分类数据集
4、softmax的从零实现、简洁实现
10-多层感知机+代码实现
1、感知机
感知机(perceptron)是二类分类的线性分类模型,其输入为实例的特征向量,输出为实例的类别。 || 感知机的目的:假设训练数据集是线性可分的,感知机学习的目的是求得一个能够将训练集整实例点和负实例点完全正确分开的分离超平面。 为了找出这样的超平面,即确定感知机模型参数w 和 b, 需要确定一个学习策略,即定义(经验)损失函数并将损失函数极小化。||
· 感知机二分类:-1或1、Vs.回归输出实数、Vs.Softmax回归输出概率 softmax多分类
解决办法
总结:
(1)感知机是一个二分类模型,是最早的AI模型之一;
(2)它的求解算法等价于使用批量大小为1的梯度下降;
(3)它不能拟合XOR函数,导致第一次AI寒冬。
2、多层感知机
(单隐藏层) 单分类、多分类
σ是按元素做运算的激活函数、要求被线性激活函数、课程截图
(多隐藏层)思考:需要多少隐藏层、每个隐藏层多大
每一层有自己的w和b、最后一层不要激活函数(作用是避免层数塌陷)
总结:
(1)多层感知机使用隐藏层和激活函数来得到非线性模型
(2)常用的激活函数是sigmoid(0,1)、Tanh(-1,1)、ReLU=max(0,x)
(3)使用Softmax来处理多类分类
(4)超参数为隐藏层数和各个隐藏层大小
3、多层感知机的实现
多层感知机(MLP,Multilayer Perceptron)也叫人工神经网络(ANN,Artificial Neural Network)除了输入输出层,它中间可以有多个隐层,最简单的MLP只含一个隐层,即三层的结构。
MLP★:最简单且原汁原味的神经网络则是多层感知器 。| 理解神经网络主要包括两大内容,一是神经网络的结构,其次则是神经网络的训练和学习,其就好比我们的大脑结构是怎么构成的,而基于该组成我们又是怎样去学习和识别不同事物的。|最典型的MLP包括包括三层:输入层、隐层和输出层,MLP神经网络不同层之间是全连接的(全连接的意思就是:上一层的任何一个神经元与下一层的所有神经元都有连接)。|神经网络主要有三个基本要素:权重、偏置和激活函数。权重:神经元之间的连接强度由权重表示,权重的大小表示可能性的大小。偏置:偏置的设置是为了正确分类样本,是模型中一个重要的参数,即保证通过输入算出的输出值不能随便激活。激活函数:起非线性映射的作用,其可将神经元的输出幅度限制在一定范围内,一般限制在(-1~1)或(0~1)之间。最常用的激活函数是Sigmoid函数,其可将(-∞,+∞)的数映射到(0~1)的范围内。|MLP的最经典例子就是数字识别,即我们随便给出一张上面写有数字的图片并作为输入,由它最终给出图片上的数字到底是几(具体过程见连接)。
torch.nn.Parameter():可以把这个函数理解为类型转换函数link、requires_grad表示是否该张量是否需要梯度,默认值为True
torch.nn.CrossEntropyLoss()、交叉熵损失函数:该损失函数结合了nn.LogSoftmax()和nn.NLLLoss()两个函数。它在做分类(具体几类)训练的时候是非常有用的。在训练过程中,对于每个类分配权值,可选的参数权值应该是一个1D张量。当你有一个不平衡的训练集时,这是是非常有用的。 交叉熵主要是用来判定实际的输出与期望的输出的接近程度,为什么这么说呢,举个例子:在做分类的训练的时候,如果一个样本属于第K类,那么这个类别所对应的的输出节点的输出值应该为1,而其他节点的输出都为0,即[0,0,1,0,….0,0],这个数组也就是样本的Label,是神经网络最期望的输出结果。也就是说用它来衡量网络的输出与标签的差异,利用这种差异经过反向传播去更新网络参数。|| 在说交叉熵之前,先说下信息量和熵。信息量:它是用来衡量一个事件的不确定性的;一个事件发生的概率越大,不确定性越小,则它所携带的信息量就越小。熵:它是用来衡量一个系统的混乱程度的,代表一个系统中信息量的总和;信息量总和越大,表明这个系统不确定性就越大。交叉熵:它主要刻画的是实际输出(概率)与期望输出(概率)的距离,也就是交叉熵的值越小,两个概率分布就越接近。 Pytorch中CrossEntropyLoss()函数的主要是将softmax-log-NLLLoss合并到一块得到的结果。①Softmax后的数值都在0~1之间,所以ln之后值域是负无穷到0。②然后将Softmax之后的结果取log,将乘法改成加法减少计算量,同时保障函数的单调性 。③NLLLoss的结果就是把上面的输出与Label对应的那个值拿出来(下面例子中就是:将log_output\logsoftmax_output中与y_target对应的值拿出来),去掉负号,再求均值。
11-模型选择+过拟合/欠拟合
1、模型选择
训练误差(模型在训练数据上的误差)和泛化误差(模型在新数据上的误差)
验证数据集(用来评估模型好坏≠训练数据)和测试数据集(只用一次的数据集)
总结:
训练数据集:训练模型参数
验证数据集:选择模型超参数
非大数据集上通常使用K-折交叉验证(来评价交叉验证的好坏)
2、过拟合和欠拟合
模型容量:拟合各种函数的能力。低容量的模型难以拟合训练数据,高容量的模型可以脊柱所有的训练数据。
VC维:对于一个分类模型,VC等于一个最大的数据集的大小,不管如何给定标号,都存在一个模型对它来进行完美分类。|| 二维线性函数集合的VC维是3 || 统计学VC维把它简单理解成为模型的复杂度和灵活度,VC维越高的模型,能够表征的函数就越广泛,当然学习过程中由于数据的不足容易造成过拟合。|| 用处:为一个模型为什么好提供理论依据(它可以衡量训练误差和泛化误差之间的间隔),但DL中很少使用(因为衡量不是很准确、计算DL模型的VC维很难)。
数据复杂度:多个重要因素:样本个数、每个样本的元素个数、时间空间结构、多样性。
总结:
(1)模型容量需要匹配数据复杂度,否则可能导致欠拟合和过拟合
(2)统计机器学习提供数学工具来衡量模型复杂度
(3)实际中一般靠观察训练误差和验证误差
3、代码实现
Accumulator累加器、2、使用:是一个实用程序类,用于对多个变量进行累加。
nn.Sequential√、两种使用方法:模块将按照构造函数中传递的顺序添加到模块中。通俗的话说,就是根据自己的需求,把不同的函数组合成一个(小的)模块使用或者把组合的模块添加到自己的网络中。(类似于python里的list)主要有两种使用方法。↓ 线性回归深度学习
12-权重衰退
1、权重衰退
权重衰减等价于范数正则化(regularization)。可以通过去收集更多的训练数据来缓解过拟合。 但这可能成本很高,耗时颇多,或者完全超出我们的控制,因而在短期内不可能做到。 假设我们已经拥有尽可能多的高质量数据,我们便可以将重点放在正则化技术上。
参数更新法则
总结:
(1)权重衰退通过L2正则项使得模型参数不会过大,从而控制模型复杂度
(2)正则项权重是控制模型复杂度的超参数
2、代码实现
synthetic_data:合成数据集
13-丢弃法
课程截图、
正则:使权重不要太大来防止过拟合(不是在输入加噪音而是在层之间加噪音=>丢弃法是正则)
总结:
(1)丢弃法将一些输出项随机置0来控制模型复杂度
(2)常作用在多层感知机的隐藏层输出上
(3)丢弃概率是控制模型复杂度的超参数
代码实现
Python assert 语句,又称断言语句,可以看做是功能缩小版的 if 语句,它用于判断某个表达式的值,如果值为真,则程序可以继续往下执行;反之,Python 解释器会报 AssertionError 错误。语法结构为:assert 表达式
14-数值稳定性+模型初始化+激活hs
课程截图 、
1、数值稳定性
向量关于向量的导数是矩阵、权重=学习率x梯度
数值稳定性的两个常见问题:梯度爆炸、梯度消失(MLP的例子)
总结:
(1)当数值过大或者过小时会导致数值问题
(2)常发生在深度模型中,因为其会对n个数累乘
2、模型初始化和激活函数
MLP的例子:正向方差、反向均值和方差、Xavier、假设线性的激活函数、检查常用激活函数、
总结:合理的权重初始值和激活函数的选取可以提升数值稳定性。
15-Kaggle之预测房价
os.path.splitext(path) os.path.dirname(path) os.path.join(path1[, path2[, ...]]) os.path.exists(path) | 分割路径,返回路径名和文件扩展名的元组 返回文件路径 把目录和文件名合成一个路径 如路径 path 存在,返回 True;如路径 path 不存在,返回 False |
join和os.path.join()-99乘法表、os.path.join()具体实现语法、
摘要算法hashlib.sha1():MD5是最常见的摘要算法,速度很快,生成结果是固定的128 bit字节,通常用一个32位的16进制字符串表示。SHA1的结果是160 bit字节,通常用一个40位的16进制字符串表示。比SHA1更安全的算法是SHA256和SHA512,不过越安全的算法不仅越慢,而且摘要长度更长。|| 廖雪峰hashlib★★运用:网站存储用户登录的用户名和口令 、hashlib.md5:要注意摘要算法不是加密算法,不能用于加密(因为无法通过摘要反推明文),只能用于防篡改,但是它的单向计算特性决定了可以在不存储明文口令的情况下验证用户口令。
digest()和hexdigest()区别:hashlib是涉及安全散列和消息摘要,提供多个不同的加密算法接口,如SHA1、SHA224、SHA256、SHA384、SHA512、MD5等。|| hash.hexdigest()返回摘要,作为十六进制数据字符串值。
os.makedirs():用于递归创建目录 os 文件/目录
requests的get方法:url(请求的url地址-必需 )verify参数(ssl证书验证-可选)、参数列表★、
url | 试一试 | 必须。请求的网址 |
stream | 试一试 | 可选。如果响应应立即下载(False)或流式传输(True)的布尔指示。 默认 False |
verify | 试一试 试一试 | 可选。用于验证服务器TLS证书的布尔值或字符串指示。 默认 True |
loc和iloc函数√:loc函数通过行索引 "Index" 中的具体值来取行数据;iloc函数通过行号来取行数据(如取第二行的数据):data.iloc[行,列]
输入区分shal和sha1(notebook下不太看得出来区别)
pd.concat():可以沿着指定的轴将多个dataframe或者series拼接到一起,这一点和另一个常用的pd.merge()函数不同,pd.merge()函数只能实现两个表的拼接。|| 例子讲解参数:
pd.concat( objs, axis=0, join='outer', join_axes=None,
ignore_index=False, keys=None, levels=None, names=None,
verify_integrity=False, sort=None, copy=True,)
pd.get_dummies:利用pandas实现one hot encode独热编码的方式、eg、“Dummy_na=True”将“na”(缺失值)视为有效的特征值,并为其创建指示符特征、特征提取-具体参数说明★、使用one_hot编码将离散的特征分解成多个特征,分解之后的特征可以用0/1来表示,这样,这个转换将特征数从79增加到了331、
pandas.get_dummies(data, prefix=None, prefix_sep=’_’,
dummy_na=False, columns=None,
sparse=False, drop_first=False, dtype=None)
data : array-like, Series, or DataFrame 输入的数据
prefix : string, list of strings, or dict of strings, default None。
get_dummies转换后,列名的前缀
columns : list-like, default None。指定需要实现类别转换的列名
dummy_na : bool, default False,增加一列表示空缺值,如果False就忽略空缺值
drop_first : bool, default False,获得k中的k-1个类别值,去除第一个。
Adam 优化算法(Adam optimization algorithm),基本上就是将Momentum和RMSprop结合在一起。 Adam优化器的主要吸引力在于它对初始学习率不那么敏感 | 可以认为成一个比较平滑的SGD。简单认识 Adam、介绍及优缺点
https://www.kaggle.com/c/california-house-price/overview