卷积神经网络实现人脸表情识别

2023-11-04

一、实现过程

1.1 下载数据集

https://github.com/truongnmt/smile-detection
创建一个文件夹存放datasets
在这里插入图片描述

1.2 根据猫狗数据集训练的方法来训练笑脸数据集

#coding=gbk
import os
import sys
def rename():
    path=input("请输入路径(例如D:\\\\picture):")
    name=input("请输入开头名:")
    startNumber=input("请输入开始数:")
    fileType=input("请输入后缀名(如 .jpg、.txt等等):")
    print("正在生成以"+name+startNumber+fileType+"迭代的文件名")
    count=0
    filelist=os.listdir(path)
    for files in filelist:
        Olddir=os.path.join(path,files)
        if os.path.isdir(Olddir):
            continue
        Newdir=os.path.join(path,name+str(count+int(startNumber))+fileType)
        os.rename(Olddir,Newdir)
        count+=1
    print("一共修改了"+str(count)+"个文件")

rename() 

路径:D:\Face_smile\datasets\train_foder\0
在这里插入图片描述
开始数:0
在这里插入图片描述
unsmile.改为smile.
在这里插入图片描述

在这里插入图片描述

1.2 图片分类

import os, shutil #复制文件
# 原始目录所在的路径
# 数据集未压缩
original_dataset_dir1 = 'D:\\Face_smile\\smile\\datasets\\train_folder\\1'  ##笑脸
original_dataset_dir0 = 'D:\\Face_smile\\smile\\datasets\\train_folder\\0'  ##非笑脸
# 我们将在其中的目录存储较小的数据集
base_dir = 'D:\\Face_smile\\smile1'
os.mkdir(base_dir)

# # 训练、验证、测试数据集的目录
train_dir = os.path.join(base_dir, 'train')
os.mkdir(train_dir)
validation_dir = os.path.join(base_dir, 'validation')
os.mkdir(validation_dir)
test_dir = os.path.join(base_dir, 'test')
os.mkdir(test_dir)

# 猫训练图片所在目录
train_cats_dir = os.path.join(train_dir, 'smile')
os.mkdir(train_cats_dir)

# 狗训练图片所在目录
train_dogs_dir = os.path.join(train_dir, 'unsmile')
os.mkdir(train_dogs_dir)

# 猫验证图片所在目录
validation_cats_dir = os.path.join(validation_dir, 'smile')
os.mkdir(validation_cats_dir)

# 狗验证数据集所在目录
validation_dogs_dir = os.path.join(validation_dir, 'unsmile')
os.mkdir(validation_dogs_dir)

# 猫测试数据集所在目录
test_cats_dir = os.path.join(test_dir, 'smile')
os.mkdir(test_cats_dir)

# 狗测试数据集所在目录
test_dogs_dir = os.path.join(test_dir, 'unsmile')
os.mkdir(test_dogs_dir)

# 将前1000张笑脸图像复制到train_cats_dir
fnames = ['smile.{}.jpg'.format(i) for i in range(1000)]
for fname in fnames:
    src = os.path.join(original_dataset_dir1, fname)
    dst = os.path.join(train_cats_dir, fname)
    shutil.copyfile(src, dst)

# 将下500张笑脸图像复制到validation_cats_dir
fnames = ['smile.{}.jpg'.format(i) for i in range(500)]
for fname in fnames:
    src = os.path.join(original_dataset_dir1, fname)
    dst = os.path.join(validation_cats_dir, fname)
    shutil.copyfile(src, dst)
    
# 将下500张笑脸图像复制到test_cats_dir
fnames = ['smile.{}.jpg'.format(i) for i in range(500)]
for fname in fnames:
    src = os.path.join(original_dataset_dir1, fname)
    dst = os.path.join(test_cats_dir, fname)
    shutil.copyfile(src, dst)
    
# 将前1000张非笑脸图像复制到train_dogs_dir
fnames = ['unsmile.{}.jpg'.format(i) for i in range(1000)]
for fname in fnames:
    src = os.path.join(original_dataset_dir0, fname)
    dst = os.path.join(train_dogs_dir, fname)
    shutil.copyfile(src, dst)
    
# 将下500张非笑脸图像复制到validation_dogs_dir
fnames = ['unsmile.{}.jpg'.format(i) for i in range(500)]
for fname in fnames:
    src = os.path.join(original_dataset_dir0, fname)
    dst = os.path.join(validation_dogs_dir, fname)
    shutil.copyfile(src, dst)
    
# 将下500张非笑脸图像复制到test_dogs_dir
fnames = ['unsmile.{}.jpg'.format(i) for i in range(500)]
for fname in fnames:
    src = os.path.join(original_dataset_dir0, fname)
    dst = os.path.join(test_dogs_dir, fname)
    shutil.copyfile(src, dst)

结果如下:
在这里插入图片描述

1.3 作为健全性检查,计算一下在每个训练分割中我们有多少图片(训练/验证/测试):

print('total training cat images:', len(os.listdir(train_cats_dir)))
print('total training dog images:', len(os.listdir(train_dogs_dir)))
print('total validation cat images:', len(os.listdir(validation_cats_dir)))
print('total validation dog images:', len(os.listdir(validation_dogs_dir)))
print('total test cat images:', len(os.listdir(test_cats_dir)))
print('total test dog images:', len(os.listdir(test_dogs_dir)))

在这里插入图片描述

1.4 卷积网络模型搭建

from keras import layers
from keras import models

model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu',
                        input_shape=(150, 150, 3)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Flatten())
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))
model.summary()

在这里插入图片描述

1.5 图像生成器读取文件中数据,进行数据预处理

from tensorflow import optimizers

model.compile(loss='binary_crossentropy',
              optimizer=optimizers.RMSprop(lr=1e-4),
              metrics=['acc'])
from keras.preprocessing.image import ImageDataGenerator

# 所有图像将按1/255重新缩放
train_datagen = ImageDataGenerator(rescale=1./255)
test_datagen = ImageDataGenerator(rescale=1./255)

train_generator = train_datagen.flow_from_directory(
        # 这是目标目录
        train_dir,
        # 所有图像将调整为150x150
        target_size=(150, 150),
        batch_size=20,
        # 因为我们使用二元交叉熵损失,我们需要二元标签
        class_mode='binary')

validation_generator = test_datagen.flow_from_directory(
        validation_dir,
        target_size=(150, 150),
        batch_size=20,
        class_mode='binary')

在这里插入图片描述

1.6 开始训练

时间漫长,慢慢等待

history = model.fit_generator(
      train_generator,
      steps_per_epoch=100,
      epochs=30,
      validation_data=validation_generator,
      validation_steps=50)

在这里插入图片描述

1.7 保存训练模型

model.save('D:\\Face_smile\\smile1\\smiles_and_unsmiles_small_1.h5')

在这里插入图片描述

1.8 在培训和验证数据上绘制模型的损失和准确性(可视化界面)

import matplotlib.pyplot as plt

acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']

epochs = range(len(acc))

plt.plot(epochs, acc, 'bo', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='Validation acc')
plt.title('Training and validation accuracy')
plt.legend()

plt.figure()

plt.plot(epochs, loss, 'bo', label='Training loss')
plt.plot(epochs, val_loss, 'b', label='Validation loss')
plt.title('Training and validation loss')
plt.legend()
plt.show()

在这里插入图片描述

1.9 使用数据扩充

datagen = ImageDataGenerator(
      rotation_range=40,
      width_shift_range=0.2,
      height_shift_range=0.2,
      shear_range=0.2,
      zoom_range=0.2,
      horizontal_flip=True,
      fill_mode='nearest')
# 这是带有图像预处理实用程序的模块
from keras.preprocessing import image

fnames = [os.path.join(train_cats_dir, fname) for fname in os.listdir(train_cats_dir)]

# 我们选择一个图像来“增强”
img_path = fnames[3]

# 读取图像并调整其大小
img = image.load_img(img_path, target_size=(150, 150))

# 将其转换为具有形状的Numpy数组(150、150、3)
x = image.img_to_array(img)

# 把它改成(1150150,3)
x = x.reshape((1,) + x.shape)

# 下面的.flow()命令生成一批随机转换的图像。
# 它将无限循环,所以我们需要在某个时刻“打破”循环!
i = 0
for batch in datagen.flow(x, batch_size=1):
    plt.figure(i)
    imgplot = plt.imshow(image.array_to_img(batch[0]))
    i += 1
    if i % 4 == 0:
        break

plt.show()

在这里插入图片描述

如果我们使用这种数据增强配置训练一个新网络,我们的网络将永远不会看到两次相同的输入。但是,输入它所看到的仍然是高度相关的,因为它们来自于少量的原始图像——我们无法产生新的信息,我们只能重新混合现有的信息。因此,这可能还不足以完全摆脱过度装修。继续战斗过度拟合,我们还将在密连接分类器之前向模型添加一个退出层:

model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu',
                        input_shape=(150, 150, 3)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Flatten())
model.add(layers.Dropout(0.5))
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))

model.compile(loss='binary_crossentropy',
              optimizer=optimizers.RMSprop(lr=1e-4),
              metrics=['acc'])

1.10 使用数据扩充和退出来训练我们的网络

train_datagen = ImageDataGenerator(
    rescale=1./255,
    rotation_range=40,
    width_shift_range=0.2,
    height_shift_range=0.2,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True,)

# 请注意,不应增加验证数据!
test_datagen = ImageDataGenerator(rescale=1./255)

train_generator = train_datagen.flow_from_directory(
        # 这是目标目录
        train_dir,
        # 所有图像将调整为150x150
        target_size=(150, 150),
        batch_size=32,
        # 因为我们使用二元交叉熵损失,我们需要二元标签
        class_mode='binary')

validation_generator = test_datagen.flow_from_directory(
        validation_dir,
        target_size=(150, 150),
        batch_size=32,
        class_mode='binary')

history = model.fit_generator(
      train_generator,
      steps_per_epoch=100,
      epochs=100,
      validation_data=validation_generator,
      validation_steps=50)

1.11保存模型

model.save('D:\\Face——smile\\smile1\\smiles_and_unsmiles_small_2.h5')

在这里插入图片描述

1.12 在培训和验证数据上绘制模型的损失和准确性(可视化界面)

acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']

epochs = range(len(acc))

plt.plot(epochs, acc, 'bo', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='Validation acc')
plt.title('Training and validation accuracy')
plt.legend()

plt.figure()

plt.plot(epochs, loss, 'bo', label='Training loss')
plt.plot(epochs, val_loss, 'b', label='Validation loss')
plt.title('Training and validation loss')
plt.legend()
plt.show()

二、运用训练的模型实现表情识别

2.1 将模型传输到树莓派

将前面训练的模型通过xshell将传输到树莓上,(由于没有摄像头)采用读取图片识别笑脸非笑脸

代码:

# 单张图片进行判断  是笑脸还是非笑脸
import cv2
from tensorflow.keras.preprocessing import image
from tensorflow.keras.models import load_model
import numpy as np
#加载模型
model = load_model('smiles_and_unsmiles_small_2.h5')
#本地图片路径
img_path='smile.jpg'
img = image.load_img(img_path, target_size=(150, 150))

img_tensor = image.img_to_array(img)/255.0
img_tensor = np.expand_dims(img_tensor, axis=0)
prediction =model.predict(img_tensor)  
print(prediction)
if prediction[0][0]>0.5:
    result='非笑脸'
else:
    result='笑脸'
print(result)

结果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.2 采用摄像头测试模型

在window上进行

#检测视频或者摄像头中的人脸
import cv2
from keras.preprocessing import image
from keras.models import load_model
import numpy as np
import dlib
from PIL import Image
model = load_model('D:\\Face_smile\\smile1\\smiles_and_unsmiles_small_2.h5')
detector = dlib.get_frontal_face_detector()
video=cv2.VideoCapture(0)
font = cv2.FONT_HERSHEY_SIMPLEX
def rec(img):
    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    dets=detector(gray,1)
    if dets is not None:
        for face in dets:
            left=face.left()
            top=face.top()
            right=face.right()
            bottom=face.bottom()
            cv2.rectangle(img,(left,top),(right,bottom),(0,255,0),2)
            img1=cv2.resize(img[top:bottom,left:right],dsize=(150,150))
            img1=cv2.cvtColor(img1,cv2.COLOR_BGR2RGB)
            img1 = np.array(img1)/255.
            img_tensor = img1.reshape(-1,150,150,3)
            prediction =model.predict(img_tensor)    
            if prediction[0][0]>0.5:
                result='unsmile'
            else:
                result='smile'
            cv2.putText(img, result, (left,top), font, 2, (0, 255, 0), 2, cv2.LINE_AA)
        cv2.imshow('Video', img)
while video.isOpened():
    res, img_rd = video.read()
    if not res:
        break
    rec(img_rd)
    if cv2.waitKey(5) & 0xFF == ord('q'):
        break
video.release()
cv2.destroyAllWindows()

结果展示:

在这里插入图片描述

三、总结

这一次实验是用卷积神经网络实现的人脸表情识别,实现过程还是遇到了很多的困难,遇到了很多导包错误的问题,keras和tensorflow很折磨人,明明下载的有,但还是在用的时候识别不到,头痛。解决了很久,后来发现是jupyter的问题,用其他软件运行代码都能识别到包,用jupyter就识别不到包。相对于上回用svm实现的人脸表情识别,对这方面的知识有了进一步的了解。

四、参考文献

python+基于Jupyter notebook完成卷积神经网络和Dlib的笑脸识别+口罩识别

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

卷积神经网络实现人脸表情识别 的相关文章

  • PyTorch - 参数不变

    为了了解 pytorch 的工作原理 我尝试对多元正态分布中的一些参数进行最大似然估计 然而 它似乎不适用于任何协方差相关的参数 所以我的问题是 为什么这段代码不起作用 import torch def make covariance ma
  • PoseWarping:如何矢量化此 for 循环(z 缓冲区)

    我正在尝试使用地面真实深度图 姿势信息和相机矩阵将帧从视图 1 扭曲到视图 2 我已经能够删除大部分 for 循环并将其矢量化 除了一个 for 循环 扭曲时 由于遮挡 视图 1 中的多个像素可能会映射到视图 2 中的单个位置 在这种情况下
  • 二维数组的按行 numpy.isin [重复]

    这个问题在这里已经有答案了 我有两个数组 A np array 3 1 4 1 1 4 B np array 0 1 5 2 4 5 2 3 5 是否可以使用numpy isin二维数组按行排列 我想检查一下是否A i j is in B
  • Pytorch:了解 nn.Module 类内部如何工作

    一般来说 一个nn Module可以由子类继承 如下所示 def init weights m if type m nn Linear torch nn init xavier uniform m weight class LinearRe
  • 使用 pytorch 获取可用 GPU 内存总量

    我正在使用 google colab 免费 Gpu 进行实验 并想知道有多少 GPU 内存可供使用 torch cuda memory allocated 返回当前占用的 GPU 内存 但我们如何使用 PyTorch 确定总可用内存 PyT
  • 运行时错误:CUDA 错误:设备端断言已触发 - 训练 LayoutLMV3 时

    我正在训练最新版本的layoutLMv3模型 但在开始训练时trainer train 出现以下错误 请帮我解决它 我使用的是 v100 4 GPU RuntimeError Traceback most recent call last
  • 在pytorch中使用tensorboard,但得到空白页面?

    我在pytorch 1 3 1中使用tensorboard 并且我在张量板的 pytorch 文档 https pytorch org docs stable tensorboard html 运行后tensorboard logdir r
  • 从打包序列中获取每个序列的最后一项

    我试图通过 GRU 放置打包和填充的序列 并检索每个序列最后一项的输出 当然我的意思不是 1项目 但实际上是最后一个 未填充的项目 我们预先知道序列的长度 因此应该很容易为每个序列提取length 1 item 我尝试了以下方法 impor
  • BatchNorm 动量约定 PyTorch

    Is the 批归一化动量约定 http pytorch org docs master modules torch nn modules batchnorm html 默认 0 1 与其他库一样正确 例如Tensorflow默认情况下似乎
  • Blenderbot 微调

    我一直在尝试微调 HuggingFace 的对话模型 Blendebot 我已经尝试过官方拥抱脸网站上给出的传统方法 该方法要求我们使用 trainer train 方法来完成此操作 我使用 compile 方法尝试了它 我尝试过使用 Py
  • Pytorch Tensor 如何获取元素索引? [复制]

    这个问题在这里已经有答案了 我有 2 个名为x and list它们的定义如下 x torch tensor 3 list torch tensor 1 2 3 4 5 现在我想获取元素的索引x from list 预期输出是一个整数 2
  • 如何使用pytorch构建多任务DNN,例如超过100个任务?

    下面是使用 pytorch 为两个回归任务构建 DNN 的示例代码 这forward函数返回两个输出 x1 x2 用于大量回归 分类任务的网络怎么样 例如 100 或 1000 个输出 对所有输出 例如 x1 x2 x100 进行硬编码绝对
  • Pytorch“展开”等价于 Tensorflow [重复]

    这个问题在这里已经有答案了 假设我有大小为 50 50 的灰度图像 在本例中批量大小为 2 并且我使用 Pytorch Unfold 函数 如下所示 import numpy as np from torch import nn from
  • 保存具有自定义前向功能的 Bert 模型并将其置于 Huggingface 上

    我创建了自己的 BertClassifier 模型 从预训练开始 然后添加由不同层组成的我自己的分类头 微调后 我想使用 model save pretrained 保存模型 但是当我打印它并从预训练上传时 我看不到我的分类器头 代码如下
  • 如何在 PyTorch 中对子集使用不同的数据增强

    如何针对不同的情况使用不同的数据增强 转换 Subset在 PyTorch 中吗 例如 train test torch utils data random split dataset 80000 2000 train and test将具
  • Pytorch 与 joblib 的 autograd 问题

    将 pytorch 的 autograd 与 joblib 混合似乎存在问题 我需要并行获取大量样本的梯度 Joblib 与 pytorch 的其他方面配合良好 但是 与 autograd 混合时会出现错误 我做了一个非常小的例子 显示串行
  • TensorFlow 相当于 PyTorch 的 Transforms.Normalize()

    我正在尝试推断最初在 PyTorch 中构建的 TFLite 模型 我一直在遵循PyTorch 实现 https github com leoxiaobin deep high resolution net pytorch blob 1ee
  • PyTorch 给出 cuda 运行时错误

    我对我的代码做了一些小小的修改 以便它不使用 DataParallel and DistributedDataParallel 代码如下 import argparse import os import shutil import time
  • Pytorch RuntimeError:“host_softmax”未针对“torch.cuda.LongTensor”实现

    我正在使用 pytorch 来训练模型 但是在计算交叉熵损失时我遇到了运行时错误 Traceback most recent call last File deparser py line 402 in
  • 如何在不安装pytorch的情况下使用pytorch预训练模型?

    我只想在 pytorch 中使用预先训练的模型 而不安装整个包 我可以从 pytorch 复制模型模块吗 恐怕你不能这样做 为了运行模型 你不仅需要经过训练的权重 pth tar 文件 还需要网络的 结构 即层 它们如何相互连接等 该网络结

随机推荐

  • ​LeetCode刷题实战88:合并两个有序数组

    算法的重要性 我就不多说了吧 想去大厂 就必须要经过基础知识和业务逻辑面试 算法面试 所以 为了提高大家的算法能力 这个公众号后续每天带大家做一道算法题 题目就从LeetCode上面选 今天和大家聊的问题叫做 合并两个有序数组 我们先来看题
  • 1002 A+B for Polynomials (25分) PAT_A

    1002 A B for Polynomials 25分 This time you are supposed to find A B where A and B are two polynomials Input Specificatio
  • AD20(Altium designer) PCB图元件位号不显示

    别人发来了一份PCB图 元件位号不显示记录下原因 1 单击红框中黄色的方块 2 弹出的窗口中点击Texts的小眼睛就可以啦
  • 四、vim高级用法配置

    四 vim高级用法配置 4 1 vim的三种模式 vim是全球两大流行文本编辑器之一 vim file 直接编辑文件内容 vim wq 文件存在 wq file 文件不存在 vim模式 1 命令模式 浏览模式 此模式下只能对文件内容浏览 对
  • v-for里面再嵌套一个v-for的写法

    v for里面再嵌套一个v for的写法 list id goods images product desc div class listContent span item create time i formatDate span div
  • 什么是深度学习?怎么学好深度学习?

    深度学习 是一种强大的多层架构 可以用于模式识别 信号检测以及分类或预测等多个领域 深度学习在过去十年获得了极高的关注 这归功于计算能力的不断发展和训练模型不断涌现出更有效的新方法 也源于可使用的数据量不断增加 什么是深度学习 为了理解深度
  • HBase启动RegionServer时报UnknownHostException错误的解决方法

    HBase启动RegionServer时报错 ERROR main regionserver HRegionServer Failed construction RegionServer java lang IllegalArgumentE
  • C++ string 类中方法 size() 和 length() 的区别

    首先说明 在C string类中 size 和length 方法是没有任何区别的 我们可以看 Microsoft Visual Studio 10 0 VC include xstring 文件 转到此两个方法的定义 size type l
  • Python3——matplotlib条形图的绘制

    实验环境 python 3 6 matplotlib 2 2 3 条形图的绘制 matplotlib pyplot bar left height alpha 1 width 0 8 color edgecolor label lw 3 1
  • 比df更好用的命令!

    大家好 我是良许 对于分析磁盘使用情况 有两个非常好用的命令 du 和 df 简单来说 这两个命令的作用是这样的 du 命令 它是英文单词 disk usage 的简写 主要用于查看文件与目录占用多少磁盘空间 df 命令 它是英文单词 di
  • 【SSH框架】慎用hibernate中的saveOrUpdate()方法,解决方案!

    今天写的项目中遇到一个异常 org springframework orm hibernate5 HibernateOptimisticLockingFailureException Batch update returned unexpe
  • 【马克思主义基本原理】--第二章--实践与认识及其发展规律

    实践与认识及其发展规律 文章目录 实践与认识及其发展规律 科学实践观 实践的本质与基本结构 真理和价值的辩证 科学实践观 马克思科学阐明了人类实践的本质和作用 创立了科学的实践观 科学的实践观是不断丰富发展的 总之 科学实践观从主观和客观
  • VS2017评估期已过的处理方法

    Visual Studio 2017 VS2017 企业版 Enterprise 注册码 NJVYC BMHX2 G77MM 4XJMR 6Q8QF Visual Studio 2017 VS2017 专业版Professional 激活码
  • r730xd服务器文档,r730xd配置服务器远程

    r730xd配置服务器远程 内容精选 换一换 如果默认的yum apt zypper源不可用 工具安装过程中会从华为开源镜像站匹配对应的镜像文件 并给出下载地址 如果没有匹配到 请自行获取对应操作系统版本的镜像文件 镜像文件名称请参见鲲鹏开
  • request.getRequestDispatcher(url) /error 404

    二 使用语法 request getRequestDispatcher 资源URI forward request response response sendRedirect web应用 资源URI 在进行web开发时 跳转是最常见的 包
  • Next 主题配置

    当前用得最多的是next主题 那为什么用得多呢 当然是符合大多数人的审美 我使用的是next v7 8 0 下载地址 theme next hexo theme next 1 基本设置 1 1 主题设置 打开博客根目录 Blog 文件夹 右
  • proteus仿真STM32串口的各种问题和解决办法

    最近在学习STM32串口通信 想试试能不能用proteus仿真 发现还是有挺多问题的 刚一开始在原理图放个STM32就报错 通过查阅资料才知道 选择 Design gt Configure Power Rails 添加到VCC VDD里头既
  • 测试开发必备10大技能,你达标了吗?

    一个人到底要走多少弯路 才能成为一名合格的测试开发工程师 近年来 随着敏捷开发 微服务架构 DevOps逐渐深入人心 软件行业发生了翻天覆地的变化 相应地 软件测试行业也洗牌加剧 软件测试的准入门槛 也从以前的是个人就行 逐渐变成了 科班出
  • JAVA————一门强大的面向对象编程语言

    JAVA 一门强大的面向对象编程语言 Java是一门面向对象编程语言 不仅吸收了C 语言的各种优点 还摒弃了C 里难以理解的多继承 指针等概念 因此Java语言具有功能强大和简单易用两个特征 Java语言作为静态面向对象编程语言的代表 极好
  • 卷积神经网络实现人脸表情识别

    文章目录 一 实现过程 1 1 下载数据集 1 2 根据猫狗数据集训练的方法来训练笑脸数据集 1 2 图片分类 1 3 作为健全性检查 计算一下在每个训练分割中我们有多少图片 训练 验证 测试 1 4 卷积网络模型搭建 1 5 图像生成器读