数据,模型,可视化在pytorch主要实现

1数据
数据划分完毕后,图片通常是png/jpg格式,pytorch读取图片,主要通过Dataset类,所以我们第一步需要将数据组织成Dataset,构建完成后,我们需要将组织好的数据加载到模型中,实现从硬盘到模型的输入,需要借助DataLoder创建迭代对象,将数据组织好后,在真正训练时,将数据进行迭代完成训练。

1.1数据构建
1.1.1制作图片数据索引
构建索引目的就是为了知道这个图片属于哪个类别,通常有两种方式,1当所有图片在同一个文件夹下,我可以通过创建一个txt文件,在文件中每行记录每一个图片及其对应标签;2我先对所有照片都分了类别,将属于同一个类别的图片置于同一个文件夹下
1.1.2构建Dataset子类
核心需要实现Dataset继承下来的虚函数:init,getItem,len
其中__init__需要告诉子类self.imgs(图像位置与标签),self.transform;__len__直接返回len(self,imgs)即可;以下以分割为例,其与分类在这里不同只是一个是数字类别标签,一个掩膜图像。

核心是getItem函数,根据初始化中的self.imgs及函数参数index,返回该索引下的图像与标签

1.1.3数据增强
在初始化函数中transforms数据增强需要我们人为去定义,目前常用的数据增强可以调用torchvision.transforms中提供的22种方式或者调用Albumentations库中提供的更为丰富的数据增强处理,下面以Albumentations中使用为例:然后在定义Dataset对象时直接调用即可。

1.2数据加载
目前数据我们数据已经组织好了,那到底怎么塞给模型呢:一次塞多少张?batch设置;塞的顺序?shuffle设置;用几个工作进程来找这batch张呢?Num_worker设置;最后一组没有batch张还要不要呢?Drop_last设置;数据万一需要进一步处理怎么办(如有几张损坏的图片)?Collate_fn给对数据进行在一次整理的机会。
collate_fn:该函数用于核对和整理数据,其输入就是一个list,list的长度是一个batch size,list中的每个元素都是__getitem__得到的结果,输出是经过该函数整理后的结果。那我们什么时候会使用到这个参数呢?我们需要对数据进行进一步处理时。比如对于数据中可能产生被损害的照片,无法转成tensor,最优解当然是剔除或改善该照片,但有时候无法完全找到到底哪一张损坏,便可以考虑自定义collate_fn函数,通过过滤掉矩阵为None的照片,保证迭代不会存在问题batch = list(filter(lambda x:x[0] is not None, batch);或者我们想对读取的照片进行数据处理,比如都所有的像素都加10,也可以在这里进行自定义,然后返回每个像素增加10后的结果。即总的来说该函数使得我们的数据在进行迭代前有了在一次重新整理的机会,通常自定义格式如下:最后通常要进过pytorch官方的default_collate函数,其有很多功能,如将numpy转成可以遍历的tensor格式,确保我们迭代不会出错。

1.3数据训练
现在数据已经由dataloader进行管理,对于每一个epoch的训练,我们只需要for img,label in dataloder即可,对于最简单的特定次数训练,即在外面再套一层循环即可。

2模型
关于模型角度核心问题围绕模型如何搭建,模型权重如何初始化,模型的迁移学习(本质还是模型权重的初始化)
2.1模型构建
先继承,再构建组件,最后组装。
首先,必须继承nn.Module这个类,方便调用其接口;然后在__init__(self)中设置好对应组件(如conv,pooling及其通过sequential组装等);最后再forward(self,x)中将定义好的组件进行组装,像搭积木一样,把网络结构搭建出来,完成模型定义。
2.2模型权重初始化
模型构建好了,该给模型什么样的初始化参数给开始训练呢?这便需要考虑权重初始化方法,而初始化方法的选取将会直接影响到模型收敛速度,使得卷积的输出和前传比较稳定。
权重初始化流程:通常有两种思路,第一种先定义初始化权重方法init_weight(model),然后在通过net.apply(init_weight)实现参数初始化;第二种则是通过model.modules实现参数初始化,即通过for layer in net.modules():进行遍历,然后对不同的网络层次定义不同的初始化方法。
常用的权重初始化方法:Xavier初始化(torch.nn.init.xavier_uniform_/normal)与kaiming初始化(torch.nn.init.kaiming_uniform_/noamal)两者都考虑了正向传播与反向传播,可以保证输入输出方差一致性,但kaming同时考虑的激活函数(relu),如果神经网络的激活函数是relu时,推荐使用kaiming初始化方法。
Pytorch默认调用权重初始化方法:其实在创建模型过程中,一旦调用nn.Conv2d就会对权重进行初始化,观察conv2d源码看self.rese_parameters中定义的self.weight.data中调用的方法,早期采用的是uniform_(-stdv,stdv)均匀分布,pytorch1.0后改用了kaiming_uniform_初始化
2.3模型迁移学习
2.3.1迁移学习权重初始化
对于迁移学习,我们通常是将一个在大数据上已经训练好的模型训练权重加载到我们特定领域任务上。
第一步:保存模型参数torch.save(net.state_dice(),”net_params.pkl”)
第二步:获取模型参数到字典pretrained_dict = torch.load(“net_params.pkl”)
第三步:加载模型参数:先获取新网络字典net_state_dict = net.state_dict();然后将预训练权重中不属于新网络的键剔除new_pretrained_dict = {k:v for k,v in pretrained_dict.items()if k in net_state_dict};接着将新参数字典更新net_state_dict.update(new_pretrained_dict);最后将更新的参数加载到网络中net.load_state_dict(net_state_dict)
2.3.2迁移学习固定学习特定层
当一个模型在pytorch中加载,其所有参数的requires_grad字段默认为true,即所有参数都会训练,我们迁移学习时往往会固定特征提取器的权重,只训练全连接层。下面以resnet18二分类为例:
1加载预训练模型:model_conv = torchvision.models.resnet18(pretrained=True)
2冻结网络权重:for param in model_conv.parameters():param.requires_grad = False
3修改为迁移学习后分类数目(对全连接层修改后requires_grad又默认成了true)
num_ftrs = model_conv.fc.in_features;model_conv.fc = nn.Linear(num_ftrs, 2)
2.3.3迁移学习为不同的层设置不同的学习率
当我们进行迁移学习的时候,有可能并非希望前面权重完全冻结,而是也能得到微小训练,但其调整力度不能过大,而我们新增的全连接层能得到更快的训练,即需要对不同的层设置不同的学习率。
1参数组划分:fc_params=list(map(id,net.fc.parameters()));conv_params=filter(lambda
p:id§not in fc_params,net_parameters())
2设置不同学习率:optimizer = optim.SGD([{‘params’:conv_params},
{‘params’:net.fc.parameters,’lr’:0.001*10}],0.001,momentum=0.9,weight_decay=le-4)
3损失函数与优化器
损失函数用于评价模型的预测值与真实值的不一致程度。通俗讲就是你说模型预测的准,它到底预测的多准,与真实标签比一比,他们之间相差的量化具体规则。常用的有bce,dice,Tversky,focal等损失函数,具体见损失函数那节。
优化器是为了找到模型最优解,即得到最优的参数。通俗讲就是我现在有损失函数,我现在希望损失函数尽可能小,我需要怎样一步步对参数进行调节使得模型得到最优解。核心算法都是反向传播,那难点在于反向传播过程中梯度的方向如何选取,每一次传播的步长有多大,具体见优化器那节。
4可视化
4.1tensorboard可视化基本流程
首先导入torch.utils.tensorboard/tensorboardX中的SummaryWriter,然后定义writer指定一个文件夹供tensorboard保存记录下来的数据。接着通过调用对应方法进行可视化后调用write.close关闭;然后在命令行中输入tensorboard --logdir=path --port=xx(指定端口号,不换电脑不用设置) --bind_all(暴露服务器ip,使得浏览器可以访问服务器ip),做后打开网页输入http://localhost:6006观察即可即可
4.2tensorboard可视化
网络结构可视化:(1)直接print(model)可以打印出模型基础构建信息,但不能显示每一层对应形状及参数量大小;(2)从torchinfo库导入summary,调用summary(model,input[batch_size,c,h,w])来得到更为详细的信息,包括模块信息,整体参数量,模型大小,前向传播或反向传播所需内存大小等。(3)在tensorboard中调用add_graph(model,input)方法
图像可视化:图像可视化主要用于可视化卷积核和可视化中间特征影像,其方法是一致的。对于单张图像add_image(tag,img[b,c,h,w],global_step[x坐标]);多张图像:add_images;也可以通过使用torchvision.utils.make_grid先将多张图片拼接成一张图片,在通过writer.add_image进行显示。
梯度及权值分布可视化:for name,layer in net.parameters():writer.addhistogram(name+’_grad’, layer.grad.cpu().data.numpy(),epoch);writer.add_histogram(name+’_data’,layer.cpu().data.numpy(),epoch)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值