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

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

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()




       

运行结果:

相关推荐
hoiii1871 天前
Qt 实现屏幕截图功能
开发语言·qt·命令模式
小白学大数据1 天前
爬虫性能天花板:asyncio赋能 Aiohttp,并发提速 10 倍
开发语言·爬虫·数据分析
Metaphor6921 天前
使用 Python 给 PDF 设置背景色或背景图
数据库·python·pdf
凡人叶枫1 天前
Effective C++ 条款07:为多态基类声明 virtual 析构函数
linux·c语言·开发语言·c++
凡人叶枫1 天前
Effective C++ 条款10:令 operator= 返回一个 reference to *this
java·linux·服务器·开发语言·c++·effective c++
郝亚军1 天前
如何让pycharm-2026.1.2顶部菜单栏固定显示在最上端
python
怪兽学LLM1 天前
LeetCode 438 找到字符串中所有字母异位词(Python 固定滑动窗口+字符计数解法)
python·算法·leetcode
麻雀飞吧1 天前
期货量化日志别泄露密码:天勤账户凭证脱敏写法
python
CC数学建模1 天前
2026年江西省研究生数学建模竞赛1题:空间数据分析中的过拟合识别完整思路、代码、模型、文章,全网首发高质量分享!
python·算法·数学建模