赞
踩
之前是使用了mnist数据,且网络结构比较简单,针对自己的数据,如何使用更复杂、经典的网络呢?
目标是人脸识别,可以看做一个多分类问题,本次实验的数据集为ferest,共200个人,1400张3*80*80图片,比较小。
分为 train 和 val两个目录,每个目录下都有200个子目录。
资源可下载
https://download.csdn.net/download/sinat_37787331/10383836
注意:训练和测试的目录名字和数量必须保持一致,子目录内可以没有图片。
附批量删除、批量改格式的代码
#!/usr/bin/python # -*- coding: utf-8 -*- import os def del_files(path): for root , dirs, files in os.walk(path): for name in files: if name.endswith(".png"): os.remove(os.path.join(root, name)) print ("Delete File: " + os.path.join(root, name)) # test if __name__ == "__main__": path = '/home/syj/Documents/datas/2' del_files(path) ''' gai hou zhui #!/usr/bin/python # -*- coding: utf-8 -*- import os def model_extentsion(path,before_ext,ext): for name in os.listdir(path): full_path=os.path.join(path,name) if os.path.isfile(full_path): split_path=os.path.splitext(full_path) pwd_name=split_path[0] pwd_ext=split_path[1] before_ext1="."+before_ext if pwd_ext == before_ext1: ext1="."+ext pwd_name+=ext1 re_name=os.path.join(path,pwd_name) os.renames(full_path, re_name) else: model_extentsion(full_path,before_ext,ext) model_extentsion("/home/syj/Documents/datas/Feret/train",'tif', "png") '''
这次加载的是自己的数据,大体分为两种
第一种:图片文件夹+txt文档
可借鉴 http://www.bubuko.com/infodetail-2304938.html
第二种:训练集和测试集分开,且每一类文件都放在同一子目录下。本文采用这种方法
# 数据人脸 train_data = torchvision.datasets.ImageFolder('/home/syj/Documents/datas/Feret/train', transform=transforms.Compose([ transforms.Resize(28), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ])) # 批训练 50samples, 1 channel, 28x28 (50, 1, 28, 28) train_loader = Data.DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True) test_data = torchvision.datasets.ImageFolder('/home/syj/Documents/datas/Feret/val', transform=transforms.Compose([ transforms.Resize(28), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ])) test_loader = Data.DataLoader(dataset=test_data, batch_size=20, shuffle=True) ‘’‘ data_transforms = { 'train': transforms.Compose([ transforms.RandomResizedCrop(224), transforms.RandomHorizontalFlip(), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]), 'val': transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), ##224*224为resnet18输入图片尺寸 transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]), #归一化 } ’‘’
主要是通过 torchvision.datasets.ImageFolder 这个函数实现的,很方便
具体的归一化等操作介绍可以参考 https://blog.csdn.net/Hungryof/article/details/76649006
官方提供了许多经典的模型,如alnex,vgg,resnet,并且有训练过的参数,可以用来迁移学习
- # model_ft = models.resnet18(pretrained=True)
- # num_ftrs = model_ft.fc.in_features
- # model_ft.fc = nn.Linear(num_ftrs, 200)
三行代码就搭建好了网络,会自动下载resnet18,只是把最后一层fc层由1000(Imaginenet)改为200就行了
有两种方法,一种只保存参数,一种全保存,后者简单但存储量大,我用的是后者
- model_ft = torch.load('/home/syj/Documents/model/resnet18_0.003.pkl')
-
- #torch.save(model_ft, '/home/syj/Documents/model/resnet18_0.003.pkl')
我跑了9个epoch,200类的acc在72%左右,接近理论,花了4分钟(gt940m)
可以参考 http://www.cnblogs.com/denny402/p/7520063.html
6.完整代码
from __future__ import print_function, division import torch import torch.nn as nn import torch.optim as optim from torch.optim import lr_scheduler from torch.autograd import Variable import torchvision from torchvision import datasets, models, transforms import time import os import matplotlib as mpl import matplotlib.pyplot as plt def train_model(model, criterion, optimizer, scheduler, num_epochs=1): since = time.time() best_model_wts = model.state_dict() best_acc = 0.0 for epoch in range(num_epochs): print('Epoch {}/{}'.format(epoch, num_epochs - 1)) print('-' * 10) # Each epoch has a training and validation phase for phase in ['train', 'val']: if phase == 'train': scheduler.step() model.train(True) # Set model to training mode else: model.train(False) # Set model to evaluate mode running_loss = 0.0 running_corrects = 0 # Iterate over data. for data in dataloders[phase]: # get the inputs inputs, labels = data # wrap them in Variable if use_gpu: inputs = Variable(inputs.cuda()) labels = Variable(labels.cuda()) else: inputs, labels = Variable(inputs), Variable(labels) # zero the parameter gradients optimizer.zero_grad() # forward outputs = model(inputs) _, preds = torch.max(outputs.data, 1) loss = criterion(outputs, labels) # backward + optimize only if in training phase if phase == 'train': loss.backward() optimizer.step() # statistics running_loss += loss.data[0] running_corrects += torch.sum(preds == labels.data) if phase == 'train': train_loss.append(loss.data[0] / 15) train_acc.append(torch.sum(preds == labels.data) / 15) else: test_loss.append(loss.data[0] / 15) test_acc.append(torch.sum(preds == labels.data) / 15) epoch_loss = running_loss / dataset_sizes[phase] epoch_acc = running_corrects / dataset_sizes[phase] print('{} Loss {:.4f} Acc: {:.4f}'.format( phase, epoch_loss, epoch_acc)) # deep copy the model if phase == 'val' and epoch_acc > best_acc: best_acc = epoch_acc best_model_wts = model.state_dict() time_elapsed = time.time() - since print('Training complete in {:.0f}m {:.0f}s'.format( time_elapsed // 60, time_elapsed % 60)) print('Best val Acc: {:4f}'.format(best_acc)) # load best model weights model.load_state_dict(best_model_wts) return model if __name__ == '__main__': # data_transform, pay attention that the input of Normalize() is Tensor and the input of RandomResizedCrop() or RandomHorizontalFlip() is PIL Image data_transforms = { 'train': transforms.Compose([ transforms.RandomResizedCrop(224), transforms.RandomHorizontalFlip(), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]), 'val': transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]), } # your image data file data_dir = '/home/syj/Documents/datas/Feret' image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x), data_transforms[x]) for x in ['train', 'val']} # wrap your data and label into Tensor dataloders = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=10, shuffle=True, num_workers=10) for x in ['train', 'val']} dataset_sizes = {x: len(image_datasets[x]) for x in ['train', 'val']} # use gpu or not use_gpu = torch.cuda.is_available() # get model and replace the original fc layer with your fc layer # model_ft = models.resnet18(pretrained=True) # num_ftrs = model_ft.fc.in_features # model_ft.fc = nn.Linear(num_ftrs, 200) model_ft = torch.load('/home/syj/Documents/model/resnet18_0.003.pkl') ##paint train_loss = [] train_acc = [] test_loss = [] test_acc = [] if use_gpu: model_ft = model_ft.cuda() # define loss function criterion = nn.CrossEntropyLoss() # Observe that all parameters are being optimized optimizer_ft = optim.SGD(model_ft.parameters(), lr=0.01, momentum=0.9) # Decay LR by a factor of 0.1 every 7 epochs exp_lr_scheduler = lr_scheduler.StepLR(optimizer_ft, step_size=7, gamma=0.1) model_ft = train_model(model=model_ft, criterion=criterion, optimizer=optimizer_ft, scheduler=exp_lr_scheduler, num_epochs=2) #torch.save(model_ft, '/home/syj/Documents/model/resnet18_0.003.pkl') ''' ##paint plt.figure() plt.subplot(2, 2, 1) plt.plot(train_loss, lw = 1.5, label = 'train_loss') plt.subplot(2, 2, 2) plt.plot(train_acc, lw = 1.5, label = 'train_acc') plt.subplot(2, 2, 3) plt.plot(test_loss, lw = 1.5,label = 'loss') plt.subplot(2, 2, 4) plt.plot(test_acc, lw = 1.5, label = 'acc') plt.savefig("resnet18_0.01-10.jpg") plt.show() print(dataset_sizes) ''' ''' https://blog.csdn.net/u014380165/article/details/78525273 ---------- train Loss: 0.1916 Acc: 0.8083 val Loss: 0.0262 Acc: 0.9778 Epoch 24/24 ---------- train Loss: 0.2031 Acc: 0.8250 val Loss: 0.0269 Acc: 1.0000 Training complete in 4m 19s Best val Acc: 1.000000 ''' ''' lr=0.003 Epoch 9/9 ---------- train Loss: 0.1358 Acc: 0.6710 val Loss: 0.1135 Acc: 0.6575 Training complete in 9m 43s Best val Acc: 0.657500 ''' ''' lr=0.01 15 Epoch 9/9 ---------- train Loss: 0.0415 Acc: 0.8530 val Loss: 0.0802 Acc: 0.7225 Training complete in 10m 6s Best val Acc: 0.722500 ''' ''' 0.01 10 Epoch 38/39 ---------- train Loss: 0.0509 Acc: 0.8640 val Loss: 0.1262 Acc: 0.7325 Epoch 39/39 ---------- train Loss: 0.0508 Acc: 0.8520 val Loss: 0.1396 Acc: 0.7200 Training complete in 4m 13s Best val Acc: 0.737500 '''
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。