【卷积神经网络作业实现人脸的关键点定位功能】

下面是完成这道题目的代码:

python 复制代码
import os
import cv2
import numpy as np
import pandas as pd
import torch
import torch.nn as nn
from torch.utils.data import Dataset,DataLoader
from torchvision import transforms
import matplotlib.pyplot as plt
复制代码
1. 数据集定义(匹配你的目录结构)
python 复制代码
class FaceKeypointDataset(Dataset):
    def __init__(self,txt_path,img_dir,transform=None):
        self.df = pd.read_csv(txt_path,sep=r'\s+',header=None,on_bad_lines='skip')
        self.img_dir = img_dir
        self.transform = transform

    def __len__(self):
        return len(self.df)


    def __getitem__(self,idx):
        #读取图片名和路径
        img_name=self.df.iloc[idx,0]
        img_path=os.path.join(self.img_dir,img_name)

        img = cv2.imread(img_path)
        img = cv2.cvtColor(img,cv2,COLOR_BGR2RGB)
        img = cv2.resize(img,(64,64))



        #读取10个关键点坐标

        kpts=self.df.iloc[idx,1:11].values.astype(np.float32)

        #坐标归一化
        kpts[0::2]/=64.0#x坐标
        kpts[1::2]/=64.0#y坐标

        if self.transform:
            img = self.transform(img)

        return img,torch.tensor(kpts,dtype=torch.float32)
复制代码
2. 卷积神经网络模型 
python 复制代码
class KeypointNet(nn.Module):
    def __init__(self):
        super().__init__()
        #卷积层提取特征
        self.conv_layers =nn.Sequential(
            nn.Conv2d(3,16,kernel_size=3,padding=1),
            nn.RELU(),
            nn.MaxPool2d(2,2),

            nn.Conv2d(16,32,kernel_size = 3,padding=1),
            nn.ReLU(),
            nn.MaxPool2d(2,2),
            
            nn.Conv2d(32,64,kernel_size=3,padding=1),
            nn.ReLU(),
            nn.MaxPool2d(2,2),
        )
    #全连接层:输出10个关键点坐标
     self.fc_layers=nn.Sequential(
        nn.Linear(64*8*8,256),
        nn.ReLU(),
        nn.Linear(256,10)#输出层:10个神经元
       )
    def forward(self,x):
        x=self.conv_layers(x)
        x=x.view(x.size(0),-1)
        x=self.fc_layers(x)
        retrun x
复制代码
3. 训练主程序 
python 复制代码
def main():
    #配置设备
    device=torch.device("cuda" if torch.cuda.is_available() else "cpu")

    print(f"使用设备:{device}")


    #数据预处理

    transform = transforms.Compose([
        transfroms.ToTensor(),
        transforms.Normalize(mean=[0.5,0.5,0.5],std=[0.5,0.5,0.5])
    ])

    train_dataset = FaceKeypointDataset(txt_path="train.txt", img_dir="imgdata", transform=transform)
    test_dataset = FaceKeypointDataset(txt_path="test.txt", img_dir="imgdata", transform=transform)



    train_loader = DataLoader(train_dataset,batch_size=8,shuffle=True)
    test_loader = DataLoader(test_dataset,batch_size=8,shuffle=False)


    #初始化模型,损失函数,优化器

    model = KeypointNet().to(device)

    criterion = nn.L1loss()
    optimizer = torch.optim.Adam(model.parameters(),lr=1e-3)


    #训练参数
    num_ephchs=30
    train_loss_history =[]
    test_loss_history=[]

    print("\n=====开始训练=====")
    for epoch in range(num_epochs):
        model.train()
        train_loss=0.0
        for imgs,kpts in train_loader:

            imgs,kpts=imgs.to(device),kpts.to(device)


            #前向传播
            outputs = model(imgs)

            loss = criterion(outputs,kpts)

            #反向传播
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
            train_loss+=loss.item() * imgs.size(0)
          #计算平均训练损失
          train_loss/ = len(train_dataset)
          train_loss_history.append(train_loss)

          #测试阶段
          model.eval()
          test_loss=0.0

          with torch.no_grad():
              for imgs,kpts in test_loader:
                  imgs,kpts = imgs.to(device),kpts.to(device)
                  outputs = model(imgs)

                  test_loss +=criterion(outputs,kpts).item()*imgs.size(0)

          test_loss / =len(test_dataset)
          test_loss_history.append(test_loss)

          print(f"Epoch [{epoch+1}/{num_epochs}} | Train Loss:{train_loss:.6f} | Test Loss:{test_loss:.6f}")
    print("======训练完成======")

    plt.figure(figsize=(10,5))
    plt.plot(train_loss_history,label = "Train Loss")
    plt.plot(test_loss_history,label="Test Loss")

    plt.xlabel("Epoch")
    plt.ylabel("L1 Loss")
    plt.title("Training and Testing Loss Curve")
    plt.lengend()
    plt.grid(True)
    plt.savefig("loss_curve.png")
    plt.show()
    torch.save(model.state_dict(), "face_keypoint_model.pth")
    print("模型已保存为 face_keypoint_model.pth")

if __name__ == "__main__":
    main()




       

运行结果:

相关推荐
谢谢 啊sir1 分钟前
L2-057 姥姥改作业 - java
java·开发语言
l1t1 分钟前
duckdb excel插件和rusty_sheet插件在python中的不同表现
开发语言·python·excel
人道领域4 分钟前
【黑马点评日记】高并发秒杀:库存超卖与锁机制解析
java·开发语言·redis·spring·intellij-idea
lsx2024069 分钟前
《jEasyUI 创建树形下拉框》
开发语言
pele12 分钟前
如何解决多线图中线条颜色不渲染(仅标记和提示框显示颜色)的问题
jvm·数据库·python
minji...15 分钟前
Linux 网络套接字编程(一)端口号port,socket套接字,socket,bind,socket 通用结构体
linux·运维·服务器·开发语言·网络
forEverPlume15 分钟前
golang如何排查大量goroutine性能问题_golang大量goroutine性能排查详解
jvm·数据库·python
2301_8148098616 分钟前
踩坑实战pywebview:用 Python + Web 技术打造轻量级桌面应用
开发语言·前端·python
南境十里·墨染春水16 分钟前
C++流类库 字符串流
开发语言·c++
2401_8836002517 分钟前
Golang怎么CGO交叉编译_Golang如何在交叉编译时处理CGO依赖问题【避坑】
jvm·数据库·python