基于深度学习的人脸情绪识别检测系统(VGG、CNN、ResNet)

第一部分:情绪识别模型训练部分,算法三种(CNN、VGG、ResNet)

1、基本表情介绍

人类的面部表情至少有21种,除了常见的高兴、吃惊、悲伤、愤怒、厌恶和恐惧6种,还有惊喜(高兴+吃惊)、悲愤(悲伤+愤怒)等15种可被区分的复合表情。详细介绍可以阅读下面博主的系列文章:
https://link.zhihu.com/target=https%3A//mp.weixin.qq.com/s%3F__biz%3DMzA3NDIyMjM1NA%3D%3D%26mid%3D2649039958%26idx%3D1%26sn%3Dbdbbb3690b8b23e107c56e14b72bf589%26chksm%3D87129a2bb065133d971793c1ca14b053737b593a5702c8375c5da5d328f0d422922ea7531b9b%26token%3D1054133372%26lang%3Dzh_CN%23rd
在这里插入图片描述
在这里插入图片描述

2、数据采集和训练

人脸情绪识别的训练数据有Kaggle和自行采集本地数据2种方式。
在这里插入图片描述
Fer2013人脸表情数据集由35886张人脸表情图片组成,其中,测试图(Training)28708张,公共验证图(PublicTest)和私有验证图(PrivateTest)各3589张,每张图片是由大小固定为48×48的灰度图像组成,共有7种表情,分别对应于数字标签0-6,具体表情对应的标签和中英文如下:
0 anger 生气;
1 disgust 厌恶;
2 fear 恐惧;
3 happy 开心;
4 sad 伤心;
5 surprised 惊讶;
6 normal 中性。
数据集下载地址
在这里插入图片描述

FER2013数据集

FER2013数据集由28709张训练图,3589张公开测试图和3589张私有测试图组成。每一张图都是像素为48*48的灰度图。FER2013数据库中一共有7中表情:愤怒,厌恶,恐惧,开心,难过,惊讶和中性。分别对应于数字标签0-6,具体表情对应的标签和中英文如下:0 anger 生气; 1 disgust 厌恶; 2 fear 恐惧; 3 happy 开心; 4 sad 伤心;5 surprised 惊讶; 6 normal 中性。

该数据库是2013年Kaggle比赛的数据,由于这个数据库大多是从网络爬虫下载的,存在一定的误差性。这个数据库的人为准确率是65% 士 5%。Kaggle的官网,数据、科学、机器学习比赛等。

3、数据清洗

在下载原文件中,emotion和pixels(像素)人脸像素数据是整合在一起的。为了方便操作,决定利用pandas库进行数据分离,即将所有emotion数据读出后,写入新创建的文件emotion.csv中去;将所有的像素数据读出后,写入新创建的文件pixels.csv文件中去。
pandas教程

  1. 关于.CSV文件,大小为28710行X2305列;

  2. 总计28710行中,其中第一行为描述信息即“emotion”和“pixels”两个单词,其余每行内含有一个样本信息,即共有28709个样本;

  3. 在2305列中,其中第一列为该样本对应的emotion,取值范围为0-6。其余2304列为包含着每个样本大小为48X48人脸图片的像素值(2304=48X48),每个像素值取值范围在0到255之间;

    像素值列表

实现代码如下:data_separation.py
# 将emotion和pixels像素数据分离
import pandas as pd

# 注意train.csv是在你电脑本地的相对或绝对路劲地址
path = 'dataset/train.csv'
# 读取数据
df = pd.read_csv(path)
# 提取emotion数据
df_y = df[['emotion']]
# 提取pixels数据
df_x = df[['pixels']]
# 将emotion写入emotion.csv
df_y.to_csv('dataset/emotion.csv', index=False, header=False)
# 将pixels数据写入pixels.csv
df_x.to_csv('dataset/pixels.csv', index=False, header=False)


此时,在dataset的文件夹下,就会生成两个新文件emotion.csv以及pixels.csv。在执行代码前,注意修改train.csv为你电脑上文件所在的相对或绝对路径。

4、将像素值数据还原为图片

  1. 给定的数据集是.csv格式的,考虑到图片分类问题的常规做法,决定先将其全部可视化,还原为图片文件后再进行图像数据处理。

  2. 在python环境下,将csv中的像素数据还原为图片并保存下来,有很多图片数据处理库都能实现类似的功能,如Pillow,opencv等。这里我采用的是用opencv来实现这一功能。

  3. 将数据分离后,人脸像素数据全部存储在pixels.csv文件中,其中每行数据就是一张人脸。按行读取数据,利用opencv将每行的2304个数据恢复为一张48X48的人脸图片,并保存为jpg格式。在保存这些图片时,将第一行数据恢复出的人脸命名为0.jpg,第二行的人脸命名为1.jpg…,以方便与label[0]、label[1]…一一对应。所以建立image-emotion映射关系表还是相当有必要的。

4.实现代码如下

import cv2
import numpy as np
# 指定存放图片的路径path = 'face_images'# 读取像素数据data = np.loadtxt('dataset/pixels.csv')
# 按行取数据for i in range(data.shape[0]):
    face_array = data[i, :].reshape((48, 48)) # reshape
cv2.imwrite(path + '//' + '{}.jpg'.format(i), face_array) # 写图片

涉及到大量数据的读取和大批图片的写入,因此占用的内存资源较多,且执行时间较长(视机器性能而定,一般要几分钟到十几分钟不等)。代码执行完毕,我们来到指定的图片存储路径,就能发现里面全部是写好的人脸图片。
人脸图像数据
这里总共写入有28709张人脸图片数据

5、创建映射表

创建image图片名和对应emotion表情数据集的映射关系表。

  1. 我们需要划分一下训练集和验证集。在项目中,共有28709张图片,取前24000张图片作为训练集,其他图片作为验证集。在工程文件夹face_images下新建文件夹train_set和verify_set,将0.jpg到23999.jpg放进文件夹train_set,将其他图片放进文件夹verify_set。在继承torch.utils.data.Dataset类定制自己的数据集时,由于在数据加载过程中需要同时加载出一个样本的数据及其对应的emotion,因此最好能建立一个image的图片名和对应emotion表情数据的关系映射表,其中记录着image的图片名和其emotion表情数据的映射关系。
  2. 实现源码:image_emotion_mapping.py
def image_emotion_mapping(path):
    # 读取emotion文件
    df_emotion = pd.read_csv('dataset/emotion.csv', header = None)
    # 查看该文件夹下所有文件
    files_dir = os.listdir(path)
    # 用于存放图片名
    path_list = []
    # 用于存放图片对应的emotion
    emotion_list = []
    # 遍历该文件夹下的所有文件
    for file_dir in files_dir:
        # 如果某文件是图片,则将其文件名以及对应的emotion取出,分别放入path_list和emotion_list这两个列表中
        if os.path.splitext(file_dir)[1] == ".jpg":
            path_list.append(file_dir)
            index = int(os.path.splitext(file_dir)[0])
            emotion_list.append(df_emotion.iat[index, 0])

    # 将两个列表写进image_emotion.csv文件
    path_s = pd.Series(path_list)
    emotion_s = pd.Series(emotion_list)
    df = pd.DataFrame()
    df['path'] = path_s
    df['emotion'] = emotion_s
    df.to_csv(path+'\\image_emotion.csv', index=False, header=False)


def main():
    # 指定文件夹路径
    train_set_path = 'face_images/train_set'
    verify_set_path = 'face_images/verify_set'
    image_emotion_mapping(train_set_path)
    image_emotion_mapping(verify_set_path)

代码执行完毕后,会在train_set和verify_set文件夹下各生成一个名为image-emotion.csv的关系映射表。
映射表序号排列
映射表

6、加载数据集

现在我们有了图片,但怎么才能把图片读取出来送给模型呢?一般在平常的时候,我们第一个想到的是将所有需要的数据聚成一堆一堆然后通过构建list去读取我们的数据:

假如我们编写了上述的图像加载数据集代码,在训练中我们就可以依靠get_training_data()这个函数来得到batch_size个数据,从而进行训练,乍看下去没什么问题,但是一旦我们的数据量超过1000:
将所有的图像数据直接加载到numpy数据中会占用大量的内存
由于需要对数据进行导入,每次训练的时候在数据读取阶段会占用大量的时间
只使用了单线程去读取,读取效率比较低下
拓展性很差,如果需要对数据进行一些预处理,只能采取一些不是特别优雅的做法
如果用opencv将所有图片读取出来,最简单粗暴的方法就是直接以numpy中array的数据格式直接送给模型。如果这样做的话,会一次性把所有图片全部读入内存,占用大量的内存空间,且只能使用单线程,效率不高,也不方便后续操作。
既然问题这么多,到底说回来,我们应该如何正确地加载数据集呢?
其实在pytorch中,有一个类(torch.utils.data.Dataset)是专门用来加载数据的,我们可以通过继承这个类来定制自己的数据集和加载方法。
Dataset类是Pytorch中图像数据集中最为重要的一个类,也是Pytorch中所有数据集加载类中应该继承的父类。其中父类中的两个私有成员函数必须被重载,否则将会触发错误提示:

def getitem(self, index):
def len(self):

其中__len__应该返回数据集的大小,而__getitem__应该编写支持数据集索引的函数,例如通过dataset[i]可以得到数据集中的第i+1个数据。

class Dataset(object):
"""An abstract class representing a Dataset.
All other datasets should subclass it. All subclasses should override
``__len__``, that provides the size of the dataset, and ``__getitem__``,
supporting integer indexing in range from 0 to len(self) exclusive.
"""
#这个函数就是根据索引,迭代的读取路径和标签。因此我们需要有一个路径和标签的 ‘容器’供我们读
def __getitem__(self, index):
	raise NotImplementedError
#返回数据的长度
def __len__(self):
	raise NotImplementedError
def __add__(self, other):
	return ConcatDataset([self, other])

我们通过继承Dataset类来创建我们自己的数据加载类,命名为FaceDataset,完整代码如下请看代码:Dataset.py

模型训练

这里采用的是基于 CNN 的优化模型,这个模型是源于github一个做表情识别的开源项目,可惜即使借用了这个项目的模型结构,但却没能达到源项目中的精度(acc在74%)。下图为该开源项目中公布的两个模型结构,这里我采用的是 Model B ,且只采用了其中的卷积-全连接部分。CNN训练模型代码开源
这里:算法参考的论文原稿我已经下载文原版在参考文献文件夹下有。需要的(V我:ZQZ2551931023)
论文PDF
原文网址
对比如下
在这里插入图片描述
CNN模型

CNN模型和算法原理实现

下图我们可以看出,在 Model B 的卷积部分,输入图片 shape 为 48X48X1,经过一个3X3X64卷积核的卷积操作,再进行一次 2X 2的池化,得到一个 24X24X64 的 feature map 1(以上卷积和池化操作的步长均为1,每次卷积前的padding为1,下同)。将 feature map 1经过一个 3X3X128 卷积核的卷积操作,再进行一次2X2的池化,得到一个 12X12X128 的 feature map 2。将feature map 2经过一个 3X3X256 卷积核的卷积操作,再进行一次 2X2 的池化,得到一个 6X6X256 的feature map 3。卷积完毕,数据即将进入全连接层。进入全连接层之前,要进行数据扁平化,将feature map 3拉一个成长度为 6X6X256=9216 的一维 tensor。随后数据经过 dropout 后被送进一层含有4096个神经元的隐层,再次经过 dropout 后被送进一层含有 1024 个神经元的隐层,之后经过一层含 256 个神经元的隐层,最终经过含有7个神经元的输出层。一般再输出层后都会加上 softmax 层,取概率最高的类别为分类结果。
CNN模型
通过数据的前向传播和误差的反向传播来训练模型了。在此之前,还需要指定优化器(即学习率更新的方式)、损失函数以及训练轮数、学习率等超参数。在本项目中,采用的优化器是SGD,即随机梯度下降,其中参数weight_decay为正则项系数;损失函数采用的是交叉熵;可以考虑使用学习率衰减。

实现代码:model_CNN.py

class FaceCNN(nn.Module):
    # 初始化网络结构
    def __init__(self):
        super(FaceCNN, self).__init__()

        # 第一次卷积、池化
        self.conv1 = nn.Sequential(
            # 输入通道数in_channels,输出通道数(即卷积核的通道数)out_channels,卷积核大小kernel_size,步长stride,对称填0行列数padding
            # input:(bitch_size, 1, 48, 48), output:(bitch_size, 64, 48, 48), (48-3+2*1)/1+1 = 48
            nn.Conv2d(in_channels=1, out_channels=64, kernel_size=3, stride=1, padding=1), # 卷积层
            nn.BatchNorm2d(num_features=64), # 归一化
            nn.RReLU(inplace=True), # 激活函数
            # output(bitch_size, 64, 24, 24)
            nn.MaxPool2d(kernel_size=2, stride=2), # 最大值池化
        )

        # 第二次卷积、池化
        self.conv2 = nn.Sequential(
            # input:(bitch_size, 64, 24, 24), output:(bitch_size, 128, 24, 24), (24-3+2*1)/1+1 = 24
            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(
            # input:(bitch_size, 128, 12, 12), output:(bitch_size, 256, 12, 12), (12-3+2*1)/1+1 = 12
            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):
        x = self.conv1(x)
        x = self.conv2(x)
        x = self.conv3(x)
        # 数据扁平化
        x = x.view(x.shape[0], -1)
        y = self.fc(x)
        return y

def train(train_dataset, val_dataset, batch_size, epochs, learning_rate, wt_decay):
    # 载入数据并分割batch
    train_loader = data.DataLoader(train_dataset, batch_size)
    # 构建模型
    model = FaceCNN()
    # 损失函数
    loss_function = nn.CrossEntropyLoss()
    # 优化器
    optimizer = optim.SGD(model.parameters(), lr=learning_rate, weight_decay=wt_decay)
    # 学习率衰减
    # scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=10, gamma=0.8)
    # 逐轮训练
    for epoch in range(epochs):
        # 记录损失值
        loss_rate = 0
        # scheduler.step() # 学习率衰减
        model.train() # 模型训练
        for images, emotion in train_loader:
            # 梯度清零
            optimizer.zero_grad()
            # 前向传播
            output = model.forward(images)
            # 误差计算
            loss_rate = loss_function(output, emotion)
            # 误差的反向传播
            loss_rate.backward()
            # 更新参数
            optimizer.step()

        # 打印每轮的损失
        print('After {} epochs , the loss_rate is : '.format(epoch+1), loss_rate.item())
        if epoch % 5 == 0:
            model.eval() # 模型评估
            acc_train = validate(model, train_dataset, batch_size)
            acc_val = validate(model, val_dataset, batch_size)
            print('After {} epochs , the acc_train is : '.format(epoch+1), acc_train)
            print('After {} epochs , the acc_val is : '.format(epoch+1), acc_val)

    return model

代码测试结果如下:

在这里插入图片描述
训练模型保存在文件下为:model_resnet.pkl
训练过程

8、模型优化(VGG、ResNet)与算法改进

我们可以用理论部分提出的另外两种模型VGG模型和ResNet模型,对现有的项目进行优化,提升识别的准确度(三种算法已经实现),模型训练也已经完成。
此处省略----

9、本地数据采集[图像采集补充]

在这里插入图片描述

源码实现如下:

class FaceRecognition:
    def __init__(self, master):
        self.master = master
        self.master.title('CNN人脸识别')
        self.frame = Frame(self.master)
        self.frame.pack(pady=10)

        # 创建按钮
        self.button1 = Button(self.frame, text='采集人脸数据', command=self.collect_face)
        self.button1.pack(side=LEFT, padx=10)
        self.button2 = Button(self.frame, text='训练模型', command=self.train_model)
        self.button2.pack(side=LEFT, padx=10)
        self.button3 = Button(self.frame, text='人脸识别', command=self.start_recognition)
        self.button3.pack(side=LEFT, padx=10)
        self.button4 = Button(self.frame, text='退出程序', command=self.master.quit)
        self.button4.pack(side=LEFT, padx=10)

        # 创建文本框用于显示结果
        self.text = Text(self.master, width=30, height=10)
        self.text.pack(pady=10)

        # 加载模型
        self.model = tf.keras.models.load_model(r'model/model.h5')

        # 获取分类器
        self.haar = cv2.CascadeClassifier(r'haarcascade_frontalface_default.xml')

        # 获取人脸识别器
        self.detector = dlib.get_frontal_face_detector()

        # 创建显示图片的标签
        self.img_label = Label(self.master)
        self.img_label.pack()

        # 创建关闭人脸识别按钮
        self.close_button = Button(self.master, text='关闭人脸识别', command=self.close_recognition)
        self.close_button.pack()

        # 是否进行人脸识别的标志
        self.recognition_flag = False

    # 采集人脸数据
    def collect_face(self):
        out_dir = './my_faces'
        if not os.path.exists(out_dir):
            os.makedirs(out_dir)

        # 改变亮度与对比度
        def relight(img, alpha=1, bias=0):
            w = img.shape[1]
            h = img.shape[0]
            # image = []
            for i in range(0, w):
                for j in range(0, h):
                    for c in range(3):
                        tmp = int(img[j, i, c] * alpha + bias)
                        if tmp > 255:
                            tmp = 255
                        elif tmp < 0:
                            tmp = 0
                        img[j, i, c] = tmp
            return img

        # 打开摄像头 参数为输入流,可以为摄像头或视频文件
        camera = cv2.VideoCapture(0)

        n = 1
        while 1:
            if (n <= 5000):
                print('It`s processing %s image.' % n)
                # 读帧
                success, img = camera.read()
                gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
                faces = self.haar.detectMultiScale(gray_img, 1.3, 5)
                for f_x, f_y, f_w, f_h in faces:
                    face = img[f_y:f_y + f_h, f_x:f_x + f_w]
                    face = cv2.resize(face, (64, 64))

                    face = relight(face, random.uniform(0.5, 1.5), random.randint(-50, 50))
                    cv2.imshow('img', face)
                    cv2.imwrite(out_dir + '/' + str(n) + '.jpg', face)
                    n += 1
                key = cv2.waitKey(30) & 0xff
                if key == 27:
                    break
            else:
                break

10、人脸情绪识别系统设与实现

测试效果

核心源码(Q:2551931023)

class EmotionClassifier:
    def __init__(self):
        self.face_cascade = cv2.CascadeClassifier(
            r".\datasets\haarcascade_frontalface_default.xml")
        self.model = Model()
        self.model.load_state_dict(
            torch.load(r'.\model\model_params.pkl', map_location='cpu'))
        self.model.eval()

    def get_emotion(self, inputs):
        inputs = self.preprocess(inputs)
        _, predicted = torch.max(self.model(inputs), 1)
        probability = F.softmax((self.model(inputs)), dim=1).detach().numpy().flatten()
        emotion = {
            0: 'angry',
            1: 'disgust',
            2: 'fear',
            3: 'happy',
            4: 'sad',
            5: 'surprised',
            6: 'normal'
        }
        return emotion[predicted.item()], probability

    def preprocess(self, inputs):
        trans = transforms.Compose([
            transforms.Grayscale(),
            transforms.ToTensor(),
        ])
        inputs = trans(inputs)
        inputs = inputs.unsqueeze(0)
        return inputs

class App:
    def __init__(self, video_source=0):
        self.window = Tk()
        self.window.title('基于CNN的情绪识别系统')
        self.video_source = video_source
        self.emo_cls = EmotionClassifier()
        self.canvas = Canvas(self.window, width=640, height=480)
        self.canvas.pack(side=LEFT)

        self.results_label = Label(self.window, text='情绪结果:', font=('Arial', 24), padx=20, pady=10)
        self.results_label.pack(side=TOP)

        self.bar_canvas = Canvas(self.window, width=320, height=240)
        self.bar_canvas.pack(side=TOP)

        self.quit_button = Button(self.window, text='退出系统', font=('Arial', 18), command=self.window.quit)
        self.quit_button.pack(side=BOTTOM, padx=20, pady=10)

        self.delay = 10
        self.update()

        self.window.mainloop()

    def update(self):
        ret, frame = cap.read()
        if ret:
            frame = cv2.flip(frame, 1)
            img = Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
            rendered_img = ImageTk.PhotoImage(img)
            self.canvas.img = rendered_img
            self.canvas.create_image(0, 0, anchor=NW, image=rendered_img)

            gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
            faces = self.emo_cls.face_cascade.detectMultiScale(gray, 1.3, 5)
            for (x, y, w, h) in faces:
                face = cv2.resize(frame[y:(y + h), x:(x + w)], (42, 42))
                emotion, probability = self.emo_cls.get_emotion(Image.fromarray(face))
                results_str = '情绪检测结果:{}'.format(emotion)
                self.results_label.config(text=results_str)

                self.bar_canvas.delete('all')
                bar_height = self.bar_canvas.winfo_height()
                bar_width = self.bar_canvas.winfo_width()
                max_prob = np.max(probability)
                prob_heights = [int(round(x / max_prob * bar_height)) for x in probability]
                prob_colors = ['red', 'blue', 'green', 'yellow', 'purple', 'brown', 'orange']
                for i in range(len(prob_heights)):
                    start_x = 0
                    start_y = bar_height / len(prob_heights) * i
                    end_x = prob_heights[i] / bar_height * bar_width
                    end_y = bar_height / len(prob_heights) * (i + 1)

                    # 拼接情绪标签、表情和百分比
                    emotion_text = ['愤怒', '厌恶', '恐惧', '高兴', '悲伤', '惊讶', '正常'][i]
                    emoji_text = ['Anger ',' disgust ', 'fear ',' happy ', 'sad ',' surprise ', 'normal'][i]
                    prob_text = '{:.2f}%'.format(probability[i] * 100)
                    label_text = '{} {} {}'.format(emotion_text, emoji_text, prob_text)

                    label_x = end_x
                    label_y = (start_y + end_y) / 2
                    self.bar_canvas.create_rectangle(start_x, start_y, end_x, end_y, fill=prob_colors[i])
                    self.bar_canvas.create_text(label_x, label_y, text=label_text, font=('Arial', 12), anchor=W)

        self.window.after(self.delay, self.update)
【资源介绍】 1、该资源包括项目的全部源码,下载可以直接使用! 2、本项目适合作为计算机、数学、电子信息等专业的课程设计、期末大作业和毕设项目,也可以作为小白实战演练和初期项目立项演示的重要参考借鉴资料。 3、本资源作为“学习资料”如果需要实现其他功能,需要能看懂代码,并且热爱钻研和多多调试实践。 基于opencv与深度学习人脸情绪识别算法源码+数据集.zip 基于opencv与深度学习人脸情绪识别算法源码+数据集.zip 基于opencv与深度学习人脸情绪识别算法源码+数据集.zip 基于opencv与深度学习人脸情绪识别算法源码+数据集.zip 基于opencv与深度学习人脸情绪识别算法源码+数据集.zip 基于opencv与深度学习人脸情绪识别算法源码+数据集.zip 基于opencv与深度学习人脸情绪识别算法源码+数据集.zip 基于opencv与深度学习人脸情绪识别算法源码+数据集.zip 基于opencv与深度学习人脸情绪识别算法源码+数据集.zip 基于opencv与深度学习人脸情绪识别算法源码+数据集.zip 基于opencv与深度学习人脸情绪识别算法源码+数据集.zip 基于opencv与深度学习人脸情绪识别算法源码+数据集.zip 基于opencv与深度学习人脸情绪识别算法源码+数据集.zip 基于opencv与深度学习人脸情绪识别算法源码+数据集.zip 基于opencv与深度学习人脸情绪识别算法源码+数据集.zip
Deep情绪识别CNN(卷积神经网络)是一种深度学习模型,用于对文本或语音中的情绪进行识别。该模型采用卷积神经网络的结构,通过学习从原始输入特征直接获取情绪表示的能力。 在使用Deep情绪识别CNN之前,我们需要预处理数据集。首先,我们需要将文本或语音数据转换为向量表示,例如Word2Vec或TF-IDF向量。其次,我们需要将情绪标签进行编码,例如将“开心”编码为0,“悲伤”编码为1等。接下来,我们将数据集划分为训练集和测试集。 Deep情绪识别CNN的模型结构包括多层卷积层、池化层和全连接层。卷积层通过滑动窗口的方式,提取输入特征的局部关系。池化层通过取最大值或平均值的方式,对卷积层的输出进行降维,提取更加抽象的特征。最后,全连接层将池化层的输出映射到情绪标签空间,进行情绪分类。 在模型训练过程中,我们使用反向传播算法更新模型参数。我们通过最小化损失函数来优化模型,例如交叉熵损失函数。为了防止过拟合,我们可以使用正则化技术,如L2正则化和Dropout方法。 训练完模型后,我们可以使用Deep情绪识别CNN对未知文本或语音进行情绪识别。通过将未知输入传入模型,我们可以获取模型对应的输出情绪概率分布。根据最大概率或设置阈值,我们可以确定输入的情绪类别。 总的来说,Deep情绪识别CNN是一种强大的情绪识别模型,能够从文本或语音中准确地识别情绪。通过合适的数据预处理、模型训练和模型调优,我们可以得到更好的情绪识别效果。
评论 58
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

扫地僧985

喜欢就支持一下,谢谢老板!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值