人工智障填坑记录

首先声明这是自己在学习期间遇到的一些问题及相关处理方法,整理下来,一方面为了记录学习过程;二是为了分享,或许能帮到大家,互相学习(其中有些解决方法不免是参考别人而整理下来的,如有雷同,不胜荣幸)。


1、已下载的CIFAR10如何加载到python (torchvision.datasets.CIFAR10) || 解决python中直接下载cifar-10-python.tar.gz 过慢的方法

将从此https://pan.baidu.com/s/1oAn8o8i链接下载的cifar-10-python.tar.gz解压提出cifar-10-batches-py文件夹,然后放在./data 目录下(jupyter notebook中的一个子目录即可)然后设置download=False即可
在这里插入图片描述
函数中的transform=transform 为先前定义的预处理操作。

2、代码np.transpose(npimg,(1,2,0))参数详解

def imshow(img):
    img = img / 2 + 0.5  # unnormalize
    npimg = img.numpy()  # 将torch.FloatTensor 转换为numpy
    plt.imshow(np.transpose(npimg,(1,2,0)))
    plt.show() 

plt.imshow()接收的参数输入顺序为(imagesize,imagesize,channels),而原始参数img的格式为(channels,imagesize,imagesize),调用np.transpose()函数来调换参数的输入顺序。如:将3×32×32调换成32×32×3.

3、针对“jupyter notebook 服务似乎挂掉了,但是会立即重启……”的解决方法。

显存分配不足,如果有GPU的话,在文件开头引入下面三行程序即可。

import os
os.environ["CUDA_VISIBLE_DEVICES"] = "0"  # 使用第1个GPU
os.environ["KMP_DUPLICATE_LIB_OK"] = 'True'  # 允许副本存在


4、关于torch.utils.data.DataLoader

torch.utils.data.DataLoader(
                            dataset,#数据加载
                            batch_size = 1#批处理大小设置
                            shuffle = False#是否进项洗牌操作
                            sampler = None#指定数据加载中使用的索引/键的序列
                            batch_sampler = None#和sampler类似
                            num_workers = 0#是否进行多进程加载数据设置
                            collat​​e_fn = None#是否合并样本列表以形成一小批Tensor
                            pin_memory = False#如果True,数据加载器会在返回之前将Tensors复制到CUDA固定内存
                            drop_last = False#True如果数据集大小不能被批处理大小整除,则设置为删除最后一个不完整的批处理。
                            timeout = 0#如果为正,则为从工作人员收集批处理的超时值
                            worker_init_fn = None


5、Pytorch加载训练好的模型

使用VGG-16模型

model = models.vgg16(pretrained=False)  # 由于是加载的已训练好的模型,此处可以设置为False
pre = torch.load(r'F:\installment\vgg16-397923af.pth')  # 提取本地模型
model.load_state_dict(pre) 

在COCO上加载经过预训练的预训练模型

model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=False,pretrained_backbone=False)
model.load_state_dict(torch.load('./model/fasterrcnn_resnet50_fpn_coco-258fb6c6.pth'))

#加载经过预先训练的模型进行分类,仅返回特征

model = torchvision.models.mobilenet_v2(pretrained=False)
model.load_state_dict(torch.load('./model/mobilenet_v2-b0353104.pth'))
backbone = model.features


6、 torch.nn.XXX 与 torch.functional.XXX的区别

两者的相同之处:
nn.XXX和nn.functional.XXX的实际功能是相同的,即nn.Conv2d和nn.functional.conv2d 都是进行卷积,nn.Dropout 和nn.functional.dropout都是进行dropout,。。。。。;
运行效率也是近乎相同。
nn.functional.XXX是函数接口,而nn.Xxx是nn.functional.XXX的类封装,并且nn.Xxx都继承于一个共同祖先nn.Module。这一点导致nn.XXX除了具有nn.functional.XXX功能之外,内部附带了nn.Module相关的属性和方法,例如train(), eval(),load_state_dict, state_dict 等。

两者的差别之处:
1、两者的调用方式不同。
nn.XXX需要先实例化并传入参数,然后以函数调用的方式调用实例化的对象并传入输入数据。

inputs = torch.rand(64, 3, 244, 244) 
conv = nn.Conv2d(in_channels=3, out_channels=64, kernel_size=3, padding=1) 
out = conv(inputs)

nn.functional.XXX同时传入输入数据和weight, bias等其他参数 。

weight = torch.rand(64,3,3,3)
bias = torch.rand(64) 
out = nn.functional.conv2d(inputs, weight, bias, padding=1)


2、nn.XXX继承于nn.Module, 能够很好的与nn.Sequential结合使用, 而nn.functional.XXX无法与nn.Sequential结合使用。

fm_layer = nn.Sequential(
            nn.Conv2d(3, 64, kernel_size=3, padding=1),
            nn.BatchNorm2d(num_features=64),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=2),
            nn.Dropout(0.2)
  )


3、nn.XXX不需要你自己定义和管理weight;而nn.functional.XXX需要你自己定义weight,每次调用的时候都需要手动传入weight, 不利于代码复用。
(1)使用nn.Xxx定义一个CNN 。

class CNN(nn.Module): 
	def __init__(self): 
		super(CNN, self).__init__() 
		self.cnn1 = nn.Conv2d(in_channels=1, out_channels=16, kernel_size=5,padding=0) 
		self.relu1 = nn.ReLU() 
		self.maxpool1 = nn.MaxPool2d(kernel_size=2) 
		self.cnn2 = nn.Conv2d(in_channels=16, out_channels=32, kernel_size=5, padding=0) 
		self.relu2 = nn.ReLU() self.maxpool2 = nn.MaxPool2d(kernel_size=2) 	
		self.linear1 = nn.Linear(4 * 4 * 32, 10) 
	def forward(self, x): 
		x = x.view(x.size(0), -1) 
		out = self.maxpool1(self.relu1(self.cnn1(x))) 
		out = self.maxpool2(self.relu2(self.cnn2(out))) 
		out = self.linear1(out.view(x.size(0), -1)) 
		return out


(2)使用nn.function.xxx定义一个与上面相同的CNN。

class CNN(nn.Module): 
	def __init__(self): 
		super(CNN, self).__init__() 
		self.cnn1_weight = nn.Parameter(torch.rand(16, 1, 5, 5)) 
		self.bias1_weight = nn.Parameter(torch.rand(16)) 
		self.cnn2_weight = nn.Parameter(torch.rand(32, 16, 5, 5)) 
		self.bias2_weight = nn.Parameter(torch.rand(32)) 
		self.linear1_weight = nn.Parameter(torch.rand(4 * 4 * 32, 10)) 
		self.bias3_weight = nn.Parameter(torch.rand(10)) 
	def forward(self, x): 
		x = x.view(x.size(0), -1) 
		out = F.conv2d(x, self.cnn1_weight, self.bias1_weight) 
		out = F.relu(out) out = F.max_pool2d(out) 
		out = F.conv2d(x, self.cnn2_weight, self.bias2_weight) 
		out = F.relu(out) 
		out = F.max_pool2d(out) 
		out = F.linear(x, self.linear1_weight, self.bias3_weight) 
		return out

PyTorch官方推荐:具有学习参数的(例如,conv2d, linear, batch_norm)采用nn.Xxx方式,没有学习参数的(例如,maxpool, loss func, activation func)等根据个人选择使用nn.functional.xxx或者nn.Xxx方式。但关于dropout,个人强烈推荐使用nn.Xxx方式,因为一般情况下只有训练阶段才进行dropout,在eval阶段都不会进行dropout。使用nn.Xxx方式定义dropout,在调用model.eval()之后,model中所有的dropout layer都关闭,但以nn.function.dropout方式定义dropout,在调用model.eval()之后并不能关闭dropout。
(来源知乎——有糖吃可好)

7、初始化模型参数

PyTorch中nn.Module的模块参数都采取了较为合理的初始化策略(不同类型的layer具体采样的哪一种初始化方法的可参考源代码)。但经常需要使用其他方法来初始化权重。PyTorch的init模块里提供了多种预设的初始化方法。

 #将权重参数初始化成均值为0、标准差为0.01的正态分布随机数,并依然将偏差参数清零。
for name, param in net.named_parameters():
    if 'weight' in name:
        init.normal_(param, mean=0, std=0.01)
        print(name, param.data)

for name, param in net.named_parameters():
    if 'bias' in name:
        init.constant_(param, val=0)
        print(name, param.data)


8、降维

# numpy中的ravel()、flatten()、squeeze()
# 都有将多维数组转换为一维数组的功能,区别:
# ravel():如果没有必要,不会产生源数据的副本
# flatten():返回源数据的副本
# squeeze():只能对维数为1的维度降维

9、numpy中的choice()

 a1 = np.random.choice(a=5, size=3, replace=False, p=None)
# 参数意思分别 是从a 中以概率P,随机选择3个, p没有指定的时候相当于是一致的分布
# replacement 代表的意思是抽样之后还放不放回去,如果是False的话,那么出来的三个数都不一样,如果是
# True的话, 有可能会出现重复的,因为前面的抽的放回去了

猜你喜欢

转载自blog.csdn.net/Su_Del/article/details/106961017