基于pytorch卷积人脸表情识别--毕业设计

2023-11-10

前言

这篇文章记录一下我本科毕业设计的内容。我的课题是人脸表情识别,本来最开始按照历届学长的传统是采用MATLAB用传统的机器学习方法来实现分类的。但是鉴于我以前接触过一点点深度学习的内容,觉得用卷积神经来实现这个网络或许效果会好一点。于是我上网络上搜集了大量资料,照着做了一个基于Pytorch实现的卷积模型,加入了调用摄像头实时识别的程序。第一次接触机器视觉的东西,没有什么经验,还望指教。本次设计的参考来源于以下:
1.基于卷积神经网络的面部表情识别(Pytorch实现)–秋沐霖。链接:LINK
2.Pytorch基于卷积神经网络的人脸表情识别-marika。链接:LINK
3.Python神经网络编程-塔里克

毕业设计内容介绍

本文章使用Pytorch深度学习框架用卷积神经网络设计了人脸表情识别程序,将部分FER2013作为数据集进行训练,另一部分作为测试集。利用三层卷积层和四层全连接层对数据集进行模型训练,训练集精度能够达到99.4%,测试集精度最高达到60.5%。同时利用训练好的模型设计了实时人脸表情识别系统,能够调用摄像头对人脸表情进行实时分析,能够识别出基本的表情类别并通过标签显示在窗口上,同时展示系统判定的概率大小。

卷积神经网络的设计

卷积网络的模型

数据集选用的是FER2013{百度网盘链接:Link}
链接:https://pan.baidu.com/s/1MTQ12vq60vVOWIPTLlfOGw
提取码:xili
该数据为csv格式存储,0-6分别代表了:(0)生气、(1)厌恶、(2)恐惧、(3)高兴、(4)悲伤、(5)惊讶、(6)自然。这些数据需要进行处理转变为jpg格式输入网络训练。下图展示了处理好的数据集。将数据集
数据集人脸示例
下图是本次系统所采用的卷积神经网络模型。数据集图像大小为48x48,模型由三层卷积和池化层组成,和四层全连接层组成。结构比较简单,因此最终训练出来的模型识别精度有限。
在这里插入图片描述

卷积池化过程详细说明

模型构建好了,那具体过程怎么实现呢,下面我会对每一次卷积和池化的过程进行详细说明。模型输入为1通道48x48的图像,输出为256通道的6x6的特征图。卷积过程中均采用3x3的卷积核,为了卷积后特征图尺寸不变,在卷积之前进行了一圈边缘填充。
填充意思是原本48x48的图像,padding为1时,会变成49x49的尺寸。
步长是指每次卷积核或者池化核移动的跨度大小。

第一层卷积池化过程

第一层卷积核池化过程:如下图所示,在第一层卷积层中,我们采用的是3x3的卷积核,输入图像大小为48x48,卷积后得到了64个通道的48x48的特征图。然后是经过ReLU函数运算,使特征图内像素值保持在合理的范围内。然后使用大小为2的池化核进行池化操作,步长为2,最后将得到64通道的24x24的特征图。
第一层卷积池化

第二层卷积池化过程

第二层卷积和池化过程:如图所示,在第二层卷积层,采用的是128个3x3的卷积核,步长为1,边缘填充为1,进行卷积之后输出为一个128通道的24x24的特征图。再经过了ReLU函数后,使用2x2的核进行池化操作,得到了128张12x12的特征图。
第二层卷积池化

第三层卷积池化过程

第三层卷积和池化的过程:如下图所示,第三层卷积采用256个卷积核对128通道的上一层输出的特征图进行卷积操作,256个通道的12x12的特征图,然后再经过ReLU函数运算,对其进行2x2的池化操作,得到了256通道6x6的特征图。
第三层卷积池化

全连接层过程

在经过三层卷积层操作后,在第四层中将第三层输出的256通道3x3的特征图进行一维化展开,然后将其全连接到4096个神经元节点上,经过ReLU激活层,再进行Dropout。在第五层中,将4096个节点连接到1024个神经元节点,经过ReLU层,再经过Dropout。在第六层中,将上一层的1024个神经元节点对下一层的256个节点进行全连接,然后连接到最后一层输出层的7个神经元节点上,经过Softmax函数就可以完成7种表情的分类,输出每一种表情的概率。

模型的训练过程

卷积与池化原理

模型构建好以后,网络的参数都还是随机的,没有任何意义,那怎么样才能让卷积神经网络完成分类的任务呢?下面我来谈谈卷积神经网络的实现过程。卷积实际上就是对图像的内容进行特征提取的一个过程,卷积核就像是一个小的窗口,去图像上逐一套,看每次所移动到的窗口位置上的“贴合度”,要是“贴合度”高,点积求和运算得到的数值就会比较高,反之就会较小。这样操作以后就会的到一个特征图。下图展示了对图像进行卷积的具体过程,卷积核共用一个偏置。在图像中,浅层的卷积层用来提取原始图像上的边缘轮廓信息,深层次的卷积层能从底层次的特征图中迭代提出复杂的图像抽象信息。
卷积过程
卷积过程演示
池化过程:池化层能够十分有效地减小图像的空间尺寸和参数量,从而减小计算量。因此,当输入图像比较大的时候,通常会导致网络运算参数量很大,在相邻的卷积层之间间隔性地引入池化操作,能够有效地解决训练参数过多的问题,能够在有效信息保留的同时压缩图像大小,提高计算速度。池化层可以选择进行平均池化或者是最大池化。平均池化是指对单元格内的所有元素指相加取平均值,最大池化是在所有对应单元格内的所有元素值中取最大值最为池化输出结果。下图展示了池化过程,采用的是最大池化。
池化过程动图
池化过程动图

模型如何训练

表情特征训练就是用本次设计的模型对预先处理好的数据集进行提取表情特征的过程。训练过程大概分为:前向传播、反向传播、损失值计算、求权值梯度和权值更新几个过程。下图展示了神经网络训练过程。
训练过程
反向传播的实现过程:深度学习中学习方式一般都是反向传播方法,–反向传播本身是有梯度下降法发展而来,通过引入一个神经单元误差delta,该变量能将梯度下降法中比较繁琐的求解偏导过程变为数列的递推关系式。通俗的来说就是,通过链式法则,可以求解出全局的损失函数对于某一个权值或者偏置的偏导。然后乘以eta,也就是学习率来更新参数大小。下式为神经单元误差delta的定义。
δ j l = ∂ C ∂ z j l ( l = 2 , 3 , ⋯   ) \delta _{j}^{l}=\frac{\partial C}{\partial z_{j}^{l}}\left( l=2,3,\cdots \right) δjl=zjlC(l=2,3,)
神经单元误差怎么求呢?根据链式法则推导,得到了第l层和第l+1层的关系式如下面公式所示。只要我们得知了最后一层的神经单元误差,就可以通过公式进行递推得到前面的神经单元误差,进而可以得到我们更新参数需要用到的参数梯度值。
δ i l = { δ 1 l + 1 w 1 i l + 1 + δ 2 l + 1 w 2 i l + 1 + ⋯ + δ m l + 1 w m i l + 1 } a ′ ( z i l ) \delta _{i}^{l}=\left\{ \delta _{1}^{l+1}w_{1i}^{l+1}+\delta _{2}^{l+1}w_{2i}^{l+1}+\cdots +\delta _{m}^{l+1}w_{mi}^{l+1} \right\} a'\left( z_{i}^{l} \right) δil={δ1l+1w1il+1+δ2l+1w2il+1++δml+1wmil+1}a(zil)
利用上式,我们可以通过递推关系逐一求出所有需要更新的参数的神经单元误差,求出这个delta以后,我们就可以通过神经单元误差与权值和权重之间的联系求的权值和偏置对于损失函数的偏导数。如下公式所示。
{ ∂ C ∂ w j i l = δ j l a j l − 1 ∂ C ∂ b j l = δ j l ( l = 2 , 3 ⋯   ) \begin{cases} \frac{\partial C}{\partial w_{ji}^{l}}=\delta _{j}^{l}a_{j}^{l-1}\\ \frac{\partial C}{\partial \mathrm{b}_{j}^{l}}=\delta _{j}^{l}\\ \end{cases}\left( l=2,3\cdots \right) wjilC=δjlajl1bjlC=δjl(l=2,3)
得到对于损失函数的偏置以后,我们的目的是为了更新网络的权重,使网络的误差进一步减小,通过以下公式进行权值更新。

模型的评估指标

在模型构建完毕后,需要对模型的效果好坏进行一些评估,然后以评估的效果来作为参考进而继续调整模型的权值和偏置量,以达到最佳的效果。根据不同选择的模型评估指标,就会有不同的评估结果,且没有什么模型能够保证在所有的评估中都是最优,因此模型的强弱能力还主要取决于要解决什么样的问题。例如自动化生成线中的水果好坏检测机器,其目的是将好的水果送到生产线前端去,坏的水果挑出来,即便仍然会有一些误判,但是影响不会太大。而对于刑事侦查中的犯罪调查就不同了,模型的建立目的是将罪犯识别出来,而不希望有太高的误判。
卷积神经网络通常使用的评估指标也就是损失函数是交叉熵损失函数。交叉熵能够衡量同一个随机变量中的两个不同概率分布的差异程度,在机器学习中就表示为真实概率分布与预测概率分布之间的差异。交叉熵的值越小,模型预测效果就越好。下式为交叉熵损失函数。
C = − 1 n ∑ i = 1 n [ y i ln ⁡ ( σ ( z ) ) + ( 1 − y i ) ln ⁡ ( 1 − σ ( z ) ) ] C=-\frac{1}{n}\sum_{i=1}^n{\left[ y_i\ln \left( \sigma \left( z \right) \right) +\left( 1-y_i \right) \ln \left( 1-\sigma \left( z \right) \right) \right]} C=n1i=1n[yiln(σ(z))+(1yi)ln(1σ(z))]

训练结果分析

通过训练曲线分析

下图显示的是训练的每个时期的损失值和测试集精度以及测试集精度曲线。其中Batch Size大小为128,学习率为0.1,对模型训练50次。图中横轴数值表示迭代轮数,纵轴数值代表了模型损失率和训练精度。从图中可以看到,训练迭代到第35轮的时候训练集精度和测试集精度都基本趋于稳定,其中训练集测试精度能够达到99.4%,测试集精度最高达到60.5%。此时损失值稳定在一个较小的数值小幅度震荡,基本能够保持在一个稳定的趋势,这时候训练模型的性能较好。
训练曲线图
输出曲线实现的代码:

def draw(train_acc, val_acc, epoch, loss):
    epoch_list.append(epoch)
    train_acc_list.append(train_acc)
    val_acc_list.append(val_acc)
    loss_list.append(loss)
    x = torch.tensor(train_acc_list)
    y = torch.tensor(val_acc_list)
    l = torch.tensor(loss_list)
    z = torch.tensor(epoch_list)
    plt.cla()
    plt.ylim((0, 2))
    plt.xlabel('epoch')
    plt.ylabel('accuracy')
    # plt.scatter(z.numpy(), x.data.numpy(), c='r', marker='x')
    # plt.scatter(z.numpy(), y.data.numpy(), c='b')
    # plt.scatter(z.numpy(), l.data.numpy(), c='g', marker='o')
    plt.plot(z.numpy(), x.data.numpy(), color='red', linestyle='--', label='train_acc')
    plt.plot(z.numpy(), y.data.numpy(), color='blue',linestyle='-.', label='val_acc')
    plt.plot(z.numpy(), l.data.numpy(), color='green', label='loss_rate')
    plt.legend()
    # plt.pause(0.005)
    plt.show()

每次训练一轮就调用一次该函数,然后更新图像。
下面是训练过程中的动图效果。为了显示效果直观,在每一轮训练都标注了点。
动图效果

通过混淆矩阵分析效果

混淆矩阵也称误差矩阵,是表示精度评价的一种标准格式,用n行n列的矩阵形式来表示。如下图所示,表示的是7种表情的混淆矩阵,矩阵正对角线代表每一种表情的判断准确率。在该图中的横坐标代表对人脸表情的预测类型,纵坐标代表了人脸表情的正确类别。
混淆矩阵
从图中我们可以看出对于高兴的判别准确率能够达到85%,也就是说在训练集中对所有开心的表情进行判别中有85%能够正确识别的,开心的表情被错判为生气、悲伤、惊讶和自然的错误率分别是3%、5%、2%和5%。在7类表情判定中,对恐惧的识别精度最低,正确率只有28%,也就是在所有恐惧的数据集中,只有28%的图片被判定正确。可见,由于对应恐惧的训练集样本较少,导致最后判定的错误率较高。
混淆矩阵实现代码:

def plot_confusion_matrix(cm, savename, title='Confusion Matrix'):
    plt.figure(figsize=(12, 8), dpi=100)
    np.set_printoptions(precision=2)  # 控制输出小数点个数为2

    # 在混淆矩阵中每格的概率值
    ind_array = np.arange(len(classes))     # 生成一个长度为*的列表[1,2,3....]
    x, y = np.meshgrid(ind_array, ind_array)    # 在网格上画一个正方形坐标
    for x_val, y_val in zip(x.flatten(), y.flatten()):
        c = cm[y_val][x_val]
        if c > 0.001:
            plt.text(x_val, y_val, "%0.2f" % (c,), color='red', fontsize=15, va='center', ha='center')

    plt.imshow(cm, interpolation='nearest', cmap=plt.cm.Pastel2)
    plt.title(title)
    plt.colorbar()
    xlocations = np.array(range(len(classes)))
    plt.xticks(xlocations, classes, rotation=90)
    plt.yticks(xlocations, classes)
    plt.ylabel('Actual label')
    plt.xlabel('Predict label')

    # offset the tick
    tick_marks = np.array(range(len(classes))) + 0.5
    plt.gca().set_xticks(tick_marks, minor=True)
    plt.gca().set_yticks(tick_marks, minor=True)
    plt.gca().xaxis.set_ticks_position('none')
    plt.gca().yaxis.set_ticks_position('none')
    plt.grid(True, which='minor', linestyle='-')
    plt.gcf().subplots_adjust(bottom=0.15)

    # show confusion matrix
    plt.savefig(savename, format='png')
    plt.show()

通过摄像头识别表情

设计流程

根据上一节训练好的模型设计一个能够调用摄像头实时识别人脸表情的系统,系统要识别的表情分为7种,分别是:悲伤、高兴、恐惧、愤怒、中性、厌恶和惊讶。识别结果会将标签显示在识别界面,同时显示识别的概率大小。系统的识别过程有如下几个步骤:
(1)运行系统的程序,自动打开摄像头;
(2)摄像头打开后,自动捕获图片,检测到人脸,框出人脸;
(3)对框中的人脸进行裁剪,并送入系统进行处理灰度化,大小尺寸归一化,转变为TENSOR格式送入卷积神经网络;
(3)卷积神经网络进行前向传播得到对7类表情的预测概率数组
(4)将卷积神经的输出取最大值作为预测值,将结果标签和对应概率输出在系统界面。

效果演示

在这里插入图片描述
在这里插入图片描述
上图演示了表情识别的效果,数字代表的是卷积神经网络输出的概率矩阵中的最大值四舍五入以后的数值。表示系统判定该表情的正确概率。

部分代码展示

 pre = model.forward(img)
    pre = F.softmax(pre, dim=1)  # dim = 0是对列操作,dim = 1是对行操作
    pro = pre.cpu().data.numpy()
    max_num = max(pro[0])
    result = round(max_num, 2)
    # print(max_num)
    pred = np.argmax(pro, axis=1)
    # pre = model(img).item()
    # print(pre)
    # pre = pre.max(1)[1]
    frame = cv2.putText(frame, emotion[pred[0]], (100, 100), cv2.FONT_HERSHEY_SIMPLEX, 2.5, (55,255,155), 2)
    #显示窗口第一个参数是窗口名,第二个参数是内容
    frame = cv2.putText(frame, str(result), (400, 100), cv2.FONT_HERSHEY_SIMPLEX, 2.5, (55, 255, 155), 2)
    cv2.imshow('emotion', frame)
    if cv2.waitKey(1) == ord('q'):#按q退出
        break

总结

博主写这篇博客是为了记录自己学习的一些历程,第一次写博客,所以很多地方可能会有些错误,希望多多包涵,还请大佬们日后多加指点。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于pytorch卷积人脸表情识别--毕业设计 的相关文章

  • PyQt:如何通过匿名代理使用网页

    这真让我抓狂 我想在 QWebPage 中显示一个 url 但我想通过匿名代理来实现 Code setting up the proxy proxy QNetworkProxy proxy setHostName 189 75 98 199
  • 为什么我的代码不能根据字典解码加密字符串?

    我有一本字典 其中包含代表字母的键和值 例如一个简单的 DICT CODE b g n a p o x d t y 我收到了一个加密代码 并将该字符串转换为一个列表 其中每个项目都是一个单词 我需要根据字典中的项目来解决它 代码示例是 wo
  • TF map_fn 或 while_loop 用于不同形状的张量列表

    我想处理不同形状的张量序列 列表 并输出另一个张量列表 考虑每个时间戳上具有不同隐藏状态大小的 RNN 就像是 输入 tf ones 1 2 2 tf ones 2 2 3 tf ones 3 2 1 输出 tf zeros 1 2 4 t
  • 在 macOS 中通过 Python 访问进程的压缩 RAM(顶部的 CMPRS)的方法?

    我试图弄清楚如何从 Python 访问任何给定进程占用的实际 RAM 量 我发现 psutil Process PID memory info rss 工作得很好 直到操作系统决定开始压缩某些进程的 RAM 然后 所有的 memory in
  • numpy 使用 datetime64 进行数字化

    我似乎无法让 numpy digitize 与 datetime64 一起使用 date bins np array np datetime64 datetime datetime 2014 n 1 s for n in range 1 1
  • 如何在 Python 3 中循环遍历集合,同时从集合中删除项目

    这是我的情况 我有一个list set 哪个并不重要 movieplayer我想调用的对象 preload 功能开启 该预加载函数可以立即返回 但希望将来返回一点 我想存储这个电影播放器 集合 表明它们尚未预加载 然后循环它们 调用prel
  • 更改 python tkinter canvas 中的线坐标

    我画了一条线tkinter Canvas现在我想移动一端 这可能吗 例如和itemconfig import tkinter tk tkinter Tk canvas tkinter Canvas tk canvas pack line c
  • Apache Spark 中的高效字符串匹配

    我使用 OCR 工具从屏幕截图中提取文本 每个大约 1 5 句话 然而 当手动验证提取的文本时 我注意到时不时会出现一些错误 鉴于文本 你好 我真的很喜欢 Spark 我注意到 1 像 I 和 l 这样的字母被 替换 2 表情符号未被正确提
  • PySide6.1 与 matplotlib 3.4 不兼容

    当我只安装PySide6时 GUI程序运行良好 但是一旦我安装了matplotlib及其依赖包 包括pyqt5 则GUI程序将无法运行并输出以下错误消息 This application failed to start because no
  • 动态 __init_subclass__ 方法的参数绑定

    我正在尝试让类装饰器工作 装饰器会添加一个 init subclass 方法到它所应用的类 但是 当该方法动态添加到类中时 第一个参数不会绑定到子类对象 为什么会发生这种情况 举个例子 这是可行的 下面的静态代码是我试图最终得到的示例 cl
  • 具有屏蔽无效值的 pcolormesh

    我试图将一维数组绘制为 pcolormesh 因此颜色沿 x 轴变化 但每个 x 的 y 轴保持不变 但我的数据有一些错误值 因此我使用屏蔽数组和自定义颜色图 其中屏蔽值设置为蓝色 import numpy as np import mat
  • 使用 numpy 在 python 中执行最大方差旋转

    我正在研究矩阵的主成分分析 我已经找到了如下所示的组件矩阵 A np array 0 73465832 0 24819766 0 32045055 0 3728976 0 58628043 0 63433607 0 72617152 0 5
  • 由于 json 字符串化 dict 键导致数据丢失

    考虑下面的例子 gt gt gt import json gt gt gt d 0 potato 0 spud gt gt gt json dumps d 0 potato 0 spud gt gt gt json loads json d
  • 检测 IDLE 的存在/如何判断 __file__ 是否未设置

    我有一个脚本需要使用 file 所以我了解到 IDLE 没有设置这个 有没有办法从我的脚本中检测到 IDLE 的存在 if file not in globals file is not set 如果你想做一些特别的事情 file 未设置
  • 处理大文件的最快方法?

    我有多个 3 GB 制表符分隔文件 每个文件中有 2000 万行 所有行都必须独立处理 任何两行之间没有关系 我的问题是 什么会更快 逐行阅读 with open as infile for line in infile 将文件分块读入内存
  • 在 virtualenvwrapper 中激活环境

    我安装了virtualenv and virtualenvwrapper用这个命令我创建了一个环境 mkvirtualenv cv 它有效 创建后我就处于新环境中 现在我重新启动了我的电脑 我想activate又是那个环境 但是怎么样 我使
  • Django 模型:如何使用 mixin 类来覆盖 django 模型以实现 save 等功能

    我想在每次保存模型之前验证值 所以 我必须重写保存函数 代码几乎是一样的 我想把它写在 mixin 类中 但失败了 我不知道如何写 super func 我英语不好 抱歉 class SyncableMixin object def sav
  • 如何循环遍历字典列表并打印特定键的值?

    我是 Python 新手 有一个问题 我知道这是一个非常简单的问题 运行Python 3 4 我有一个需要迭代并提取特定信息的列表 以下是列表 称为部分 的示例 已截断 数千个项目 state DEAD id phwl type name
  • 在 Django shell 会话期间获取 SQL 查询计数

    有没有办法打印 Django ORM 在 Django shell 会话期间执行的原始 SQL 查询的数量 Django 调试工具栏已经提供了此类信息 例如 5 QUERIES in 5 83MS但如何从 shell 中获取它并不明显 您可
  • 如何为所有用户安装 Anaconda python?

    Anaconda python 发行版 https store continuum io cshop anaconda 非常方便地部署科学计算环境 SCE 并根据需要切换python版本 默认情况下 安装会将 python 定位到 anac

随机推荐

  • visio2016企业批量授权版本的激活方式

    首先先下载visio2016的企业批量授权版本 下载地址 用window的资源管理器打开压缩包 点击setup exe 之后默认安装 接下来就是激活的过程 win r快捷键 输入cmd cd C Program Files Microsof
  • anaconda 安装 for macOSX

    步骤 1 登陆官网 https www anaconda com 2 点击 get started 开始 3 选择下载 下载 4 根据自己的电脑来选择下载的方式 我用的是mac所以就选择这个 这里有两种选择 其实都可以 选择一个就行 4 1
  • osgEarth的Rex引擎原理分析(二十一)创建瓦片模型过程详解

    目标 十七 中问题47 瓦片模型的作用是负责管理瓦片中的影像 高程等图层信息 这些信息的获取最终通过createTileModel函数来实现 负责维护瓦片版本等 应当是每一个瓦片都对应有一个瓦片模型 这个瓦片模型是在瓦片请求过程中创建的 具
  • 面试最常被问的 Java 后端题目及参考答案

    一 Java 基础篇 1 Object 有哪些常用方法 大致说一下每个方法的含义 2 Java 创建对象有几种方式 3 获取一个类对象的方式有哪些 4 ArrayList 和 LinkedList 的区别有哪些 5 用过 ArrayList
  • next.js中引入sass

    第一步 安装sass npm install save zeit next sass node sass 第二步 在项目根目录添加 next config js 文件 用于指示Next加载对用的功能 const withSass requi
  • 基础软件与开发语言开源论坛

    ChinaOSC 2022基础软件与开发语言开源技术论坛将于8月20日 14 00 18 00在陕西省西安高新国际会议中心召开 论坛邀请到在操作系统 中间件等基础软件领域 以及编程语言领域深耕多年的开源专家 深度分享开源软件研发的创新之路
  • 【Pandas总结】第九节 Pandas_累计与分组 pd.groupby()

    文章目录 一 数据准备 二 累计值计算 2 1 df describe 2 2 常用统计值 三 分组 pd groupby 四 更多的使用方法 aggregate filter transform apply 4 1 aggregate 4
  • [Kafka] - Kafka Java Producer代码实现

    根据业务需要可以使用Kafka提供的Java Producer API进行产生数据 并将产生的数据发送到Kafka对应Topic的对应分区中 入口类为 Producer Kafka的Producer API主要提供下列三个方法 public
  • webview拦截垃圾电信运营商的广告方法

    mWebView setWebViewClient new WebViewClient Override public boolean shouldOverrideUrlLoading WebView view String url if
  • terminated 线程_Java中如何正确地中断一个线程?

    本文主要整理了关于线程中断的相关知识点 1 线程的状态 NEW 新建 一个尚未启动的线程处于这一状态 A thread that has not yet started is in this state RUNNABLE 可运行 一个正在
  • QT实现塔防游戏

    在基本功能实现后 对游戏进行优化 主要有以下几部分 实现传奇的升级 实现传奇的移除 绘画出波数与血量 实现游戏的暂停与回到选关关卡 实现游戏的胜利与失败 1 实现传奇的升级 创建一个selectbutton2类 ifndef SELECTB
  • 【华为OD机试真题 Python】多个数组合并

    前言 本专栏将持续更新华为OD机试题目 并进行详细的分析与解答 包含完整的代码实现 希望可以帮助到正在努力的你 关于OD机试流程 面经 面试指导等 如有任何疑问 欢迎联系我 wechat steven moda email nansun09
  • 如何让RecyclerView滑动到底部?

    在做这个功能时 使用scroll的任何一个方法 发现它每次都只滑到了一半 今天终于解决了 解决方法如下 LinearLayoutManager linearLayoutManager LinearLayoutManager recycler
  • 【批量注册组件】

    自动的批量注册组件 大致步骤 使用 require 提供的函数 context 加载某一个目录下的所有 vue 后缀的文件 然后 context 函数会返回一个导入函数 importFn 它又一个属性 keys 获取所有的文件路径 通过文件
  • 不得不读

    本次总共收集了8位大牛的8篇精品文章 内容涉及设计 验证 行业研究 ICer职场生活等各方面 欢迎大家点击阅读并关注 1 酒酒拿下四五十万的真实大厂面试经历 作者介绍 酒酒成电研三在读 自学算法leetcode刷题 双修IC验证 斩获互联网
  • 程序中难以捉摸的错误如何自动检测?Parasoft Insure++ v2021.1发布!

    Parasoft Insure 是用于 C 和 C 应用程序的自动化运行时应用程序测试工具 可检测难以捉摸的错误 例如内存损坏 内存泄漏 内存分配错误 变量初始化错误 变量定义冲突 指针错误 库错误 I O 错误 和逻辑错误 Parasof
  • Python网络爬虫使用教程

    文章目录 一 URL资源抓取 1 urllib 2 requests 3 requests html 二 正则表达式 三 数据解析 1 Beautiful Soup 2 lxml 3 selectolax 四 自动化爬虫selenium 五
  • 汉字的区码和位码

    写于2016年12月08日 汉字的区码和位码 由于国标码是四位十六进制 为了便于交流 大家常用的是四位十进制的区位码 所有的国标汉字与符号组成一个94 94的矩阵 在此方阵中 每一行称为一个 区 每一列称为一个 位 因此 这个方阵实际上组成
  • 字典树实现_数据结构与算法之字典树(Golang实现)

    1 字典树 算法描述 trie树的本质 就是利用字符串之间的公共前缀 将重复的前缀合并在一起 时间复杂度 构建O n 查询O k 1 1 1 算法步骤 根节点 什么都不表示 做一个字典比如a z 字母表 没一个节点包含这26个字母的字典表
  • 基于pytorch卷积人脸表情识别--毕业设计

    基于卷积神经网络的人脸表情识别 前言 毕业设计内容介绍 卷积神经网络的设计 卷积网络的模型 卷积池化过程详细说明 第一层卷积池化过程 第二层卷积池化过程 第三层卷积池化过程 全连接层过程 模型的训练过程 卷积与池化原理 模型如何训练 模型的