本文旨在对深度学习重要概念进行整理和对pytorch算法进行整理
参考《深度学习之pytorch实战计算机视觉》
损失值就是预测值与真实之间的误差,梯度就是多元函数的各个参数求导并以向量的形式出现。
梯度更新就是对损失函数求导,
每次计算损失值都是对参与训练的整个数据集而言的。出现了批量梯度下降,即将训练集划分为多个批次,每次计算损失函数选取一个批次并对全局参数进行梯度更新.直到所以批次数据使用完毕就是训练一轮,会使得计算损失函数的时间和训练的复杂度降低,但是很容易导致优化函数的最终结果是全局最优解。还有一个就是随机梯度下降,就是随机选择数据计算损失函数,并对损失函数求导梯度更新,缺点会受到随机训练数据集中噪声数据影响。
sigmoid的导数的取值区间是0-0.25,在后向传播每经过一个节点就要乘以sigmoid导数,梯度大小就变为原来的1/4,随着模型层数加深,梯度值就越来越小,甚至会消失。
输出结果是以0为中心,解决了激活函数在模型优化过程中收敛速度慢的问题,取值为0-1,不够大,所以仍然会出现梯度消失的情况
目前使用率最高的激活函数,输出结果小于0激活函数输出为0,否则就是本身,收敛速度非常快,因为Relu输出不是零中心数据,可能默写神经元永远不会被激活,这些神经元对应的参数不能被更新。因为模型参数在初始化的时候被设置为全正或者全负;在反向传播的时候设置学习率过大,收敛较快导致。目前改进版本是Leaky-ReLU,R-ReLU
参考之前的文章
卷积神经网络
深度卷积神经网络DCNN总结(AlexNet,ZFNet,VGGNet,GooleNet,ResNet)
CNN中重要的组件就是Filter(卷积核),卷积核有三个元素,高度、宽度、深度,高度和宽度一般常用的是33和55,深度根据输入图像的通道数设置,如果是图像是3通道彩色的,就设置为3,如果输入图像是黑白的,就设置为1.
三通道的卷积过程可以看成三个独立的单通道卷积过程,最后三个独立的单通道卷积过程相加即可。
将输入图像在经过卷积层和池化层操作后提取的核心特征与全连接层定义的权重参数相乘,将输出的参数值输入到softmax激活函数中,激活函数输出的是各个类别的可能性。
在学习pytorch框架之前,可以先参考我的python学习笔记专栏和我之前的pytorch文章
一些简单的加减乘除这里就不列举,列举常用但是看到不知道是什么的
求幂运算符:**
取整运算符://
与:and
或:or
非:not
成员运算符:in,返回值为布尔类型。
身份运算符:is ;is not,只有内存地址一样,才返回True,跟==是不同的
init():类的初始化方法,在创建实例的时候会调用此方法
self:代表类的实例,在定义类的时候是必须有的,但是调用的时候不必传入参数。
ndim:数组的维度个数:2行3列的数组维度数ndim是2
shape:数组的维度,2行3列shape是(2,3)
size:数组中元素的总数量,2行3列为6
dtype:数组中元素的类型
itemsize:每个元素字节大小,比如dtype是float64,itemsize为8
数组打印:直接print(数组名字)
min:最小值
max:最大值
sum:对数组进行求和,可以设置axis设置是对行还是列求和
exp:指数运算
sqrt:平方根运算
square:平方运算
seed:伪随机
rand:在[0,1)满足均匀分布的随机样本
randn:满足平均值为0,方差为1的正态分布
randint:在给定的范围生成类型为整数的随机样本数
b 蓝色
g 绿色
r 红色
c 蓝绿色
m 洋红色
y 黄色
k 黑色
w 白色
o 圆形
‘*’ *
‘+’ +
x x
‘-’ 实线
‘–’虚线
‘-.’点实线
‘.’点线
torch.FloatTensor可以是一个维度值,也可以是一个列表
如果给的是一个维度值,可以根据维度值随机生成浮点型
torch.IntTensor
没有指定类型 torch.rand(2,3):生成2行3列的浮点型数据
torch.randn 也是随机生成
torch.range:生成自定义起始范围和结束范围的浮点型数据Tensor
如torch.range(1,20,1):范围是1-20,间隔是1
小节: 没有指定类型生成的Tensor都是浮点型
torch.abs:输入tensor数据,输出为绝对值
torch.add:输入tensor数据,输出为两个tensor相加
torch.clamp:对输入参数按照自定义的范围随机裁剪,参数为:tensor数据类型、裁剪的上边界、裁剪的下边界
torch.div:求商
torch.mul:求积
torch.pow:求幂
torch.mm:求矩阵的乘积
torch.mv:第一个参数是矩阵,第二个参数是向量,返回乘积
torch.autograd包:用这个包中的variable包对Tensor对象封装,然后自动链式求导
用X代表节点,x.data代表数据类型变量,x.grad是variable对象,x.grad.data是梯度值
可以构建一个继承torch.nn.Module的新类,完成对前向传播和后向传播的重写,使用forward作为前向传播的关键字,使用backward作为后向传播的关键字,
torch.nn中有很多实现神经网络具体功能的类,比如卷积层,池化层,全连接层,参数归一化,Dropout,激活函数,
是torch.nn中的序列容器,可以搭建网络,1、直接嵌套2、使用orderdict字典,前者从0开始对模块进行排序,后者可以自定义模块名字
用于定义模型的线性层,参数:输入特征数、输出特征数、是否使用偏置,默认是True
使用均方误差对损失值进行计算,在定义类的时候不需要传入任何参数,在使用实例的时候需要传入两个维度一样的参数进行计算
使用平均绝对误差计算损失值,在定义类的时候不需要传入任何参数,在使用实例的时候需要传入两个维度一样的参数进行计算
计算交叉熵,在定义类的时候不需要传入任何参数,在使用实例的时候需要输入两个满足交叉熵计算条件的参数
参数输入通道,输出通道,卷积核大小,步长,paddingde
池化窗口大小,步长,paddingde
以一定随机概率将部分参数归零,因为是随机的,所以每轮进行丢弃的神经元也不同,最后训练出来的模型不会对某部分参数过度依赖,防止过拟合,随机概率默认值是0.5
x.view(-1,1414128)进行扁平化处理,然后全连接层,如果不进行扁平化处理,全连接输出维度和输入维度不匹配;最后使用self.dense进行最后分类。
models.parameters()
torch.optim里面有很多自动优化参数的类,如torch.optim.Adam里面可以传入被优化的参数models.parameters(),学习率初始值,并且可以根据梯度更新对学习率进行自动调节。
上面介绍使用torch.nn中线性层和激活函数配合torch.optim完成神经网络搭建和优化,并使用torch.auto完成自动梯度功能,
torchvision主要功能是实现数据处理、导入和预览,一般会用到torchvision.datasets和torchvision.transforms,torchvision.datasets实现对数据集下载,root用于指定下载数据集存放路径,transforms指定在导入数据集对数据进行哪些变换,train是数据应该载入哪部分?
torchvision.transforms.Compose对各种变换进行组合,传入的参数是一个列表,比如**transforms.ToTensor(),transforms.Normalize()**对数据标准化,需要使用均值和标准差进行数据标准化,经过标准化之后,默认是数据是均值为0,标准差为1的正态分布;
其他参数大家用到自行查阅。
batch_size:确认每个包大小,shuffle:是否打乱
使用torch,utils.data,DataLoader类
# 获取一个批次的图片数据和标签
images,labels=next(iter(data_loader_train))
# 将一个批次图片构造成网格模式,参数是一个批次的装载数据,每个装载数据都是4维的,维度是batchsize,channel,height,weight,输出结果是channel,height,weight,图片被整合,height,weight改变,channel值不变
img=torchvision.utils.make_grid(images)
# 转换成数组形式,用plt显示,数组的维度是height,weight,channel
img=img.numpy().transpose(1,2,0)
std=[0.5]
mean=[0.5]
img=img*std+mean
print(labels[i] for i in range(64))
plt.imshow(img)
下载模型
model=models.vgg16(prepare=True)
在迁移学习中调整最多的也就是全连接层,先冻结全连接层之前的部分,在学习过程中不进行参数更新,将参数中param.requires_grad全部设置为False,就不会进行梯度更新,就是之前的冻结操作;然后定义新的全连接层从新赋值给model.classifier,全连接层重新被定义之后,全连接层的参数会自动解冻。优化参数变成model.classifier.parameters,这样只需要训练很少就可以达到很高准确率,
设置每个模型不同权重,对结果预测结果进行加权平均。然后再和真实值进行比较
RNN也可以实现分类,在特征提取上没有CNN强大,RNN可以随意控制输入和输出的数量,
核心特征提取编码和数据重构解码
#在原始图片山加上一个维度相同的随机数字对图像中的像素点进行扰乱
noisy_images=images+0.5*np.random.randn(*images.shape)
noisy_images=np.clip(noisy_images,0.,1.)