• 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]

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

  • 相关阅读:
    MobaXterm两种方式上传下载文件
    C++Primer 第一章 开始
    Dart(3)-常量
    特征工程/数据预处理超全面总结(持续更新ing...)
    【解决】多卡服务器GPU不能多用户同时使用的问题
    javaee实验,SpringMVC 参数绑定
    微信小程序登录获取不到头像和昵称解决办法!
    cookie时效无限延长方案
    C#程序随系统启动例子 - 开源研究系列文章
    【数据分享】深圳市出租车GPS数据
  • 原文地址:https://blog.csdn.net/jiebaoshayebuhui/article/details/127797383