1、nn.functional中的函数和nn.Module主要区别
function定义的激活函数等不需要学习,参数更新。激活函数(ReLU,sigmoid,tanh),池化等可以使用functional替代。
module一般定义层,参数需要更新,对于卷积,全连接等具有可学习参数的网络建议使用nn.Module
2、pytorch使用多gpu训练机制
处理接口是 model = nn . DataParallel ( model ,device_ids)
机制是:首先将模型加载到主GPU上,然后再将模型复刻到各个指定的分GPU中,然后将输入数据按batch维度进行划分(坑:需要先将数据加载到主GPU上),具体来说就是每个GPU分配到的数据batch数量是总输入数据的batch除以指定GPU个数
每个GPU将针对各自的输入数据独立进行forward计算,最后将各个GPU的loss计算求和,再用反向传播更新单个GPU上得模型参数,再将更新后得模型参数复制到其他GPU中,就完成了一次迭代。
3、加速python代码
用GPU、batchsize,用CPU加载数据,采用异步,先加载一部分数据到内存
4、定义完model,什么时候会调用forward(为什么用output=model(img)就可以)
一般网络层结构都是继承父类得构造函数,在父类中有call函数,会自动触发,逐渐调用各种系统、前向、后向的hooks
5、Variable
是Autograd的核心类,它封装了Tensor,并整合了反向传播的相关实现
三属性:data 获得Tensor本身
grad 获得Tensor梯度
grad_fn 获得方式
神经网络可以用这将一个个节点连起来,一次性计算梯度
6、torchvision
torchvision,视觉工具包,提供了很多视觉图像处理的工具,其中transforms模块提供了对PIL Image对象和Tensor对象的常用操作。主要包含三部分:
•models:提供深度学习中各种经典网络的网络结构以及预训练好的模型,包括AlexNet、VGG系列、ResNet系列、Inception系列等。
•datasets: 提供常用的数据集加载,设计上都是继承torhc.utils.data.Dataset,主要包括MNIST、CIFAR10/100、ImageNet、COCO等。
•transforms:提供常用的数据预处理操作,主要包括对Tensor以及PIL Image对象的操作。
7、train和eval区别
模型有BN,train保证BN用每一批数据的均值和方差
eval保证用全部训练数据的均值和方差
有dropout,train保证使用
eval保证不使用
两者都有梯度计算,但eval不作反向传播,使用with torch.no_grad可以加速时间及节省 GPU使用
8、pytorch如何微调fine tuning
在加载了预训练模型参数之后,需要finetuning模型,可以使用不同的方式finetune
局部微调:加载了模型参数后,只想调节最后几层,其它层不训练,也就是不进行梯度计算,pytorch提供的requires_grad使得对训练的控制变得非常简单
全局微调:对全局微调时,只不过我们希望改换过的层和其他层的学习速率不一样,这时候把其它层和新层在optimizer中单独赋予不同的学习速率。
9、torch.nn
10、nn.Module与autograd的区别
nn.Module利用了autograd技术,对nn的功能进行扩展,实现了深度学习中更多的层。只需实现前向传播功能,autograd即会自动实现反向传播。
11、pytorch中torch.Tensor()和torch.tensor()的相同点和区别
相同点:Tensor和tensor都能用于生成新的张量
不同点:torch.Tensor()是python类,是torch.FloatTensor()的别名,使用torch.Tensor()会调用Tensor类的构造函数,生成float类型的张量;而torch.tensor()仅仅是python的函数,函数原型是torch.tensor(data, dtype=None, device=None, requires_grad=False),其中data可以是scalar,list,tuple,numpy array等等。然后torch.tensor会从data中的数据部分进行拷贝(而不是引用),根据原始数据类型生成相应的 torch.LongTensor、torch.FloatTensor和torch.DoubleTensor。
12、pytorch中backward()的理解
13、conv2d的参数及含义
一般模型构建
训练
一、数据处理、读取
(1)定义数据处理的方式
data_transforms=transforms.Compose([
transforms.RandomResizeCrop(),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize()])
(2)自定义数据集形式
video_dataset=videoDataset(video_info_list,transforms)
videoDataset 自定义,主要包含三个部分
__init__ 初始化
__len__ 获取数据集大小
__get__ 读取数据
(3)数据集加载
data_loaders=torch.utils.Dataloader(video_dataset,batch_size,shuffle,num_worker)
#num_worker 表示有多少进程处理数据加载
#也可以加sampler自定义取样本策略,但shuffle要设为False
二、模型构建
(1)加载模型
model=models.主网络层(参数)
(2)加载预训练参数(可选)
model.load_state_dict(torch.load(权重参数pkl的路径))
#若是finetune,只训练某几层,可以冻结其它不用训练层的参数
for param in model.parameters():
param.requires_grad=False
#然后修改最后的输出层
(3)将网络送到GPU
#若是分布式要加 model=nn.DataParallel(model)
model=model.cuda()
三、定义损失函数
criterion=nn.CrossEntropyLoss()
四、定义优化器
optimizer=optim.SGD(model.parameters(),lr,momentum,weigh_decay)
#设置学习率下降策略
scheduler=torch.optim.lr_scheduler.StepLR(optimizer,step_size,gamma)
五、训练
for epoch in range(num_epochs):
epoch +=1
loss_mean=0
correct=0
model.train() #训练模式
for item,datas in enumerate(data_loaders):
#forward
inputs,labels=datas
if use_gpu:
labels=np.array(labels).astype(int)
labels=torch.from_numpy(labels)
inputs=Variable(inputs.cuda())
labels=Variable(labels.cuda())
optimizer.zero_grad() #梯度清0,防止上一次的影响这一次
outputs=model(inputs)
#backward
loss=criterion(outputs,labels)
loss.backward()
optimizer.step() #更新参数
#统计分类情况
_,preds=torch.max(outputs.data,1) #输出每一行的最大值
correct+=torch.sum(preds=labels.data).item()
#打印训练信息
loss_mean+=loss.item()
epoch_loss=loss_mean/data_size
epoch_acc=correct/float(data_size*batch_size)
scheduler.step()
评估
过程差不多类似于训练,只是可以加上不用计算梯度的语句,以及设置模式为eval()
网络层定义
class Stnet(nn.Module):
def __init__(self,参数列表):
super(Stnet,self).__init__() #继承父类
self.参数=参数列表的参数
#定义网络层
self.conv1=nn.Conv2d()
self.bn1=nn.BatchNorm2d()
#初始化指定层的参数
for m in self.modules():
if isinstance(m,nn.Conv2d):
nn.init.kaiming_normal_()
elif isinstance(m,nn.BatchNorm2d):
nn.init.constant_()
def forward(self,x):
x=self.conv1(x)
#也可以使用function函数定义的网络层
x=F.avg_pool2d()
return x
以上内容均来源于各个版主、牛客网总结