P6打卡—Pytorch实现人脸识别

1.检查GPU

import torch
import torch.nn as nn
import matplotlib.pyplot as plt
import torchvision

device=torch.device("cuda" if torch.cuda.is_available() else "cpu")
device

2.查看数据

import os,PIL,random,pathlib
data_dir = pathlib.Path('data/48-data')
data_dir=pathlib.Path(data_dir)
data_path=list(data_dir.glob("*"))
ClassNames=[str(path).split('\\')[2] for path in data_path]
ClassNames

​​​​​

3.划分数据集

train_trainsforms=transforms.Compose([
    transforms.Resize([224,224]),
    transforms.ToTensor(),
    transforms.Normalize(
        mean=[0.486,0.456,0.406],
        std=[0.229,0.224,0.225]
    )
]
)
total_data=datasets.ImageFolder("data/48-data",transform=train_trainsforms)
total_data

total_data.class_to_idx

train_size=int(0.8*len(total_data))
test_size=len(total_data)-train_size
train_dataset,test_dataset=torch.utils.data.random_split(total_data,(train_size,test_size))
train_dataset,test_dataset

batch_size=32
train_dl=torch.utils.data.DataLoader(train_dataset,batch_size,shuffle=True,num_workers=1)
test_dl=torch.utils.data.DataLoader(test_dataset,batch_size,shuffle=True,num_workers=1)

for X,y in train_dl:
    print(X.shape)
    print(y.shape)
    break

​​

4.调用官方模型

from torchvision.models import vgg16
print("Using {} device".format(device))
model=vgg16(pretrained=True).to(device)
for param in model.parameters():
    param.requires_grad=False
model.classifier._modules['6']=nn.Linear(4096,len(ClassNames))
model.to(device)
model

​​​

5.动态调整学习率函数

#调用官方动态学习率接口
learning_rate = 1e-4
lambda1=lambda epoch:0.92**(epoch//4)
optimizer=torch.optim.SGD(model.parameters(),lr=learning_rate)
scheduler=torch.optim.lr_scheduler.LambdaLR(optimizer,lr_lambda=lambda1)

6.编译及训练模型

def train(dataloader,model,loss_fn,optimizer):
    size=len(dataloader.dataset)
    num_batches=len(dataloader)
    train_loss,train_acc=0,0
    for X,y in dataloader:
        X,y =X.to(device),y.to(device)
        pred=model(X)
        loss=loss_fn(pred,y)
        #反向传播
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        
        train_loss+=loss.item()
        train_acc+=(pred.argmax(1)==y).type(torch.float).sum().item()
    train_acc/=size
    train_loss/=num_batches
    return train_acc,train_loss

def test(dataloader,model,loss_fn):
    size=len(dataloader.dataset)
    num_batches=len(dataloader)
    test_loss,test_acc=0,0
    with torch.no_grad():
        for imgs,target in dataloader:
            imgs,target=imgs.to(device),target.to(device)
            target_pred=model(imgs)
            loss=loss_fn(target_pred,target)
            test_loss+=loss.item()
            test_acc+=(target_pred.argmax(1)==target).type(torch.float).sum().item()
    test_acc/=size
    test_loss/=num_batches
    return test_acc,test_loss

import copy
loss_fn=nn.CrossEntropyLoss()
epochs=40
train_loss=[]
train_acc=[]
test_loss=[]
test_acc=[]
best_acc=0
for epoch in range(epochs):
    model.train()
    epoch_train_acc,epoch_train_loss=train(train_dl,model,loss_fn,optimizer)
    #更新学习率
    scheduler.step()
    model.eval()
    epoch_test_acc,epoch_test_loss=test(test_dl,model,loss_fn)

    if epoch_test_acc>=best_acc:
        best_acc=epoch_test_acc
        best_model=copy.deepcopy(model)
    train_acc.append(epoch_train_acc)
    train_loss.append(epoch_train_loss)
    test_acc.append(epoch_test_acc)
    test_loss.append(epoch_test_loss)
    lr=optimizer.state_dict()['param_groups'][0]['lr']
    template = ('Epoch:{:2d}, Train_acc:{:.1f}%, Train_loss:{:.3f}, Test_acc:{:.1f}%, Test_loss:{:.3f}, Lr:{:.2E}')
    print(template.format(epoch+1, epoch_train_acc*100, epoch_train_loss, 
                          epoch_test_acc*100, epoch_test_loss, lr))
PATH='./best_model.pth'
torch.save(best_model.state_dict(),PATH)
print('Finished Training')

​​​​​​

7.结果可视化

import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings("ignore")
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
plt.rcParams['figure.dpi']=100

epochs_range = range(epochs)

plt.figure(figsize=(12, 3))
plt.subplot(1, 2, 1)
plt.plot(epochs_range, train_acc, label='Training Accuracy')
plt.plot(epochs_range, test_acc, label='Test Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')

plt.subplot(1, 2, 2)
plt.plot(epochs_range, train_loss, label='Training Loss')
plt.plot(epochs_range, test_loss, label='Test Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()

​​

8.预测本地图片

from PIL import Image
classes=list(total_data.class_to_idx)
def predict_one_image(image_path,model,transform,classes):
    test_img=Image.open(image_path).convert('RGB')
    plt.imshow(test_img)
    test_img=transform(test_img)
    img=test_img.to(device).unsqueeze(0)
    model=model.eval()
    output=model(img)
    _,pred=torch.max(output,1)
    pred_class=classes[pred]
    print('预测结果是:{pred_class}')

predict_one_image(image_path='data/48-data/Angelina Jolie/005_582c121a.jpg',
                  model=model,
                  transform=train_trainsforms,
                  classes=classes)
#查看最优损失及准确率
best_model.eval()
epoch_test_Acc,epoch_test_loss=test(test_dl,best_model,loss_fn)
epoch_test_Acc,epoch_test_loss

​​

​​总结:

1.VGG-16

VGG-16(Visual Geometry Group-16)是由牛津大学视觉几何组(Visual Geometry Group)提出的一种深度卷积神经网络架构,用于图像分类和对象识别任务。VGG-16在2014年被提出,是VGG系列中的一种。VGG-16之所以备受关注,是因为它在ImageNet图像识别竞赛中取得了很好的成绩,展示了其在大规模图像识别任务中的有效性。

以下是VGG-16的主要特点:

  1. **深度:**VGG-16由16个卷积层和3个全连接层组成,因此具有相对较深的网络结构。这种深度有助于网络学习到更加抽象和复杂的特征。
  2. 卷积层的设计: VGG-16的卷积层全部采用3x3的卷积核和步长为1的卷积操作,同时在卷积层之后都接有ReLU激活函数。这种设计的好处在于,通过堆叠多个较小的卷积核,可以提高网络的非线性建模能力,同时减少了参数数量,从而降低了过拟合的风险。
  3. **池化层:**在卷积层之后,VGG-16使用最大池化层来减少特征图的空间尺寸,帮助提取更加显著的特征并减少计算量。
  4. **全连接层:**VGG-16在卷积层之后接有3个全连接层,最后一个全连接层输出与类别数相对应的向量,用于进行分类。

VGG-16结构说明:

  • 13个卷积层(Convolutional Layer),分别用blockX_convX表示;
  • 3个全连接层(Fully connected Layer),用classifier表示;
  • 5个池化层(Pool layer)。

VGG-16****包含了16个隐藏层(13个卷积层和3个全连接层),故称为 VGG-16

2.设置动态学习率

#非官方设置动态学习率
def adjust_learning_rate(optimizer, epoch, start_lr):
     # 每 2 个epoch衰减到原来的 0.98
     lr = start_lr * (0.92 ** (epoch // 2))
     for param_group in optimizer.param_groups:
         param_group['lr'] = lr

learn_rate = 1e-4 # 初始学习率
optimizer  = torch.optim.SGD(model.parameters(), lr=learn_rate)

#官方设置动态学习率
# 调用官方动态学习率接口时使用
lambda1 = lambda epoch: 0.92 ** (epoch // 4)
optimizer = torch.optim.SGD(model.parameters(), lr=learn_rate)
scheduler = torch.optim.lr_scheduler.LambdaLR(optimizer, lr_lambda=lambda1) #选定调整方法

model = [torch.nn.Parameter(torch.randn(2, 2, requires_grad=True))]
optimizer = SGD(model, 0.1)
scheduler = ExponentialLR(optimizer, gamma=0.9)

for epoch in range(20):
    for input, target in dataset:
        optimizer.zero_grad()
        output = model(input)
        loss = loss_fn(output, target)
        loss.backward()
        optimizer.step()
    scheduler.step()
相关推荐
Srlua7 分钟前
辅助任务改进社交帖子多模态分类
人工智能·python
兔子的洋葱圈8 分钟前
Python的3D可视化库【vedo】2-5 (plotter模块) 坐标转换、场景导出、添加控件
python·3d·数据可视化
drebander15 分钟前
基于 Python 将 PDF 转 Markdown 并拆解为 JSON,支持自定义标题处理
python·pdf·json
L_cl26 分钟前
【NLP 15、深度学习处理文本】
人工智能·深度学习
2401_871151071 小时前
十二月第14讲:使用Python实现两组数据纵向排序
开发语言·python·算法
知新_ROL1 小时前
通过解调使用正则化相位跟踪技术进行相位解包裹
人工智能·算法·机器学习
一位小说男主1 小时前
可解释性方法:从理论到实践的深度剖析(续上文)
人工智能·深度学习·机器学习
Cachel wood1 小时前
Vue.js前端框架教程5:Vue数据拷贝和数组函数
linux·前端·vue.js·python·阿里云·前端框架·云计算
martian6651 小时前
深入详解神经网络基础知识——理解前馈神经网络( FNN)、卷积神经网络(CNN)和循环神经网络(RNN)等概念及应用
人工智能·深度学习·神经网络
程序猿人大林1 小时前
C# opencvsharp 流程化-脚本化-(2)ROI
人工智能·计算机视觉·c#