欢迎光临
我们一直在努力

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

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

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. 数据集定义(匹配你的目录结构)

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. 卷积神经网络模型

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. 训练主程序

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

运行结果:

赞(0)
未经允许不得转载:171主机测评 » 【卷积神经网络作业实现人脸的关键点定位功能】
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址