文章目录

  • 前言
  • 一、项目结构
  • 二、数据集准备
  • 三、网络模型
  • 四、具体代码
    • 1.get_face.py
    • 2.find_iu.py
    • 3.spider_iu.py
    • 4.file_deal.py
    • 5.network.py
    • 4.utils.py
  • 总结

前言

出于兴趣和对IU的喜爱,笔者花了几天尝试用爬虫从百度图片获取韩国艺人的人物图片并下载,利用深度神经网络从其中识别出IU(李知恩),并将IU的人物图片保存至文件夹。但是限于GPU性能无法使用太复杂的网络,最后识别的效果不佳,若读者有兴趣,也可以去替换一下网络,改善一下数据集,尝试提升识别性能。
项目环境:python3.6


一、项目结构

二、数据集准备

数据集准备分为两步:1、获取图片,2、提取人脸。
1、获取图片
首先可以利用爬虫,从百度图片上批量下载图片,但注意下载数据集所用的关键词不要和之后识别任务的关键词太接近,否则若有图片重合,就会产生“识别得很准”的错觉。下面的程序为爬虫部分,在name.txt文件中写好要搜索的关键词,即可使用。

# 爬虫部分,存放到 name + ‘文件’#############################################################################################if GET_PIC == 1:headers = {'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2','Connection': 'keep-alive','User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0','Upgrade-Insecure-Requests': '1'}A = requests.Session()A.headers = headerstm = int(input('请输入每类图片的下载数量 '))numPicture = tmline_list = []with open('./name.txt', encoding='utf-8') as file:line_list = [k.strip() for k in file.readlines()]  # 用 strip()移除末尾的空格for word in line_list:url = 'https://image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&word=' + word + '&pn='tot = Find(url, A)Recommend = recommend(url)  # 记录相关推荐print('经过检测%s类图片共有%d张' % (word, tot))file = word + '文件'y = os.path.exists(file)if y == 1:print('该文件已存在,无需创建')else:os.mkdir(file)t = 0tmp = urlwhile t < numPicture:try:url = tmp + str(t)# result = requests.get(url, timeout=10)# 这里搞了下result = A.get(url, timeout=10, allow_redirects=False)print(url)except error.HTTPError as e:print('网络错误,请调整网络后重试')t = t + 60else:dowmloadPicture(result.text, word)t = t + 60numPicture = numPicture + tmprint('当前搜索结束,开始提取人脸')#############################################################################################

下载图片时要注意区分,将IU的图片放在一个文件夹下,Other的放在另一文件夹下。训练集和测试集都要如此。如下图所示:

每个文件夹内都是下图形式:

在IU文件夹内图片如下所示:

对于文件夹内文件的命名,可以利用以下这段程序,按顺序重命名。

import osraw_train_root_1 = 'E:/Table/学习数据集/find_iu/data/raw/train/IU/'
raw_train_root_2 = 'E:/Table/学习数据集/find_iu/data/raw/train/Other/'
raw_test_root_1 = 'E:/Table/学习数据集/find_iu/data/raw/test/IU/'
raw_test_root_2 = 'E:/Table/学习数据集/find_iu/data/raw/test/Other/'
raw_roots = [raw_train_root_1, raw_train_root_2, raw_test_root_1, raw_test_root_2]for path in raw_roots:# 获取该目录下所有文件,存入列表中fileList = os.listdir(path)n = 0for i in fileList:# 设置旧文件名(就是路径+文件名)oldname = path + os.sep + fileList[n]  # os.sep添加系统分隔符# 设置新文件名newname = path + os.sep + str(n) + '.JPG'os.rename(oldname, newname)  # 用os模块中的rename方法对文件改名print(oldname, '======>', newname)n += 1

2、提取人脸

提取人脸需要用到一个人脸识别库face_recognition库。face_recognition库的下载步骤参考:https://blog.csdn.net/qq_34020487/article/details/101871752
主要有三步,可以直接在anaconda的命令行界面复制使用:

  1. pip install CMake -i https://pypi.douban.com/simple
  2. pip install dlib==19.7.0 -i https://pypi.douban.com/simple
  3. pip install face_recognition -i https://pypi.douban.com/simple

笔者已尝试,确实可用。
使用下述的函数就可以获得一张图片对应的人脸,返回值就是人脸图片。

# 找到图片中的人脸
#############################################################################################
def find_face(path):# Load the jpg file into a numpy arrayimage = face_recognition.load_image_file(path)# Find all the faces in the image using the default HOG-based model.# This method is fairly accurate, but not as accurate as the CNN model and not GPU accelerated.# See also: find_faces_in_picture_cnn.pyface_locations = face_recognition.face_locations(image) # 可以选择 model="cnn"if len(face_locations) == 0:return Noneelse:for face_location in face_locations:# Print the location of each face in this imagetop, right, bottom, left = face_location# You can access the actual face itself like this:face_image = image[top:bottom, left:right]pil_image = Image.fromarray(face_image)return pil_image
#############################################################################################

对数据集进行操作之后,就可以获得处理后的人脸图片。之所以不用人物图训练,而是提取出人脸后再进行训练,是考虑到人物图像中干扰因素太多,且经过试验后发现识别的效果非常差,于是加入这个提取人脸的环节。对数据集的操作代码如下:

# 将训练集和测试集中的raw图片处理,提取出人脸图片
#############################################################################################
if __name__ == '__main__':  # 主函数入口raw_train_root_1 = 'E:/Table/学习数据集/find_iu/data/raw/train/IU/'raw_train_root_2 = 'E:/Table/学习数据集/find_iu/data/raw/train/Other/'raw_test_root_1 = 'E:/Table/学习数据集/find_iu/data/raw/test/IU/'raw_test_root_2 = 'E:/Table/学习数据集/find_iu/data/raw/test/Other/'raw_roots = [raw_train_root_1, raw_train_root_2, raw_test_root_1, raw_test_root_2]img_raw_train_1 = os.listdir(raw_train_root_1)img_raw_train_2 = os.listdir(raw_train_root_2)img_raw_test_1 = os.listdir(raw_test_root_1)img_raw_test_2 = os.listdir(raw_test_root_2)img_raws = [img_raw_train_1, img_raw_train_2, img_raw_test_1, img_raw_test_2]new_path_train_1 = 'E:/Table/学习数据集/find_iu/data/processed/train/IU/'new_path_train_2 = 'E:/Table/学习数据集/find_iu/data/processed/train/Other/'new_path_test_1 = 'E:/Table/学习数据集/find_iu/data/processed/test/IU/'new_path_test_2 = 'E:/Table/学习数据集/find_iu/data/processed/test/Other/'new_paths = [new_path_train_1, new_path_train_2, new_path_test_1, new_path_test_2]for raw_root, img_raw, new_path in zip(raw_roots, img_raws, new_paths):n = 0for i in range(len(img_raw)):try:img = Image.open(raw_root + img_raw[i])except:print('a file error, continue')continueelse:img_train = find_face(raw_root + img_raw[i])if img_train == None:continueelse:# img_train.save(new_path + '%d.JPG'%n)# print(raw_root + img_raw[i])n += 1print('在%d张图片中,共找到%d张脸' % (len(img_raw), n))
#############################################################################################

处理前的图片数据均存放在raw文件夹中,处理后的存放在processed文件夹中,如下图:

两个文件夹的内部结构完全一样:


三、网络模型

1、图像处理

将图片裁剪为112×92大小,使用RGB图像,(这里试过用灰度图像,但好像效果不会更好,就放弃了),在对图片进行归一化处理。

data_transform = transforms.Compose([# transforms.Grayscale(num_output_channels=1),  # 彩色图像转灰度图像num_output_channels默认1transforms.Resize(112),transforms.CenterCrop((112, 92)),  # 中心裁剪为112*92transforms.ToTensor(),transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])# transforms.Normalize(mean=0.5, std=0.5)])

使用孪生神经网络(Siamese Network)

class SiameNetwork(nn.Module):def __init__(self):super(SiameNetwork, self).__init__()# input: h=112, w=92self.conv1 = torch.nn.Sequential(torch.nn.Conv2d(in_channels=3,  # 输入单通道out_channels=16,  # 16个3*3卷积核kernel_size=3,  # 卷积核尺寸stride=2,  # 卷积核滑动步长, 1的话图片大小不变,2的话会大小会变为(h/2)*(w/2)padding=1),  # 边缘填充大小,如果要保持原大小,kernel_size//2torch.nn.BatchNorm2d(16),  # 标准化,前面卷积后有16个图层torch.nn.ReLU()  # 激活函数)  # output: h=56, w=46self.conv2 = torch.nn.Sequential(torch.nn.Conv2d(16, 32, 3, 2, 1),torch.nn.BatchNorm2d(32),torch.nn.ReLU())  # output: h=28, w=23self.conv3 = torch.nn.Sequential(torch.nn.Conv2d(32, 64, 3, 2, 1),torch.nn.BatchNorm2d(64),torch.nn.ReLU())  # output: h=14, w=12self.conv4 = torch.nn.Sequential(torch.nn.Conv2d(64, 64, 2, 2, 0),torch.nn.BatchNorm2d(64),torch.nn.ReLU())  # output: h=7, w=6self.mlp1 = torch.nn.Linear(7 * 6 * 64, 100)  # 需要计算conv4的输出尺寸,每次卷积的输出尺寸(size - kernal + 2*padding)/stride + 1self.mlp2 = torch.nn.Linear(100, 10)def forward(self, x):x = self.conv1(x)x = self.conv2(x)x = self.conv3(x)x = self.conv4(x)x = self.mlp1(x.view(x.size(0), -1))  # view展平x = self.mlp2(x)return x

四、具体代码

1.get_face.py

from PIL import Image
import face_recognition
import os# 找到图片中的人脸
#############################################################################################
def find_face(path):# Load the jpg file into a numpy arrayimage = face_recognition.load_image_file(path)# Find all the faces in the image using the default HOG-based model.# This method is fairly accurate, but not as accurate as the CNN model and not GPU accelerated.# See also: find_faces_in_picture_cnn.pyface_locations = face_recognition.face_locations(image) # 可以选择 model="cnn"if len(face_locations) == 0:return Noneelse:for face_location in face_locations:# Print the location of each face in this imagetop, right, bottom, left = face_location# You can access the actual face itself like this:face_image = image[top:bottom, left:right]pil_image = Image.fromarray(face_image)return pil_image
############################################################################################## 将训练集和测试集中的raw图片处理,提取出人脸图片
#############################################################################################
if __name__ == '__main__':  # 主函数入口raw_train_root_1 = 'E:/Table/学习数据集/find_iu/data/raw/train/IU/'raw_train_root_2 = 'E:/Table/学习数据集/find_iu/data/raw/train/Other/'raw_test_root_1 = 'E:/Table/学习数据集/find_iu/data/raw/test/IU/'raw_test_root_2 = 'E:/Table/学习数据集/find_iu/data/raw/test/Other/'raw_roots = [raw_train_root_1, raw_train_root_2, raw_test_root_1, raw_test_root_2]img_raw_train_1 = os.listdir(raw_train_root_1)img_raw_train_2 = os.listdir(raw_train_root_2)img_raw_test_1 = os.listdir(raw_test_root_1)img_raw_test_2 = os.listdir(raw_test_root_2)img_raws = [img_raw_train_1, img_raw_train_2, img_raw_test_1, img_raw_test_2]new_path_train_1 = 'E:/Table/学习数据集/find_iu/data/processed/train/IU/'new_path_train_2 = 'E:/Table/学习数据集/find_iu/data/processed/train/Other/'new_path_test_1 = 'E:/Table/学习数据集/find_iu/data/processed/test/IU/'new_path_test_2 = 'E:/Table/学习数据集/find_iu/data/processed/test/Other/'new_paths = [new_path_train_1, new_path_train_2, new_path_test_1, new_path_test_2]for raw_root, img_raw, new_path in zip(raw_roots, img_raws, new_paths):n = 0for i in range(len(img_raw)):try:img = Image.open(raw_root + img_raw[i])except:print('a file error, continue')continueelse:img_train = find_face(raw_root + img_raw[i])if img_train == None:continueelse:# img_train.save(new_path + '%d.JPG'%n)# print(raw_root + img_raw[i])n += 1print('在%d张图片中,共找到%d张脸' % (len(img_raw), n))
#############################################################################################

2.find_iu.py

import torch
import torchvision
import torch.nn as nn
from torch.autograd import Variable
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
import cv2   #opencv库,用于图片可视化
import numpy as np
import os
from utils import draw_result
from network import SiameNetwork
from get_face import find_faceif __name__ == '__main__':  # 主函数入口# 设置参数#############################################################################################path = 'E:/Table/学习数据集/find_iu/result/'    # 存放和生成结果的路径标志epochs = 20       #训练周期BATCH_SIZE = 16    #批量样本大小NUM_WORKERS = 0############################################################################################## 数据处理#############################################################################################data_transform = transforms.Compose([# transforms.Grayscale(num_output_channels=1),  # 彩色图像转灰度图像num_output_channels默认1transforms.Resize(112),transforms.CenterCrop((112, 92)),  # 中心裁剪为112*92transforms.ToTensor(),transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])# transforms.Normalize(mean=0.5, std=0.5)])train_dataset = datasets.ImageFolder(root = r'E:/Table/学习数据集/find_iu/data/processed/train',transform = data_transform)test_dataset = datasets.ImageFolder(root = r'E:/Table/学习数据集/find_iu/data/processed/test',transform = data_transform)train_loader = DataLoader(train_dataset, batch_size=BATCH_SIZE, shuffle=True, num_workers=NUM_WORKERS)test_loader = DataLoader(test_dataset, batch_size=BATCH_SIZE, shuffle=True, num_workers=NUM_WORKERS)image, labels = next(iter(train_loader))       #数据可视化img = torchvision.utils.make_grid(image, nrow = 10)img = img.numpy().transpose(1, 2, 0)cv2.imshow('img', img)    #展示图像cv2.waitKey(0)  #按下任一按键后开始工作print("data ready!")##############################################################################################配置设备、损失函数和优化器#############################################################################################device = torch.device('cuda')model = SiameNetwork().to(device)cost = torch.nn.CrossEntropyLoss()        #定义损失函数,使用交叉熵optimizer = torch.optim.Adam(model.parameters(), lr=0.0008, weight_decay=0.001)            #Adam优化器print("device ready!")##############################################################################################训练过程,训练周期由epochs决定#############################################################################################draw_epoch = []   #记录训练阶段draw_loss = []    #记录训练损失,用于绘制draw_train_acc = []   #记录训练准确度,用于绘制draw_val_loss = []   #记录测试损失,用于绘制draw_val_acc = []  # 记录测试准确度,用于绘制for epoch in range(epochs):#训练过程sum_loss = 0.0sum_val_loss = 0.0train_correct = 0test_correct = 0for data in train_loader:inputs,labels = datainputs,labels = Variable(inputs).cuda(),Variable(labels).cuda()optimizer.zero_grad()        #将上一batch梯度清零outputs = model(inputs)loss = cost(outputs, labels)loss.backward()             #反向传播optimizer.step()_, id = torch.max(outputs.data, 1)sum_loss += loss.datatrain_correct += torch.sum(id == labels.data)for data in test_loader:              # 模型测试inputs,labels = datainputs,labels = Variable(inputs).cuda(),Variable(labels).cuda()outputs = model(inputs)val_loss = cost(outputs, labels)_,id = torch.max(outputs.data, 1)sum_val_loss += val_loss.datatest_correct += torch.sum(id == labels.data)print('[%d,%d] train loss:%.03f      train acc:%.03f%%'%(epoch + 1, epochs, sum_loss / len(train_loader), (100 * train_correct / len(train_dataset))))print('        val loss:%.03f        val acc:%.03f%%'%(sum_val_loss / len(test_loader), (100 * test_correct / len(test_dataset))))draw_epoch.append(epoch+1)       # 用于后续画图的数据draw_loss.append(sum_loss / len(train_loader))draw_train_acc.append(100 * train_correct / len(train_dataset))draw_val_loss.append(sum_val_loss / len(test_loader))draw_val_acc.append(100 * test_correct / len(test_dataset))np.savetxt('%s/train_loss.txt'%(path), draw_loss, fmt="%.3f")        # 保存损失数据np.savetxt('%s/train_acc.txt'%(path), draw_train_acc, fmt="%.3f")  # 保存准确率数据np.savetxt('%s/val_loss.txt'%(path), draw_val_loss, fmt="%.3f")     # 保存损失数据np.savetxt('%s/val_acc.txt'%(path), draw_val_acc, fmt="%.3f")  # 保存准确率数据print("train ready!")##############################################################################################数据可视化#############################################################################################draw_result(draw_epoch, path)   # 绘图函数print("draw ready!")##############################################################################################模型的存储和载入#############################################################################################torch.save(model.state_dict(), "parameter.pkl") #saveprint("save ready!")#############################################################################################

3.spider_iu.py

import re
import requests
from urllib import error
from bs4 import BeautifulSoup
import os
import torch
from torch.autograd import Variable
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
from network import SiameNetwork
from utils import cv_imread
import cv2
from PIL import Image
import shutil
from get_face import find_face# 设置参数
#############################################################################################
GET_PIC = 0    # 1 执行这步,0 不执行
GET_FACE = 0
GET_IU = 1
#############################################################################################
num = 0
numPicture = 0
file = ''
List = []# 爬虫所用函数
#############################################################################################
def Find(url, A):global Listprint('正在检测图片总数,请稍等.....')t = 0i = 1s = 0while t < 1000:Url = url + str(t)try:# 这里搞了下Result = A.get(Url, timeout=7, allow_redirects=False)except BaseException:t = t + 60continueelse:result = Result.textpic_url = re.findall('"objURL":"(.*?)",', result, re.S)  # 先利用正则表达式找到图片urls += len(pic_url)if len(pic_url) == 0:breakelse:List.append(pic_url)t = t + 60return sdef recommend(url):Re = []try:html = requests.get(url, allow_redirects=False)except error.HTTPError as e:returnelse:html.encoding = 'utf-8'bsObj = BeautifulSoup(html.text, 'html.parser')div = bsObj.find('div', id='topRS')if div is not None:listA = div.findAll('a')for i in listA:if i is not None:Re.append(i.get_text())return Redef dowmloadPicture(html, keyword):global num# t =0pic_url = re.findall('"objURL":"(.*?)",', html, re.S)  # 先利用正则表达式找到图片urlprint('找到关键词:' + keyword + '的图片,即将开始下载图片...')for each in pic_url:print('正在下载第' + str(num + 1) + '张图片,图片地址:' + str(each))try:if each is not None:pic = requests.get(each, timeout=7)else:continueexcept BaseException:print('错误,当前图片无法下载')continueelse:string = file + r'\\' + keyword + '_' + str(num) + '.jpg'fp = open(string, 'wb')fp.write(pic.content)fp.close()num += 1if num >= numPicture:return
#############################################################################################if __name__ == '__main__':  # 主函数入口# 爬虫部分,存放到 name + ‘文件’#############################################################################################if GET_PIC == 1:headers = {'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2','Connection': 'keep-alive','User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0','Upgrade-Insecure-Requests': '1'}A = requests.Session()A.headers = headerstm = int(input('请输入每类图片的下载数量 '))numPicture = tmline_list = []with open('./name.txt', encoding='utf-8') as file:line_list = [k.strip() for k in file.readlines()]  # 用 strip()移除末尾的空格for word in line_list:url = 'https://image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&word=' + word + '&pn='tot = Find(url, A)Recommend = recommend(url)  # 记录相关推荐print('经过检测%s类图片共有%d张' % (word, tot))file = word + '文件'y = os.path.exists(file)if y == 1:print('该文件已存在,无需创建')else:os.mkdir(file)t = 0tmp = urlwhile t < numPicture:try:url = tmp + str(t)# result = requests.get(url, timeout=10)# 这里搞了下result = A.get(url, timeout=10, allow_redirects=False)print(url)except error.HTTPError as e:print('网络错误,请调整网络后重试')t = t + 60else:dowmloadPicture(result.text, word)t = t + 60numPicture = numPicture + tmprint('当前搜索结束,开始提取人脸')############################################################################################## 将训练集和测试集中的raw图片处理,提取出人脸图片,从file+'文件'到‘待分辨人脸’############################################################################################if GET_FACE == 1:if GET_PIC == 0:file = '韩国女艺人文件'raw_root = 'E:/Table/学习数据集/find_iu/'+ file + '/'img_raw = os.listdir(raw_root)new_path = 'E:/Table/学习数据集/find_iu/待分辨人脸/'n = 0for i in range(len(img_raw)):try:img = Image.open(raw_root + img_raw[i])except:print('a file error, continue')continueelse:img_train = find_face(raw_root + img_raw[i])if img_train == None:continueelse:img_train.save(new_path + '%d.JPG' % n)print(raw_root + img_raw[i])n += 1print('在%d张图片中,共找到%d张脸' % (len(img_raw), n))print('提取人脸结束,开始寻找IU')############################################################################################## 开始判别,从’待分辨人脸‘中找出IU存放到’IU_pic‘#############################################################################################if GET_IU == 1:data_transform = transforms.Compose([# transforms.Grayscale(num_output_channels=1),  # 彩色图像转灰度图像num_output_channels默认1transforms.Resize(112),transforms.CenterCrop((112, 92)),  # 中心裁剪为112*92transforms.ToTensor(),transforms.Normalize(mean=[0.5, 0.5, 0.5],std=[0.5, 0.5, 0.5])# transforms.Normalize(mean=0.5, std=0.5)])device = torch.device('cuda')model = SiameNetwork().to(device)model.load_state_dict(torch.load('parameter.pkl'))  # loadmodel.eval()judge_root = 'E:/Table/学习数据集/find_iu/待分辨人脸/'img_judge = os.listdir(judge_root)new_path = 'E:/Table/学习数据集/find_iu/IU_pic/'result = []n = 0for i in range(len(img_judge)):try:img = Image.open(judge_root + img_judge[i])except:print('a file error, continue')continueelse:img = img.convert('RGB')print(judge_root + img_judge[i])input = data_transform(img)input = input.unsqueeze(0)  # 这里经过转换后输出的input格式是[C,H,W],网络输入还需要增加一维批量大小B# 增加一维,输出的img格式为[1,C,H,W]input = Variable(input.cuda())output = model(input)  # 将图片输入网络得到输出_, id = torch.max(output.data, 1)   # 0是IU,1是其他if id.item() == 0:shutil.copy(judge_root + img_judge[i], new_path)n += 1print('/n在%d张图片中,共找到%d张IU的图片'%(len(img_judge), n))#############################################################################################

4.file_deal.py

import osraw_train_root_1 = 'E:/Table/学习数据集/find_iu/data/raw/train/IU/'
raw_train_root_2 = 'E:/Table/学习数据集/find_iu/data/raw/train/Other/'
raw_test_root_1 = 'E:/Table/学习数据集/find_iu/data/raw/test/IU/'
raw_test_root_2 = 'E:/Table/学习数据集/find_iu/data/raw/test/Other/'
raw_roots = [raw_train_root_1, raw_train_root_2, raw_test_root_1, raw_test_root_2]for path in raw_roots:# 获取该目录下所有文件,存入列表中fileList = os.listdir(path)n = 0for i in fileList:# 设置旧文件名(就是路径+文件名)oldname = path + os.sep + fileList[n]  # os.sep添加系统分隔符# 设置新文件名newname = path + os.sep + str(n) + '.JPG'os.rename(oldname, newname)  # 用os模块中的rename方法对文件改名print(oldname, '======>', newname)n += 1

5.network.py

import torch
import torch.nn as nnclass SiameNetwork(nn.Module):def __init__(self):super(SiameNetwork, self).__init__()# input: h=112, w=92self.conv1 = torch.nn.Sequential(torch.nn.Conv2d(in_channels=3,  # 输入单通道out_channels=16,  # 16个3*3卷积核kernel_size=3,  # 卷积核尺寸stride=2,  # 卷积核滑动步长, 1的话图片大小不变,2的话会大小会变为(h/2)*(w/2)padding=1),  # 边缘填充大小,如果要保持原大小,kernel_size//2torch.nn.BatchNorm2d(16),  # 标准化,前面卷积后有16个图层torch.nn.ReLU()  # 激活函数)  # output: h=56, w=46self.conv2 = torch.nn.Sequential(torch.nn.Conv2d(16, 32, 3, 2, 1),torch.nn.BatchNorm2d(32),torch.nn.ReLU())  # output: h=28, w=23self.conv3 = torch.nn.Sequential(torch.nn.Conv2d(32, 64, 3, 2, 1),torch.nn.BatchNorm2d(64),torch.nn.ReLU())  # output: h=14, w=12self.conv4 = torch.nn.Sequential(torch.nn.Conv2d(64, 64, 2, 2, 0),torch.nn.BatchNorm2d(64),torch.nn.ReLU())  # output: h=7, w=6self.mlp1 = torch.nn.Linear(7 * 6 * 64, 100)  # 需要计算conv4的输出尺寸,每次卷积的输出尺寸(size - kernal + 2*padding)/stride + 1self.mlp2 = torch.nn.Linear(100, 10)def forward(self, x):x = self.conv1(x)x = self.conv2(x)x = self.conv3(x)x = self.conv4(x)x = self.mlp1(x.view(x.size(0), -1))  # view展平x = self.mlp2(x)return x

4.utils.py

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import cv2# 绘制训练、测试的损失、准确度
#############################################################################################
def draw_result(draw_epoch, path):show_loss = np.loadtxt('%s/train_loss.txt' % (path))   # 读取txt文件,不同优化器的损失show_train_acc = np.loadtxt('%s/train_acc.txt' % (path))  # 读取不同模型的准确度show_val_loss = np.loadtxt('%s/val_loss.txt' % (path))  # 读取txt文件,不同优化器的损失show_val_acc = np.loadtxt('%s/val_acc.txt' % (path))  # 读取不同模型的准确度mpl.rc('font',family='Times New Roman', weight='semibold', size=9)  # 设置matplotlib中所有绘图风格的设置font1 = {'weight' : 'semibold', 'size' : 11}  #设置文字风格fig = plt.figure(figsize = (7,5))    #figsize是图片的大小`ax1 = fig.add_subplot(2, 2, 1)       # ax1是子图的名字ax1.plot(draw_epoch, show_loss,color = 'red', label = u'AdaPID', linewidth =1.0)ax1.legend()   #显示图例ax1.set_title('Training Loss', font1)ax1.set_xlabel(u'Epoch', font1)ax2 = fig.add_subplot(2, 2, 2)ax2.plot(draw_epoch, show_val_loss,color = 'red', label = u'Adam', linewidth =1.0)ax2.legend()   #显示图例ax2.set_title('Validation Loss', font1)ax2.set_xlabel(u'Epoch', font1)ax3 = fig.add_subplot(2, 2, 3)ax3.plot(draw_epoch, show_train_acc,color = 'red', label = u'Adam', linewidth =1.0)ax3.legend()   #显示图例ax3.set_title('Training Accuracy', font1)ax3.set_xlabel(u'Epoch', font1)ax4 = fig.add_subplot(2, 2, 4)ax4.plot(draw_epoch, show_val_acc,color = 'red', label = u'Adam', linewidth =1.0)ax4.legend()   #显示图例ax4.set_title('Validation Accuracy', font1)ax4.set_xlabel(u'Epoch', font1)plt.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=0.45) # hspace为子图上下间距plt.savefig('%s/show_curve.jpg' % (path), dpi=300)
############################################################################################## 用于解决cv.imread不能读取中文路径的问题
#############################################################################################
def cv_imread(filePath):# 核心就是下面这句,一般直接用这句就行,直接把图片转为mat数据cv_img = cv2.imdecode(np.fromfile(filePath, dtype=np.uint8), -1)# imdecode读取的是rgb,如果后续需要opencv处理的话,需要转换成bgr,转换后图片颜色会变化# cv_img=cv2.cvtColor(cv_img,cv2.COLOR_RGB2BGR)return cv_img
#############################################################################################

总结

总体而言,这是一个新人的兴趣之作,虽然失败了但是做的过程还蛮有趣的,主要是过程中可以看到iu,哈哈。

人脸识别IU(李知恩)相关推荐

  1. 什么是iu组装服务器,IU李知恩和“买家秀”在“教科书”级别的私有服务器共享是邻居...

    T恤在很多女孩心目中可以算是百搭,但是很难穿上一种新时尚单品,因为宽松的款式很难满足女孩突出身材的需求,而极高的舒适性也让她们无法完全抛弃T恤.如果你不知道热门的夏天在t恤上看起来如何好看,让我们看看 ...

  2. 人脸识别IU(李知恩)(2)

    文章目录 前言 一.项目结构 二.使用步骤 1.生成特征向量 2.训练模型 3.运行结果 总结 前言 在之前的对IU的人脸识别中,在使用face_recognition库进行人脸提取的过程中,发现这个 ...

  3. 机器学习——SVM(支持向量机)与人脸识别

    目录 系列文章目录 一.SVM的概念与原理 1.SVM简介 2.SVM基本流程 3.SVM在多分类中的推广 二.经典SVM运用于图像识别分类 三.SVM运用于人脸识别 1.预处理 1.1 数据导入与处 ...

  4. 机器学习——LR(线性回归)、LRC(线性回归分类)与人脸识别

    目录 系列文章目录 一.LR的概念.原理与LR用于简单数据的预测 1.LR简介 2.LR算法模型 3.LR用于简单数据的预测 二.LRC的简介与算法流程 1.LRC(线性回归分类)简介 2.LRC算法 ...

  5. 基于人脸识别的商业大数据1

    主要内容: 人脸识别登录      根据人脸识别与浏览记录相结合的方式进行商品和广告推荐      根据表情识别来分别客户对广告推荐的喜好程度 功能性需求: 人脸检测:      通过摄像头获取人脸轮 ...

  6. 【开发教程15】AI语音人脸识别(会议记录仪/人脸打卡机)-加解密及数据协议

    CC3200AI实验教程 --疯壳·开发板系列 加解密及数据协议 在<AI人脸系统架构>一节中,我们提到AI设备与服务器之间的通信协议及TEA加密.这一节主要来讲解一下TEA加密另附上&l ...

  7. 人脸识别原理详细讲解

    人脸识别原理(以GitHub项目face_recognition为例) - 知乎 Github开源人脸识别项目face_recognition - 知乎

  8. 开源毕业设计:基于嵌入式ARM-Linux的应用OpenCV和QT实现的人脸识别系统(源码+论文)

    毕业一载有余,把毕业设计作品分享一下,希望能帮助到有需要的同学们. 资料获取: 帮助/答疑/辅导...等请联系博主,请点如下链接: linux_face.txt · zengzr/share_cont ...

  9. Python吴恩达深度学习作业16 -- 人脸识别

    人脸识别 - the Happy House 在此次作业中,你将学习构建人脸识别系统. 人脸识别问题通常分为两类: 人脸验证:比如在某些机场,系统通过扫描你的护照,然后确认你(携带护照的人)是本人,从 ...

最新文章

  1. Spring Boot+Gradle+ MyBatisPlus3.x搭建企业级的后台分离框架
  2. 鞭策你一辈子的好文章
  3. whatpulse.exe 启动时报错
  4. OpenCV图像锐化/增强
  5. mysql5.6.13_MySQL-5.6.13解压版(zip版)安装配置教程
  6. 制作U盘启动盘之Ubuntu
  7. 自走棋电脑版_手游版《自走棋》上线试玩
  8. _04媒体文件的读取
  9. 进制转换工具类-JAVA
  10. VS C++ sprintf 格式
  11. MySQL sql语句总结
  12. java企业通用模块_[模板风格]WordPress企业主题Start通用响应式强大模块化wordpress-无...
  13. 苹果手机卡死黑屏了不能开机怎么处理
  14. excel中为什么不显示单引号
  15. 如何把WORD转换成EXCEL
  16. 苹果机和Android,苹果机和安卓机各有优缺点,但苹果机这四点让人顶不住
  17. ps使用,绘制外观图
  18. 利用python对文件夹中所有图像进行批量增强处理并保存结果
  19. liblensfun 在 mingw 上编译时遇到的奇怪问题
  20. 云图科技,长沙VR全景打造旅游业新视角

热门文章

  1. 你的笔记本需要整理么
  2. Ubuntu 12.04 1 跑 Windows下的类通达信股票软件
  3. Linux 存储 superblock
  4. 网上的无形税:视频编解码器
  5. [bsoj3134] 好感统计
  6. 2G-3G-4G网络结构演进过程
  7. 匿名可访问FTP服务器地址大全
  8. 使用canal解决Mysql和Redis数据同步问题
  9. Java春招面试复习:有关于Java Map,应该掌握的8个问题
  10. Android下USB Accessory的实现分析 (三)--- Android Open AccessoryProtocol