首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

pytorch知识一tensor数据声明、类型转换。微调rensnet34的注意点。

  • 25-03-03 22:41
  • 4713
  • 9877
blog.csdn.net

1、tensor类型的数据声明:

A、

  1. import torch
  2. import numpy as np
  3. from torch.autograd import Variable
  4. running_corrects = 0.0
  5. # 声明一个单一变量3,Tensor默认的tensor类型是(torch.FloaTensor)的简称
  6. a=torch.Tensor([3])
  7. aa=torch.Tensor(0)
  8. # 其中tensor默认生成的数据类型是int64位的
  9. aaa=torch.tensor([3])
  10. aaaa=torch.tensor(0)
  11. print(a.dtype)
  12. print(aa.dtype)
  13. print(aaa.dtype)
  14. print(aaaa.dtype)
  15. print(aaa)
  16. print(aaaa)
  17. b=torch.Tensor([3])
  18. # 声明一个2*3的矩阵数据
  19. numpy_tensor=np.random.randn(2,3)
  20. c=torch.Tensor(numpy_tensor)
  21. print(c)
  22. # 进行数据的第二维度求和,此时sum返回的是跟数据一样的浮点型数据
  23. testarray=torch.sum(c,1)
  24. print(testarray)
  25. # 此时sum返回的数据是int64为的,此时要使用强制转换进行float类型
  26. running_corrects += torch.sum(a == b).float()
  27. hh = running_corrects / 4.0
  28. print(hh)

其输出结果是:

  1. torch.float32
  2. torch.float32
  3. torch.int64
  4. torch.int64
  5. tensor([3])
  6. tensor(0)
  7. tensor([[-0.2286, 0.7078, -0.9872],
  8. [-0.3574, -0.6509, -0.3000]])
  9. tensor([-0.5080, -1.3083])
  10. tensor(0.2500)

   注意:从上面可以看出torch声明变量的时候使用:Tensor()跟tensor()两个函数声明的得出的数据类型是不一样的,不过其作用倒是一样的,这两者声明的都是CPU的数据类型,所以使用到GPU的使用需要使用(.cuda())来把数据加载到gpu,或者在声明数据的时候就使用gpu tensor类型来声明,其是torch.cuda.FloatTensor()等,具体类型可以看下面解释。

  B、Torch定义的其中CPU tensor类型和八种GPU tensor类型:

参考网站: PyTorch中文文档  

torch.Tensor

torch.Tensor是一种包含单一数据类型元素的多维矩阵。

Torch定义了七种CPU tensor类型和八种GPU tensor类型:

Data tyoeCPU tensorGPU tensor
32-bit floating pointtorch.FloatTensortorch.cuda.FloatTensor
64-bit floating pointtorch.DoubleTensortorch.cuda.DoubleTensor
16-bit floating pointN/Atorch.cuda.HalfTensor
8-bit integer (unsigned)torch.ByteTensortorch.cuda.ByteTensor
8-bit integer (signed)torch.CharTensortorch.cuda.CharTensor
16-bit integer (signed)torch.ShortTensortorch.cuda.ShortTensor
32-bit integer (signed)torch.IntTensortorch.cuda.IntTensor
64-bit integer (signed)torch.LongTensortorch.cuda.LongTensor

torch.Tensor是默认的tensor类型(torch.FlaotTensor)的简称。

一个张量tensor可以从Python的list或序列构建:

  1. >>> torch.FloatTensor([[1, 2, 3], [4, 5, 6]])
  2. 1 2 3
  3. 4 5 6
  4. [torch.FloatTensor of size 2x3]

一个空张量tensor可以通过规定其大小来构建:

  1. >>> torch.IntTensor(2, 4).zero_()
  2. 0 0 0 0
  3. 0 0 0 0
  4. [torch.IntTensor of size 2x4]

可以用python的索引和切片来获取和修改一个张量tensor中的内容:

  1. >>> x = torch.FloatTensor([[1, 2, 3], [4, 5, 6]])
  2. >>> print(x[1][2])
  3. 6.0
  4. >>> x[0][1] = 8
  5. >>> print(x)
  6. 1 8 3
  7. 4 5 6
  8. [torch.FloatTensor of size 2x3]

每一个张量tensor都有一个相应的torch.Storage用来保存其数据。类tensor提供了一个存储的多维的、横向视图,并且定义了在数值运算。

!注意: 会改变tensor的函数操作会用一个下划线后缀来标示。比如,torch.FloatTensor.abs_()会在原地计算绝对值,并返回改变后的tensor,而tensor.FloatTensor.abs()将会在一个新的tensor中计算结果。

  1. class torch.Tensor
  2. class torch.Tensor(*sizes)
  3. class torch.Tensor(size)
  4. class torch.Tensor(sequence)
  5. class torch.Tensor(ndarray)
  6. class torch.Tensor(tensor)
  7. class torch.Tensor(storage)

根据可选择的大小和数据新建一个tensor。 如果没有提供参数,将会返回一个空的零维张量。如果提供了numpy.ndarray,torch.Tensor或torch.Storage,将会返回一个有同样参数的tensor.如果提供了python序列,将会从序列的副本创建一个tensor。

2、下面是微调resnet34的注意点:

其下面是微调训练代码:

  1. from __future__ import print_function, division
  2. import torch
  3. import torch.nn as nn
  4. import torch.optim as optim
  5. from torch.optim import lr_scheduler
  6. from torch.autograd import Variable
  7. import torchvision
  8. from torchvision import datasets, models, transforms
  9. import time
  10. import os
  11. import matplotlib as mpl
  12. import matplotlib.pyplot as plt
  13. model_path='model/madel_state_dict.pt'
  14. def train_model(model, criterion, optimizer, scheduler, num_epochs=1):
  15. since = time.time()
  16. best_model_wts = model.state_dict()
  17. best_acc = 0.0
  18. for epoch in range(num_epochs):
  19. print('Epoch {}/{}'.format(epoch, num_epochs - 1))
  20. print('-' * 10)
  21. # Each epoch has a training and validation phase
  22. for phase in ['train', 'val']:
  23. if phase == 'train':
  24. scheduler.step()
  25. model.train(True) # Set model to training mode
  26. else:
  27. # 设置这个eval()可以让dropout、bn等进入预估状态,而不启用否则启用另一种计算方法。
  28. model.eval() # Set model to evaluate mode
  29. running_loss = 0.0
  30. running_corrects = 0.0
  31. # Iterate over data.
  32. for data in dataloders[phase]:
  33. # get the inputs
  34. inputs, labels = data
  35. # wrap them in Variable
  36. if use_gpu:
  37. inputs = Variable(inputs.cuda())
  38. labels = Variable(labels.cuda())
  39. else:
  40. inputs, labels = Variable(inputs), Variable(labels)
  41. # zero the parameter gradients,这个不会影响网络的验证的
  42. optimizer.zero_grad()
  43. # forward
  44. outputs = model(inputs)
  45. _, preds = torch.max(outputs.data, 1)
  46. # 这个也是不会影响到网络的验证的
  47. loss = criterion(outputs, labels)
  48. # backward + optimize only if in training phase
  49. if phase == 'train':
  50. loss.backward()
  51. optimizer.step()
  52. # statistics这里有个问题的:由于loss单个数值来的,而后面使用running_loss进行求平均值,
  53. #导致损失值很低。所以这里正确的代码是要乘多一个inputs.size(0)
  54. running_loss += loss.data[0]
  55. # 其中这里最坑,其中如果sum里面的是bool类型数据,则其返回的是int64为数据类型
  56. # 这就会导致epoch_acc的准确度一直是0
  57. running_corrects += torch.sum(preds == labels.data).float()
  58. if phase == 'train':
  59. train_loss.append(loss.data[0] / 15)
  60. train_acc.append(torch.sum(preds == labels.data) / 15)
  61. else:
  62. test_loss.append(loss.data[0] / 15)
  63. test_acc.append(torch.sum(preds == labels.data) / 15)
  64. epoch_loss = running_loss / dataset_sizes[phase]
  65. epoch_acc = running_corrects / dataset_sizes[phase]
  66. print('{} Loss {:.4f} Acc: {:.4f}'.format(
  67. phase, epoch_loss, epoch_acc))
  68. # deep copy the model
  69. if phase == 'val' and epoch_acc > best_acc:
  70. best_acc = epoch_acc
  71. best_model_wts = model.state_dict()
  72. torch.save(best_model_wts, model_path)
  73. time_elapsed = time.time() - since
  74. print('Training complete in {:.0f}m {:.0f}s'.format(
  75. time_elapsed // 60, time_elapsed % 60))
  76. print('Best val Acc: {:4f}'.format(best_acc))
  77. # load best model weights更新网络的权重,使用最高准确度的那个
  78. # model.load_state_dict(best_model_wts)
  79. model.load_state_dict(torch.load(model_path))
  80. return model
  81. if __name__ == '__main__':
  82. # data_transform, pay attention that the input of Normalize() is Tensor and the input of RandomResizedCrop() or RandomHorizontalFlip() is PIL Image
  83. data_transforms = {
  84. 'train': transforms.Compose([
  85. transforms.RandomResizedCrop(224),
  86. transforms.RandomHorizontalFlip(),
  87. transforms.ToTensor(),
  88. transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
  89. ]),
  90. 'val': transforms.Compose([
  91. transforms.Resize(256),
  92. transforms.CenterCrop(224),
  93. transforms.ToTensor(),
  94. transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
  95. ]),
  96. }
  97. # your image data file,这个数据很量很重要,每类数据多的话收敛的快
  98. data_dir = 'foodsmall'
  99. image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x),
  100. data_transforms[x]) for x in ['train', 'val']}
  101. # wrap your data and label into Tensor 这里的shuffle一定要开启,否者训练出来的准确度很低
  102. dataloders = {x: torch.utils.data.DataLoader(image_datasets[x],
  103. batch_size=5,
  104. shuffle=True,
  105. num_workers=10) for x in ['train', 'val']}
  106. dataset_sizes = {x: len(image_datasets[x]) for x in ['train', 'val']}
  107. # use gpu or not
  108. use_gpu = torch.cuda.is_available()
  109. # get model and replace the original fc layer with your fc layer
  110. model_ft = models.resnet34(pretrained=True)
  111. num_ftrs = model_ft.fc.in_features
  112. model_ft.fc = nn.Linear(num_ftrs, 7)
  113. # model_ft = torch.load('/home/syj/Documents/model/resnet18_0.003.pkl')
  114. ##paint
  115. train_loss = []
  116. train_acc = []
  117. test_loss = []
  118. test_acc = []
  119. if use_gpu:
  120. model_ft = model_ft.cuda()
  121. # define loss function
  122. criterion = nn.CrossEntropyLoss()
  123. # Observe that all parameters are being optimized,微调全部参数,其开始准确度很低,训练速度很慢
  124. # optimizer_ft = optim.SGD(model_ft.parameters(), lr=0.03, momentum=0.9)
  125. # 微调全连层的参数,其准确度上升的很快,收敛速度很快
  126. optimizer_ft = optim.SGD(model_ft.fc.parameters(), lr=0.03, momentum=0.9)
  127. # 使用Adam训练,准确度上升的更快,收敛速度很快
  128. # optimizer_ft=optim.Adam(model_ft.parameters(),lr=0.03)
  129. # Decay LR by a factor of 0.1 every 7 epochs
  130. exp_lr_scheduler = lr_scheduler.StepLR(optimizer_ft, step_size=7, gamma=0.1)
  131. model_ft = train_model(model=model_ft,
  132. criterion=criterion,
  133. optimizer=optimizer_ft,
  134. scheduler=exp_lr_scheduler,
  135. num_epochs=20)
  136. torch.save(model_ft, '/home/syj/Documents/model/resnet18_0.003.pkl')

其要注意点是:

A、微调的话使用要注意定义optim的时候其参数要使用全连层的参数。如果使用全局的参数的话也可以,不过刚开始准确度会很低,然后慢慢收敛。

B、使用DataLoader()进行加载数据的时候其中shuffle参数一定要设置为True。否则收敛不了或者上升很慢慢。、

C、其中在验证的时候网络一定要设置为:model.eval().使网络进入验证模式,其才会禁用dropout()等功能。

下面是一些使用总结:

  进行全局参数的调整,其需要的epoch比较多。这里的把训练的梯度清零函数跟计算损失的函数都放到test里面,其对预测没有影响。所以一切ok:

使用Fenet进行微调10类每类只有7张人脸的数据。微调最后一层参数,其识别率从很低往上升,收敛的速度也挺快的:

使用Fenet进行微调10类每类只有7张人脸的数据。训练全部参数,其识别率特别低,如果epoch最够大的话其或许是可以上升的,因为其准确度有上升趋势:

使用foodsmall数据集其共有7类,每类数据是7张,其训练全部参数,开始准确度很低,然后就很慢有上升趋势,跟fenet数据集一样。所以其数据集是多通道灰度图使用三通道的网络进行训练是不会影响到网络训练的:

使用foodsmall数据集其共有7类,每类数据是7张,其训练全部参数,开始准确度很低,然后就很慢有上升趋势,跟fenet数据集一样。所以其数据集是多通道灰度图使用三通道的网络进行训练是不会影响到网络训练的使用Adam进行梯度计算:

 

 

 

 

 

 

 

 

 

文章知识点与官方知识档案匹配,可进一步学习相关知识
Python入门技能树人工智能深度学习416686 人正在系统学习中
注:本文转载自blog.csdn.net的yangdeshun888的文章"https://blog.csdn.net/yangdashi888/article/details/84024939"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2491) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top