• PyTorch搭建卷积神经网络(ResNet-50网络)进行图像分类实战(附源码和数据集)


    需要数据集和源码请点赞关注收藏后评论区留言~~~

    一、实验数据准备

    我们使用的是MIT67数据集,这是一个标准的室内场景检测数据集,一个有67个室内场景,每类包括80张训练图片和20张测试图片 读者可通过以下网址下载

    但是数据集较大,下载花费时间较长,所以建议私信我发给你们

    数据集

    将下载的数据集解压,主要使用Image文件夹,这个文件夹一共包含6700张图片,还有它们标签的txt文件

    大体流程分为以下几步

    二、数据预处理和准备

    1:数据集的读取

    2:重载data.Dataset类

    3:transforms数据预处理

    三、模型构建

    1:ResNet-50网络

    网络结构图如下

    2:bottleneck的实现

    结构图如下

     

    3:ResNet-50卷积层定义

    4:forward函数的实现

    5:预训练参数装载

    四、模型训练与结果评估

    1:训练类的实现

    2:优化器的定义

    3:学习率衰减

    4:训练

    训练过程如下

     最后 部分代码如下

    1.py

    1. import torch
    2. from torch.autograd import Variable as V
    3. import torchvision.models as models
    4. from torchvision import transforms as trn
    5. from torch.nn import functional as F
    6. import os
    7. import numpy as np
    8. from mymodels import *
    9. from PIL import Image
    10. import torch.utils.data as data
    11. from torch.utils.data import DataLoader
    12. from utils import *
    13. tmp_dir = '/home/yyh/tmpmit67'
    14. import torch.optim as optim
    15. import matplotlib.pyplot as plt
    16. import time
    17. import json
    18. def get_im_list(im_dir, file_path):
    19. im_list = []
    20. im_labels = []
    21. im_origin = []
    22. with open(file_path, 'r') as fi:
    23. for line in fi:
    24. im_list.append(im_dir + line.split()[0])
    25. im_labels.append(int(line.split()[-1]))
    26. im_origin.append(line.split()[0])
    27. array = line.split('/')
    28. return im_list, im_labels, im_origin
    29. ate(fi):
    30. sname = line.strip()
    31. sdict[sid] = sname
    32. return sdict
    33. _sdict = sun397_sdict()
    34. arch = 'resnet50'
    35. # load the pre-trained weights
    36. model_file = '%s_places365.pth.tar' % arch
    37. if not os.access(model_file, os.W_OK):
    38. weight_url = 'http://places2.csail.mit.edu/models_places365/' + model_file
    39. os.system('wget ' + weight_url)
    40. model = resnet50(num_classes=365)
    41. checkpoint = torch.load(model_file, map_location=lambda storage, loc: storage)
    42. state_dict = {str.replace(k,'module.',''): v for k,v in checkpoint['state_dict'].items()}
    43. model.load_state_dict(state_dict)
    44. model.fc = torch.nn.Linear(2048,67)
    45. model.eval()
    46. """
    47. model = resnet50(num_classes=67)
    48. pretrained = torch.load("/home/yyh/fineTune/mit67_place/model_epoch_30.pth").module
    49. state_dict = pretrained.state_dict()
    50. model.load_state_dict(state_dict)
    51. model.eval()
    52. """
    53. # load the image transformer
    54. transform_train = trn.Compose([
    55. trn.Scale(256),
    56. trn.RandomSizedCrop(224),
    57. trn.RandomHorizontalFlip(),
    58. trn.ToTensor(),
    59. trn.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    60. ])
    61. transform_test = trn.Compose([
    62. trn.Scale(256),
    63. trn.CenterCrop(224),
    64. trn.ToTensor(),
    65. trn.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    66. ])
    67. # load the class label
    68. def default_loader(path):
    69. return Image.open(path).convert('RGB')
    70. class MyDataset(data.Dataset):
    71. def __init__(self, images, labels,loader=default_loader,transform=None):
    72. self.images = images
    73. self.labels = labels
    74. self.loader = loader
    75. self.transform = transform
    76. def __getitem__(self, index):
    77. img, target = self.images[index], self.labels[index]
    78. #print(img)
    79. img = self.loader(img)
    80. if self.transform is not None:
    81. img = self.transform(img)
    82. #print(img)
    83. return img, target
    84. def __len__(self):
    85. return len(self.images)
    86. imdir = r'C:\Users\Admin\Desktop\MIT67\Images/'
    87. train_file = 'C:\Users\Admin\Desktop\MIT67\TrainImages.label'
    88. test_file = 'C:\Users\Admin\Desktop\MIT67\TestImages.label'
    89. #train_file = test_file
    90. train_list, train_labels,img_path= get_im_list(imdir, train_file)
    91. test_list, test_labels ,img_path_2= get_im_list(imdir, test_file)
    92. batch_size = 16
    93. net = model
    94. net.cuda()
    95. #print(test_js)
    96. for i in range(0, len(train_list)):
    97. path = img_path[i]
    98. save = []
    99. print(path)
    100. json_name = (path.replace("/", "_")).replace(".jpg", ".json")
    101. f_train = open("C:\Users\Admin\Desktop\rgbd_data\annotated_area/" + json_name)
    102. train_js = json.load(f_train)
    103. if len(train_js) == 0:
    104. train_js.append( {"classname":"unknown","bbox":[0,0,223,223],"score":1})
    105. for j in range(0, len(train_js)):
    106. data, target = train_list[i], train_labels[i]
    107. data = Image.open(data).convert('RGB')
    108. json_data = train_js[j]["bbox"]
    109. data = data.resize((224, 224), Image.ANTIALIAS)
    110. print(json_data)
    111. data = data.crop([json_data[0], json_data[1], json_data[2], json_data[3]])
    112. data = data.resize((224, 224), Image.ANTIALIAS)
    113. data = transform_test(data)
    114. newdata = torch.zeros(1, 3, 224, 224)
    115. newdata[0] = data
    116. data = Variable(newdata).cuda()
    117. output, record = net(data)
    118. data = record.cpu().detach().numpy()
    119. save.append(data)
    120. data = save[0]
    121. for j in range(1, len(train_js)):
    122. data += save[j]
    123. data = data / len(train_js)
    124. # print(data)
    125. # target = Variable(target).cuda()
    126. # print(output)
    127. # print(output["avgpool"].cpu().shape)
    128. root = "/home/yyh/PycharmProjects/feature_extractor/loc_224_npy/" + path.split("/")[0]
    129. if not os.path.exists(root):
    130. os.makedirs(root)
    131. dir = "/home/yyh/PycharmProjects/feature_extractor/loc_224_npy/" + path.replace(".jpg",".npy")
    132. np.save(dir, data)
    133. print(i)
    134. for i in range(0, len(test_list)):
    135. path = img_path_2[i]
    136. save = []
    137. print(path)
    138. json_name = (path.replace("/", "_")).replace(".jpg", ".json")
    139. f_test = open("/home/yyh/rgbd_data/annotated_area/" + json_name)
    140. test_js = json.load(f_test)
    141. if len(test_js) == 0:
    142. test_js.append( {"classname":"unknown","bbox":[0,0,223,223],"score":1})
    143. for j in range(0, len(test_js)):
    144. data, target = test_list[i], test_labels[i]
    145. data = Image.open(data).convert('RGB')
    146. json_data = test_js[j]["bbox"]
    147. data = data.resize((224, 224), Image.ANTIALIAS)
    148. print(json_data)
    149. data = data.crop([json_data[0], json_data[1], json_data[2], json_data[3]])
    150. data = data.resize((224, 224), Image.ANTIALIAS)
    151. data = transform_test(data)
    152. newdata = torch.zeros(1, 3, 224, 224)
    153. tach().numpy()
    154. save.append(data)
    155. data = save[0]
    156. for j in range(1, len(test_js)):
    157. data += save[j]
    158. data = data / len(test_js)
    159. print(data)
    160. root = "/home/yyh/PycharmProjects/feature_extractor/loc_224_npy/" + path.split("/")[0]
    161. if not os.path.exists(root):
    162. os.makedirs(root)
    163. dir = "/home/yyh/PycharmProjects/feature_extractor/loc_224_npy/" + path.replace(".jpg",".npy")
    164. np.save(dir, data)
    165. print(i)
    166. #time.sleep(10)
    167. #print(net)
    168. #train_net = torch.nn.DataParallel(net, device_ids=[0])
    169. #optimizer = optim.SGD(params=train_net.parameters(), lr=0.001, momentum=0.9, weight_decay=1e-4)
    170. #scheduler = StepLR(optimizer, 30, gamma=0.1)
    171. #trainer = Trainer(train_net, optimizer, F.cross_entropy, save_dir="./mit67_imagenet_448")
    172. #trainer.loop(130, train_loader, test_loader, scheduler)

    2.py

    1. from pathlib import Path
    2. import torch
    3. from torch.autograd import Variable
    4. from torch.optim import Optimizer
    5. from torch import nn
    6. from tqdm import tqdm
    7. import torch.nn.functional as F
    8. expansion = 4
    9. def __init__(self, inplanes, planes, stride=1, downsample=None):
    10. super(Bottleneck, self).__init__()
    11. self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=1, bias=False)
    12. self.bn1 = nn.BatchNorm2d(planes)
    13. self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=stride,
    14. padding=1, bias=False)
    15. self.bn2 = nn.BatchNorm2d(planes)
    16. self.conv3 = nn.Conv2d(planes, planes * self.expansion, kernel_size=1, bias=False)
    17. self.bn3 = nn.BatchNorm2d(planes * self.expansion)
    18. self.relu = nn.ReLU(inplace=True)
    19. self.downsample = downsample
    20. self.stride = stride
    21. def forward(self, x):
    22. residual = x
    23. out = self.conv1(x)
    24. out = self.bn1(out)
    25. out = self.relu(out)
    26. out = self.conv2(out)
    27. out = self.bn self.conv3(out)
    28. out = self.bn3(out)
    29. if self.downsample is not None:
    30. residual = self.downsample(x)
    31. out += residual
    32. out = self.relu(out)
    33. return out
    34. def __init__(self, block, layers, num_classes=1000):
    35. self.inplanes = 64
    36. super(ResNet, self).__init__()
    37. self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3,
    38. bias=False)
    39. self.bn1 = nn.BatchNorm2d(64)
    40. self.relu = nn.ReLU(inplace=True)
    41. self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
    42. self.layer1 = self._make_layer(block, 64, layers[0])
    43. self.layer2 = self._make_layer(block, 128, layers[1], stride=2)
    44. self.layer3 = self._make_layer(block, 256, layers[2], stride=2)
    45. self.layer4 = self._make_layer(block, 512, layers[3], stride=2)
    46. self.avgpool = nn.AvgPool2d(kernel_size=7, stride=1, padding=0)
    47. self.fc = nn.Linear(512 * block.expansion, num_classes)
    48. for m in self.modules():
    49. if isinstance(m, nn.Conv2d):
    50. nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
    51. elif isant_(m.weight, 1)
    52. nn.init.constant_(m.bias, 0)
    53. def _make_layer(self, block, planes, blocks, stride=1):
    54. downsample = None
    55. if stride != 1 or self.inplanes != planes * block.expansion:
    56. downsample = nn.Sequential(
    57. nn.Conv2d(self.inplanes, planes * block.expansion,
    58. kernel_size=1, stride=stride, bias=False),
    59. nn.BatchNorm2d(planes * block.expansion),
    60. )
    61. layers = []
    62. layers.append(block(self.inplanes, planes, stride, downsample))
    63. self.inplanes = planes * block.expansion
    64. for i in range(1, blocks):
    65. layers.append(block(self.inplanes, planes))
    66. return nn.Sequential(*layers)
    67. def forward(self, x):
    68. record = dict()
    69. x = self.conv1(x)
    70. x = self.bn1(x)
    71. x = self.relu(x)
    72. record["maxpool"] = x
    73. x = self.maxpool(x)
    74. x = self.layer1(x)
    75. record["layer1"] = x
    76. x = self.layer2(x)
    77. record["layer2"] = x
    78. x = self.layer3(x)
    79. record["layer3"] = x
    80. x = self.layer4(x)
    81. record["layer4"] = x
    82. x = selpool"] = x
    83. x = self.fc(x)
    84. return x,record["avgpool"]
    85. def rined=False, **kwargs):
    86. """Constructs a ResNet-50 model.
    87. Args:
    88. pretrained (bool): If True, returns a model pre-trained on ImageNet
    89. """
    90. model = ResNet(Bottleneck, [3, 4, 6, 3], **kwargs)
    91. return model

    3.py

    1. from pathlib import Path
    2. import torch
    3. from torch.autograd import Variable
    4. from torch.optim import Optimizer
    5. from torch import nn
    6. from tqdm import tqdm
    7. a.is_available()
    8. torch.backends.cudnn.benchmark = True
    9. def __init__(self, model, optimizer, loss_f, save_dir=None, save_freq=10):
    10. self.model = model
    11. if self.cuda:
    12. model.cuda()
    13. self.optimizer = optimizer
    14. self= save_dir
    15. self.save_freq = save_freq
    16. def _iteration(self, data_loader, is_train=True):
    17. loop_loss = []
    18. accuracy = []
    19. for data, target in tqdm(data_loader, ncols=80):
    20. if self.cuda:
    21. data, target = data.cuda(), target.cuda()
    22. output = self.model(data)
    23. loss = self.loss_f(output, target)
    24. loop_loss.append(loss.data.item() / len(data_loader))
    25. accuracy.append((output.data.max(1)[1] == target.data).sum().item())
    26. if is_train:
    27. self.optimizer.zero_grad()
    28. loss.backward()
    29. self.optimizer.step()
    30. mode = "train" if is_train else "test"
    31. #print(">>>[{}] loss: {:.2f}/accuracy: {:.2%}").format(mode,sum(loop_loss),float(sum(accuracy)) / float(len(data_loader.dataset)))
    32. print(mode)
    33. print(sum(loop_loss))
    34. print(float(sum(accuracy)) / float(len(data_loader.dataset)))
    35. return loop_loss, accuracy
    36. def train(self, data_loader):
    37. self.model.train()
    38. with torch.enable_grad():
    39. loss, correct = self._iteration(data_loader)
    40. def test(self, data_loader):
    41. self.model.eval()
    42. with torch.no_grad():
    43. loss, correct = self._iteration(data_loader, is_train=False)
    44. def loop(self, epochs, train_data, test_data, scheduler=None):
    45. for ep in range(1, epochs + 1):
    46. if scheduler is not None:
    47. scheduler.step()
    48. print("epochs: {}".format(ep))
    49. self.train(train_data)
    50. self.test(test_data)
    51. if ep % self.save_freq == 0:
    52. self.save(ep)
    53. def save(self, epoch, **kwargs):
    54. if self.save_dir is not None:
    55. model_out_path = Path(self.save_dir)
    56. state = self.model
    57. if not model_out_path.exists():
    58. model_out_path.mkdir()
    59. print(self.save_dir+ "model_epoch_{}.pth".format(epoch))
    60. torch.save(state, self.save_dir+ "/model_epoch_{}.pth".format(epoch))
    61. class _LRScheduler(object):
    62. def __init__(self, optimizer, last_epoch=-1):
    63. if not isinstance(optimizer, Optimizer):
    64. raise TypeError('{} is not an Optimizer'.format(
    65. type(optimizer).__name__))
    66. self.optimizer = optimizer
    67. if last_epoch == -1:
    68. for group in optimizer.param_groups:
    69. group.setdefault('initial_lr', group['lr'])
    70. else:
    71. for i, group in enumerate(optimizer.param_groups):
    72. if 'initial_lr' not in group:
    73. raise KeyError("param 'initial_lr' is not specified "
    74. "in param_groups[{}] when resuming an optimizer".format(i))
    75. self.base_lrs = list(map(lambda group: group['initial_lr'], optimizer.param_groups))
    76. self.step(last_epoch + 1)
    77. self.last_epoch = last_epoch
    78. def get_lr(self):
    79. raise NotImplementedError
    80. def step(self, epoch=None):
    81. if epoch is None:
    82. tep_size, gamma=0.1, last_epoch=-1):
    83. self.step_size = step_size
    84. self.gamma = gamma
    85. super(StepLR, self).__init__(optimizer, last_epoch)
    86. def get_lr(self):
    87. return [base_lr * self.gamma ** (self.last_epoch // self.step_size)
    88. for base_lr in self.base_lrs]

    创作不易 觉得有帮助请点赞关注收藏~~~

  • 相关阅读:
    Oracle 的LogMiner
    IDC TechScape中国数据安全发展路线图,美创两款产品获重点推荐
    MySQL数据库下载与安装使用
    校园快餐店网上订餐管理系统(JSP+MySQL+MyEclipse)
    餐厅预订APP多少钱一套?餐厅预订APP如何收费?
    计数与期望
    Shell 初始化配置指北 | Ubuntu
    VL3 奇偶校验
    基于java+ssm+easyui灵悟酒店系统
    基于图的路径搜索技术基础知识
  • 原文地址:https://blog.csdn.net/jiebaoshayebuhui/article/details/127797383