日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

深度学习项目,使用python进行表情识别,pytorch应用

發布時間:2024/1/8 python 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深度学习项目,使用python进行表情识别,pytorch应用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 前言
  • 一、深度學習是什么?
  • 二、數據的預處理
    • 1.數據分類
    • 2.代碼
  • 三、構建模型與訓練
    • 1.模型與代碼
    • 2.使用方法
  • 四、實時識別
  • 總結


前言

這個項目是以前課設用到的功能之一,參考了其他人的人的博客,自己做了一下整理
需要用到的庫有:opencv,pandas,pytorch,numpy,dlib
本項目基于深度學習


一、深度學習是什么?

深度學習(DL, Deep Learning)是機器學習(ML, Machine Learning)領域中一個新的研究方向,它被引入機器學習使其更接近于最初的目標——人工智能(AI, Artificial Intelligence)。

形象來說,深度學習就是構建一個類似于人類大腦的人工神經網絡,通過已有的數據不斷學習,最終使得每個神經元的參數趨于完美,使其能夠解決實際生活中的抽象問題。


二、數據的預處理

1.數據分類

我們所用到的數據都存放在train.csv文件里面,文件的結構如下:


其中,lable是單張圖片的標簽,不同的值對應不同的表情:

valueemotion
0angry
1disgust
2fear
3happy
4sad
5surprise
6neutral

feature是單張圖片的字符串編碼,每一串編碼由28 * 28 = 784組字符串組成,每組字符串對應一個像素的灰度圖。

在預處理階段,我們需要將train.scv文件中的所有圖像提取出來,分為train_data和val_data,分別作為訓練集與驗證集,并存放到各自的文件夾。
同時,建立train_data.csv與val_data.csv存放文件名到該文件標簽的映射


2.代碼

""" 該文件將原數據‘train.csv’分離 圖片分離到train_data, val_data兩個文件夾中 并創建train_data_set.csv與val_data_set.csv來標注數據 """ import pandas as pd import cv2 as cv import numpy as np import osdef classify():"""將數據分為訓練集與數據集并儲存:return:"""# 數據預處理# 將label與人臉數據作拆分path = './train.csv'all_data = pd.read_csv(path)# 將百分之70的數據作為訓練集train_num = int(all_data.shape[0] * 0.7)train_data = all_data.loc[0: train_num]val_data = all_data.loc[train_num:]print(train_data)save_img_and_label(train_data, './train_data', './train_data_set.csv')save_img_and_label(val_data, './val_data', './val_data_set.csv')def save_img_and_label(data: pd.DataFrame, img_save_path, csv_save_path):"""保存數據中的圖片并對其標注"""if not os.path.exists(img_save_path):os.mkdir(img_save_path)img_name_list = []img_label_list = []for i in range(len(data)):# 生成文件名img_name = '{}.jpg'.format(i)# 讀取csv文件中字符串類型的圖片img_str = data[['feature']].values[i][0]img_label = str(data[['label']].values[i][0])# 分隔字符串,得到每個像素點的灰度img_list = img_str.split(' ')# 轉化為darray數組并保存img = np.array(img_list, dtype=np.int32).reshape((48, 48))cv.imwrite(img_save_path + '/' + img_name, img)img_name_list.append(img_name)img_label_list.append(img_label)# 保存數據save_data = pd.DataFrame(img_label_list, index=img_name_list)save_data.to_csv(csv_save_path, header=False)# 調用執行 classify()

運行完成后結果如下


train_data里面的東西


train_data_set.csv里面的東西


三、構建模型與訓練

1.模型與代碼

使用的模型參考了如下A模型


代碼如下
文件名train_model.py

""" 訓練模型 """ import torch import torch.utils.data as data from torch.utils.data.dataset import T_co import pandas as pd import numpy as np import cv2 as cv import torch.nn as nn from torch import optimclass FaceDateset(data.Dataset):"""加載數據的類"""def __init__(self, img_dir, data_set_path):self.img_dir = img_dirself.label_path = data_set_path# 讀取csvimg_names = pd.read_csv(data_set_path, header=None, usecols=[0])img_labels = pd.read_csv(data_set_path, header=None, usecols=[1])# 轉化為一維np數組self.img_names = np.array(img_names)[:, 0]self.img_labels = np.array(img_labels)[:, 0]def __getitem__(self, index) -> T_co:# 記載圖片路徑img_path = self.img_dir + '/' + self.img_names[index]# 讀取圖片img = cv.imread(img_path)# 轉化為灰度img = cv.cvtColor(img, cv.COLOR_BGR2GRAY)# 直方圖均衡img = cv.equalizeHist(img)# 標準化輸入并進行歸一化img = img.reshape((1, 48, 48)) / 255.0# 轉化為torch圖片img_torch = torch.from_numpy(img).type('torch.FloatTensor')label = self.img_labels[index]return img_torch, labeldef __len__(self):return self.img_names.shape[0]def gaussian_weights_init(m):"""參數初始化,采用高斯分布"""classname = m.__class__.__name__if classname.find('Conv') != -1:m.weight.data.normal_(0.0, 0.04)def validate(model, dataset, batch_size):"""驗證模型在驗證集上的正確率"""val_loader = data.DataLoader(dataset, batch_size)result, num = 0.0, 0for images, labels in val_loader:pred = model.forward(images)pred = np.argmax(pred.data.numpy(), axis=1)labels = labels.data.numpy()result += np.sum((pred == labels))num += len(images)acc = result / numreturn accclass FaceCNN(nn.Module):"""CNN神經網絡"""def __init__(self):super().__init__()# 第一層卷積、池化self.conv1 = nn.Sequential(nn.Conv2d(in_channels=1, out_channels=64, kernel_size=3, stride=1, padding=1), # 卷積層nn.BatchNorm2d(num_features=64), # 歸一化nn.RReLU(inplace=True), # 激活函數nn.MaxPool2d(kernel_size=2, stride=2), # 最大值池化)# 第二層卷積、池化self.conv2 = nn.Sequential(nn.Conv2d(in_channels=64, out_channels=128, kernel_size=3, stride=1, padding=1),nn.BatchNorm2d(num_features=128),nn.RReLU(inplace=True),# output:(bitch_size, 128, 12 ,12)nn.MaxPool2d(kernel_size=2, stride=2),)# 第三層卷積、池化self.conv3 = nn.Sequential(nn.Conv2d(in_channels=128, out_channels=256, kernel_size=3, stride=1, padding=1),nn.BatchNorm2d(num_features=256),nn.RReLU(inplace=True),# output:(bitch_size, 256, 6 ,6)nn.MaxPool2d(kernel_size=2, stride=2),)# 參數初始化self.conv1.apply(gaussian_weights_init)self.conv2.apply(gaussian_weights_init)self.conv3.apply(gaussian_weights_init)# 全連接層self.fc = nn.Sequential(nn.Dropout(p=0.2),nn.Linear(in_features=256 * 6 * 6, out_features=4096),nn.RReLU(inplace=True),nn.Dropout(p=0.5),nn.Linear(in_features=4096, out_features=1024),nn.RReLU(inplace=True),nn.Linear(in_features=1024, out_features=256),nn.RReLU(inplace=True),nn.Linear(in_features=256, out_features=7),)def forward(self, x):"""前向傳播"""# print(x.shape)x = self.conv1(x)x = self.conv2(x)x = self.conv3(x)# 數據扁平化x = x.view(x.shape[0], -1)y = self.fc(x)return ydef train(lr=0.01, weight_decay=0, batch_size=128, epochs=100):"""訓練模型"""# 加載數據train_data_set = FaceDateset('train_data', 'train_data_set.csv')val_data_set = FaceDateset('val_data', 'val_data_set.csv')train_loader = data.DataLoader(train_data_set, batch_size)# 構建神經網絡model = FaceCNN()# 損失函數loss_fun = nn.CrossEntropyLoss()# 優化器optimizer = optim.Adam(model.parameters(), lr=lr, weight_decay=weight_decay)# 記錄損失值與正確率loss_log = open('loss_log.txt', 'w')acc_log = open('acc_log.txt', 'w')for epoch in range(epochs):# 損失函數值print('第{}輪訓練開始'.format(epoch))loss_rate = 0model.train()for images, labels in train_loader:# 梯度清零optimizer.zero_grad()# 前向轉播out_put = model.forward(images)# 計算誤差值loss_rate = loss_fun(out_put, labels)# 反向傳播loss_rate.backward()optimizer.step()# 保存損失值loss_log.write('{}\n'.format(loss_rate.item()))loss_log.flush()print('第{}輪損失值為:{}'.format(epoch, loss_rate.item()))# 計算并保存正確率,保存模型if epoch % 5 == 0:acc = validate(model, val_data_set, batch_size)print('第{}輪正確率為:{}'.format(epoch, acc))acc_log.write('{}, {}\n'.format(epoch, acc))acc_log.flush()torch.save(model, './models/train_{}.pkl'.format(epoch))loss_log.close()acc_log.close()if __name__ == '__main__':train()

文件名show_log.py

""" 可視化結果 """ import matplotlib.pyplot as plt import numpy as npdef cvt_file2np(log_file_path):"""讀取log文件并轉化為np數組"""log = np.genfromtxt(log_file_path, delimiter=',')if log.ndim != 1:x = np.array(log[:, 0])y = np.array(log[:, 1])else:length = log.shape[0]x = np.arange(0, length)y = logreturn [x, y]acc_data = cvt_file2np('acc_log.txt') loss_data = cvt_file2np('loss_log.txt') loss_data[1] = loss_data[1] + 0.0000001 loss_data[1] = np.log10(loss_data[1])plt.subplot(121) plt.plot(acc_data[0], acc_data[1]) plt.title('acc') plt.xlabel('epoch') plt.ylabel('acc')plt.subplot(122) plt.plot(loss_data[0], loss_data[1]) plt.title('log10(loss)') plt.xlabel('iteration') plt.ylabel('log10(loss)') plt.show()

2.使用方法

首先運行train_model.py文件訓練模型,這里采用的是cup運算,非常花費時間。
運行完成后模型會保存到根目錄的models文件夾下,每訓練5個epoch保存一次。
訓練完成后,運行show_log.py將訓練結果可視化,例如:

不難看出,訓練到第35輪時正確率最高,之后數據發生了過擬合,正確率開始下降。


四、實時識別

使用opencv來打開攝像頭,實現對圖像中人臉的實時識別
(由于課設中不需要使用gui顯示圖像,所以設置了一個變量gui_open來控制是否顯示gui)
代碼如下:
文件名:my_face.py

""" 表情識別 """ import cv2 as cv import dlib import numpy as np import torch from train_model import FaceCNN from my_utils import get_face_target, labels, soft_max, cvt_R2N import warnings warnings.filterwarnings("ignore")class EmotionIdentify:"""用于表情識別的類"""def __init__(self, gui_open=False):# 使用特征提取器get_frontal_face_detectorself.detector = dlib.get_frontal_face_detector()# 加載CNN模型self.model = FaceCNN()self.model.load_state_dict(torch.load('./models/train_35.pkl').state_dict())# 建cv2攝像頭對象,這里使用電腦自帶攝像頭,如果接了外部攝像頭,則自動切換到外部攝像頭self.cap = cv.VideoCapture(0)# 設置視頻參數,propId設置的視頻參數,value設置的參數值self.cap.set(3, 480)# 截圖screenshot的計數器self.img = Noneself.gui_open = gui_opendef get_img_and_predict(self):"""表情識別:return:(img, emotion)"""gray_img, left_top, right_bottom, result = None, None, None, Noneif self.cap.isOpened():# 從攝像頭讀取圖像flag, img = self.cap.read()self.img = imgimg_gray = cv.cvtColor(img, cv.COLOR_RGB2GRAY)# 使用人臉檢測器檢測每一幀圖像中的人臉。并返回人臉數rectsfaces = self.detector(img_gray, 0)if len(faces) > 0:# 只取第一張臉face = faces[0]left_top = (face.left(), face.top())right_bottom = (face.right(), face.bottom())# 轉化為灰度圖片并提取目標gray_img = cv.cvtColor(img, cv.COLOR_BGR2GRAY)gray_img = get_face_target(gray_img, face)# 將目標大小重置為神經網絡的輸入大小gray_img = cv.resize(gray_img, (48, 48))target_img = gray_img.reshape((1, 1, 48, 48)) / 255.0img_torch = torch.from_numpy(target_img).type('torch.FloatTensor')result = self.model(img_torch).detach().numpy()result = soft_max(result)if self.gui_open:self.show(gray_img, left_top, right_bottom, result)return self.img, resultraise Exception('No camera')def show(self, gray_img, left_top, right_bottom, result):"""顯示圖像"""show_img = self.imgif gray_img is not None:cv.imshow('gray_img', gray_img)color = (255, 34, 78)cv.rectangle(show_img, left_top, right_bottom, color, 2)emotion = labels[np.argmax(result)]cv.putText(show_img, emotion, left_top, 0, 2, color, 2)cv.imshow('cv', show_img)cv.waitKey(20)def my_test():ed = EmotionIdentify(gui_open=True)flag = Truewhile flag is not None:flag = ed.get_img_and_predict()cv.waitKey(10)result = flag[1]print(cvt_R2N(result))if __name__ == '__main__':my_test()
依賴工具my_utils.py """ 使用的工具 """ import numpy as nplabels = {0: 'angry', 1: 'disgust', 2: 'fear', 3: 'happy',4: 'sad', 5: 'surprise', 6: 'neutral'}def get_face_target(gray_img: np.ndarray, face):"""從gray_img中提取面部圖像:param gray_img::param face::return:"""img_size = gray_img.shape# print(img_size)x1, y1, x2, y2 = face.left(), face.top(), face.right(), face.bottom()def reset_point(point, max_size):"""重置點的位置:param point: 當前點的坐標:param max_size: 點在坐標軸的上的最大位置:return:"""if point < 0:point = 0if point > max_size:point = max_size - 1return pointx1 = reset_point(x1, img_size[0])x2 = reset_point(x2, img_size[0])y1 = reset_point(y1, img_size[1])y2 = reset_point(y2, img_size[1])return gray_img[y1:y2, x1:x2]def soft_max(x):"""classify"""exp_x = np.exp(x)sum_x = np.sum(exp_x)y = exp_x / sum_xreturn ydef cvt_R2N(result):"""將神經網絡預測的結果轉化為0-100的數值"""if result is None:return 80cvt_M = [70, 20, 60, 100, 10, 90, 80]cvt_M = np.array(cvt_M)level = np.sum(cvt_M * result)return level

結果如下:

注:cvt_R2N()函數該項目用不到


總結

該項目的項目樹如下

  • data_classfy.py
  • my_face.py
  • my_utils.py
  • show_log.py
  • train.csv
  • train_model.py

總結

以上是生活随笔為你收集整理的深度学习项目,使用python进行表情识别,pytorch应用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产精品无码久久久久 | 日日干夜 | 在线观看自拍 | 男男大尺度| 黄色aaa视频 | 成人涩涩 | 亚洲污片 | 日韩黄色影视 | 一区二区三区在线观 | 依人久久 | 久久久亚洲综合 | 91麻豆精品国产午夜天堂 | 色乱码一区二区三区在线男奴 | 99热这里都是精品 | 精品人妻久久久久一区二区三区 | 人妻无码久久一区二区三区免费 | 朋友人妻少妇精品系列 | 成人伊人 | 中文字幕人妻丝袜乱一区三区 | 闫嫩的18sex少妇hd | 国产大片黄| 韩国三级hd两男一女 | 国产精品自拍99 | 亚洲精品不卡 | 国产精品99 | 毛茸茸毛片 | 国产激情网 | 亚洲大色| 丰满雪白极品少妇流白浆 | 蜜桃99视频一区二区三区 | 久久久免费高清视频 | 国产精品老牛影院99av | 中国极品少妇xxxx做受 | 老司机性视频 | 高潮无码精品色欲av午夜福利 | 天天干人人干 | a资源在线观看 | 古装三级吃奶做爰 | 亚洲免费在线观看av | 日本在线精品视频 | 国产91久久婷婷一区二区 | 嫩草影院av| 国产真人无码作爱视频免费 | 欧美成人性生活视频 | 五月婷婷影院 | h片在线 | 伊人激情综合网 | 怡红院院av | 麻豆 国产 | 欧美亚洲国产视频 | 欧美视频a | 伊人成综合网 | 激情三级在线 | www.爱色av.com| 欧美日韩一区二区视频观看 | 色花av| 久久婷婷五月综合色国产香蕉 | 兔费看少妇性l交大片免费 日韩高清不卡 | 国产香蕉在线观看 | 亚洲欧洲精品一区二区 | aaa一级黄色片 | 在线观看黄色的网站 | 97超在线 | 日韩在线免费观看视频 | 国产一二在线观看 | 欧美污视频| 高h喷水荡肉少妇爽多p视频 | 中文字幕欧美另类精品亚洲 | 99热影院 | 国产人成视频在线观看 | 国内免费毛片 | 五月婷婷久久综合 | 日本视频三区 | 羽月希奶水一区二区三区 | 天天射日日干 | 久久精品99久久久久久久久 | 国产人澡人澡澡澡人碰视频 | 懂色av蜜臀av粉嫩av分 | 亚洲AV无码国产精品播放在线 | 色涩涩| 亚洲手机视频 | 毛片精品| 欧美成人久久久 | 18禁男女爽爽爽午夜网站免费 | 成人小视频在线看 | 69精品人人 | 中文字幕大全 | 97影院在线午夜 | 91日日| 夫妻精品| 少妇自拍视频 | 欧美成人午夜电影 | 日本免费一区二区三区四区五六区 | 96日本xxxxxⅹxxx17 | a√在线观看 | 日韩在线一区视频 | 日本一级三级三级三级 | 夜夜操导航 | 男女高潮网站 |