Em primeiro lugar, declaro que estes são alguns dos problemas e soluções relacionadas que encontrei durante o meu estudo. Eu resolvo, por um lado, para registrar o processo de aprendizagem; por outro lado, para compartilhar, talvez ajudar a todos, aprender uns com os outros (algumas das soluções são inevitáveis para se referir a outras E é uma grande honra resolver isso se houver semelhanças).
1. Como carregar o CIFAR10 baixado em python (torchvision.datasets.CIFAR10) || Resolva o problema de baixar cifar-10-python.tar.gz diretamente em python é muito lento
Descompacte o cifar-10-python.tar.gz baixado do link https://pan.baidu.com/s/1oAn8o8i para abrir a pasta cifar-10-batches-py e coloque-o em ./data (jupyter notebook A subdiretório em) e defina download = False
. O transform = transform na função é a operação de pré-processamento definida anteriormente.
2. Codifique os detalhes do parâmetro 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()
A ordem de entrada dos parâmetros recebidos por plt.imshow () é (imagesize, imagesize, channels), e o formato do parâmetro original img é (channels, imagesize, imagessize), chame a função np.transpose () para alterar o ordem de entrada dos parâmetros. Por exemplo: substitua 3 × 32 × 32 por 32 × 32 × 3.
3. A solução para "o serviço jupyter notebook parece estar fora do ar, mas irá reiniciar imediatamente ...".
A alocação de memória é insuficiente. Se houver uma GPU, as seguintes três linhas de programa podem ser introduzidas no início do arquivo.
import os
os.environ["CUDA_VISIBLE_DEVICES"] = "0" # 使用第1个GPU
os.environ["KMP_DUPLICATE_LIB_OK"] = 'True' # 允许副本存在
4. Sobre torch.utils.data.DataLoader
torch.utils.data.DataLoader(
dataset,#数据加载
batch_size = 1,#批处理大小设置
shuffle = False,#是否进项洗牌操作
sampler = None,#指定数据加载中使用的索引/键的序列
batch_sampler = None,#和sampler类似
num_workers = 0,#是否进行多进程加载数据设置
collate_fn = None,#是否合并样本列表以形成一小批Tensor
pin_memory = False,#如果True,数据加载器会在返回之前将Tensors复制到CUDA固定内存
drop_last = False,#True如果数据集大小不能被批处理大小整除,则设置为删除最后一个不完整的批处理。
timeout = 0,#如果为正,则为从工作人员收集批处理的超时值
worker_init_fn = None )
5. Pytorch carrega o modelo treinado
Use o modelo VGG-16
model = models.vgg16(pretrained=False) # 由于是加载的已训练好的模型,此处可以设置为False
pre = torch.load(r'F:\installment\vgg16-397923af.pth') # 提取本地模型
model.load_state_dict(pre)
Carregue o modelo pré-treinado pré-treinado no 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'))
#Carregue um modelo pré-treinado para classificação, retorne apenas recursos
model = torchvision.models.mobilenet_v2(pretrained=False)
model.load_state_dict(torch.load('./model/mobilenet_v2-b0353104.pth'))
backbone = model.features
6. A diferença entre torch.nn.XXX e torch.functional.XXX
As semelhanças entre os dois:
as funções reais de nn.XXX e nn.functional.XXX são as mesmas, ou seja, nn.Conv2d e nn.functional.conv2d são ambos convolução, e nn.Dropout e nn.functional.dropout são ambos Realizam abandono. . . . . ;
A eficiência operacional é quase a mesma.
nn.functional.XXX é uma interface funcional e nn.Xxx é um encapsulamento de classe de nn.functional.XXX e nn.Xxx todos herdam de um ancestral comum nn.Module. Isso leva a nn.XXX, além de ter funções nn.functional.XXX, também possui atributos e métodos relacionados a nn.Module, como train (), eval (), load_state_dict, state_dict, etc.
A diferença entre os dois:
1. Os métodos de chamada dos dois são diferentes.
nn.XXX precisa ser instanciado e passado em parâmetros e, em seguida, o objeto instanciado é chamado em uma chamada de função e os dados de entrada são passados.
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 também passa dados de entrada e outros parâmetros, como peso e polarização.
weight = torch.rand(64,3,3,3)
bias = torch.rand(64)
out = nn.functional.conv2d(inputs, weight, bias, padding=1)
2. nn.XXX herda de nn.Module e pode ser usado em conjunto com nn.Sequential, mas nn.functional.XXX não pode ser usado em conjunto com 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 não exige que você defina e gerencie o peso sozinho; enquanto nn.functional.XXX exige que você defina o peso, você precisa passar manualmente o peso cada vez que você chamá-lo, o que não é propício para reutilização de código.
(1) Use nn.Xxx para definir um 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) Use nn.function.xxx para definir o mesmo CNN acima.
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
Recomendação oficial da PyTorch: use nn.Xxx para parâmetros de aprendizagem (por exemplo, conv2d, linear, batch_norm) e use nn.functional.xxx ou nn para aqueles sem parâmetros de aprendizagem (por exemplo, maxpool, função de perda, função de ativação), etc. .de acordo com a escolha pessoal. Maneira Xxx. Porém, em relação ao abandono, recomendo fortemente o uso do método nn.Xxx, pois em geral o abandono é realizado apenas na fase de treinamento e não será realizado na fase de avaliação. Use nn.Xxx para definir o dropout. Depois de chamar model.eval (), todas as camadas de dropout no modelo são fechadas, mas define o dropout no modo nn.function.dropout. O dropout não pode ser fechado após chamar model.eval ().
(Fonte Know-It é melhor ter açúcar)
7. Inicializar os parâmetros do modelo
Os parâmetros do módulo de nn.Module em PyTorch adotaram uma estratégia de inicialização mais razoável (consulte o código-fonte para o método de inicialização específico amostrado por diferentes tipos de camadas). Mas muitas vezes é necessário usar outros métodos para inicializar os pesos. O módulo init do PyTorch oferece uma variedade de métodos de inicialização predefinidos.
#将权重参数初始化成均值为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. Redução de dimensionalidade
# numpy中的ravel()、flatten()、squeeze()
# 都有将多维数组转换为一维数组的功能,区别:
# ravel():如果没有必要,不会产生源数据的副本
# flatten():返回源数据的副本
# squeeze():只能对维数为1的维度降维
9. Escolha () em numpy
a1 = np.random.choice(a=5, size=3, replace=False, p=None)
# 参数意思分别 是从a 中以概率P,随机选择3个, p没有指定的时候相当于是一致的分布
# replacement 代表的意思是抽样之后还放不放回去,如果是False的话,那么出来的三个数都不一样,如果是
# True的话, 有可能会出现重复的,因为前面的抽的放回去了