上海企业网站设计公司电话wordpress仿站教程

pingmian/2026/1/25 2:18:00/文章来源:
上海企业网站设计公司电话,wordpress仿站教程,跟网站开发有关的内容,百度网址大全址大全1 项目背景 #c 概述 项目的目的 图像分类是整个计算机视觉领域中最基础的任务#xff0c;也是最重要的任务之⼀#xff0c;最适合拿来进⾏学习实践。为了让新⼿们能够⼀次性体验⼀个⼯业级别的图像分类任务的完整流程#xff0c;本次我们选择带领⼤家完成⼀个对图片中⼈脸进…1 项目背景 #c 概述 项目的目的 图像分类是整个计算机视觉领域中最基础的任务也是最重要的任务之⼀最适合拿来进⾏学习实践。为了让新⼿们能够⼀次性体验⼀个⼯业级别的图像分类任务的完整流程本次我们选择带领⼤家完成⼀个对图片中⼈脸进⾏表情识别的任务。本任务只对嘴唇部分的表情进⾏识别所以我们的目标就是获取人脸嘴唇区域的图像然后进行分类。 #c 前景 项目的应用前景 ⼈脸表情识别(facial expression recognition, FER)作为⼈脸识别技术中的⼀个重要组成部分近年来在⼈机交互、安全、机器⼈制造、⾃动化、医疗、通信和驾驶领域得到了⼴泛的关注成为学术界和⼯业界的研究热点是⼈脸属性分析的重点。 #c 总结 项目总结 训练步骤 通过该项目初步对「深度学习」有了实践经验。整个学习的流程有四个步骤分别是 「数据收集」收集需要的数据可以通过爬虫的方式去收集自己想要的数据相关资料【杂谈】深度学习必备各路免费爬虫一举拿下。 「数据处理」把收集到的数据处理成需要的格式筛选掉不合格的数据和相关的脏数据。或者进一步提取数据。 「模型训练」搭建寻训练的模型准备模型的数据接口然后进行模型的训练。 「模型测试」对训练好额模型进行测试。 相关知识 在实践过程当中学习一些相关的概念知识整理到了第五点中。有「级联选择器」「字典推导式」「损失函数」「优化器」「学习率调度器」。 需继续学习的技术 需要继续深入学习「深度学习理论」「Numpy」「matplotlib」「OpenCV」「Pytorch」。 2 数据获取 #e 爬取数据的方法 使用爬虫工具获取图片的数据 本项目使用的爬虫项目是https://github.com/sczhengyabin/Image-Downloader 可以按要求爬取百度、Bing、Google 上的图片。 #c 问题 问题与解决方法 Ubuntu中出现xcd的问题 尝试了网上的各种方法最后改用windows上进行 3 数据处理 #c 解释 数据处理的重要性 爬取得到的数据是⽐较脏的需要进⾏整理主要包括统⼀图⽚后缀和重命名。统⼀后缀格式可以减少以后写数据 API 时的压⼒也可以测试图⽚是不是可以正常的读取及时防⽌未知问题的出现这很重要。 3.1 图片格式统一 #e 数据处理的代码 该py文件用一个函数listfiles于将指定目录下的所有图片文件转换为jpg格式的图片文件并删除原图片文件。 参数rootDir表示要转换的图片文件所在的目录 返回值无 总结 1.使用os.walk()函数遍历指定目录下的所有文件和子目录。 2.使用cv2.imread()函数读取图片文件。 3.使用cv2.imwrite()函数保存图片文件。 4.使用os.remove()函数删除原图片文件。 import os import cv2 def listfiles(rootDir):list_dirs os.walk(rootDir)用于生成文件夹中的文件名通过在目录树中游走。这个函数返回一个「三元组」(dirpath, dirnames, filenames)。dirpath是一个字符串表示当前正在遍历的目录的路径。dirnames是一个列表包含了dirpath下所有子目录的名字。filenames是一个列表包含了非目录文件的名字。这行代码中的list_dirs将会是一个「迭代器」每次迭代返回上述的三元组表示rootDir目录及其所有子目录中的文件和目录信息。for root, dirs, files in list_dirs:for d in dirs:print(os.path.join(root, d))#打印目录for f in files:fileid f.split(.)[0]#获取文件名filepath os.path.join(root, f)#获取文件路径print(filepath)try:#异常处理确保程序不会因为读取图片出错而中断src cv2.imread(filepath,1)#读取图片cv2.imread()函数读取图片接收两个参数第一个参数是图片路径第二个参数是读取图片的方式1表示读取彩色图片参数0表示读取灰度图片返回值是一个numpy数组表示图片的像素矩阵。print(src,filepath,src.shape)#src.shape是图片的尺寸os.remove(filepath)#删除原图片cv2.imwrite(os.path.join(root,fileid.jpg),src)#保存图片cv2.imwrite()函数保存图片接收两个参数第一个参数是保存图片的路径第二个参数是图片的像素矩阵返回值是一个布尔值表示是否保存成功except:os.remove(filepath)continue path ./opencv_facetest listfiles(path)3.2 数据清洗 #c 解释 为何清洗数据 利⽤搜索引擎爬取得到的图⽚肯定有「不符合要求」的数据清洗主要是「删除不合适」的图⽚即⾮⼈脸的照⽚。如果利⽤「⼈脸检测算法」仍然⽆法清除⼲净样本则需要⼿动筛选。当然如果你使⽤多个关键词或者使⽤不同的搜索引擎同样的关键词或者从视频中提取图⽚那么爬取回来的图⽚很可能有重复或者⾮常的相似这样的数据集需要「去重」。 #e 人脸检测算法 使用OpenCV检测图片中的人脸并显示出来删除没有人脸的图片 使用到的知识 1. OpenCV 的人脸检测接口 2. os.listdir() 方法用于返回指定的文件夹包含的文件或文件夹的名字的列表 3. os.remove() 方法用于删除文件 4. plt.imshow() 方法用于显示图片 5. plt.show() 方法用于显示图片 6. CascadeClassifier.detectMultiScale() 方法用于检测图片中的人脸 import cv2 import os import matplotlib.pyplot as plt# 人脸检测的接口这个是 OpenCV 中自带的 cascade_path ./Emotion_Recognition_File/face_detect_model/haarcascade_frontalface_default.xml cascade cv2.CascadeClassifier(cascade_path)xml文件是OpenCV中的一个训练好的分类器也就是一个训练好的模型包含了所有必要的参数和特征用于快速准确地检测图像中的面部。# img_path ./Emotion_Recognition_File/face_det_img/ # 测试图片路径 img_path ./opencv_facetest # def DelNoneFaceImage(img_path):删除没有人脸的图片images os.listdir(img_path)os.listdir() 方法用于返回指定的文件夹包含的文件或文件夹的名字的列表。这个列表以字母顺序。 它不包括 . 和.. 即使它在文件夹中。参数path表示要列出的目录返回值返回指定路径下的文件和文件夹列表for image in images:im cv2.imread(os.path.join(img_path, image), 1) # 读取图片rects cascade.detectMultiScale(im, 1.3, 5) # 人脸检测函数cascade.detectMultiScale()函数是OpenCV中的一个人脸检测函数用于检测图片中的人脸。它接收三个参数im待检测的图像通常是灰度图像因为Haar特征基于灰度值计算。1.3scaleFactor参数指定在图像尺寸减小时搜索窗口的缩放比例。值越大检测速度越快但可能错过一些小的或者是距离较远的面部。5minNeighbors参数指定每个候选矩形应该保留的邻近矩形的最小数量。这个参数控制着检测的质量较高的值会减少检测到的假阳性但也可能错过一些真正的对象。返回值是一个矩形列表每个矩形表示一个检测到的人脸。print(检测到人脸的数量, len(rects))if len(rects) 0: # len(rects) 是检测人脸的数量如果没有检测到人脸的话会显示出图片适合本地调试使用在服务器上可能不会显示os.remove(os.path.join(img_path, image)) # print(删除图片, image)print()print(删除完成)returndef DetcFaceImage(img_path):检测图片中的人脸并显示出来images os.listdir(img_path)for image in images:im cv2.imread(os.path.join(img_path, image), 1) # 读取图片rects cascade.detectMultiScale(im, 1.3, 5) # 人脸检测函数print(检测到人脸的数量, len(rects))if len(rects) 0: # len(rects) 是检测人脸的数量如果没有检测到人脸的话会显示出图片适合本地调试使用在服务器上可能不会显示passplt.imshow(im[:, :, ::-1]) # 显示plt.imshow()函数用于显示图片接收一个参数即要显示的图片。由于OpenCV读取的图片是BGR格式而matplotlib显示的图片是RGB格式所以需要将BGR格式转换为RGB格式。[:, :, ::-1]表示将图片的第三个维度颜色通道反转即将BGR转换为RGB。plt.show() # DelNoneFaceImage(img_path) DetcFaceImage(img_path)3.3 提取嘴唇区域 本任务只对嘴唇部分的表情进⾏识别所以我们的目标就是获取人脸嘴唇区域的图像然后进行分类。我们利⽤ OpencvDlib 算法提取嘴唇区域 Dlib 算法会得到⾯部的 68 个关键点我们从中得到嘴唇区域并适当扩⼤。 人脸 68 点位置图如下 #c 问题 dlib安装问题 PS E:\Projects\Emotion_Recognition pip install dlib× Building wheel for dlib (pyproject.toml) did not run successfully.│ exit code: 1╰─ [13 lines of output]running bdist_wheelrunning buildrunning build_extTraceback (most recent call last):ModuleNotFoundError: No module named cmakeERROR: CMake must be installed to build dlib[end of output]note: This error originates from a subprocess, and is likely not a problem with pip.ERROR: Failed building wheel for dlib Failed to build dlib ERROR: Could not build wheels for dlib, which is required to install pyproject.toml-based projects解决方法安装cmakepip install cmake ,然后指定dlib的版本pip install dlib19.24.2 #e 提取的代码 下面的代码可以对图片进行人脸检测检测到人脸后会将嘴巴区域分割出来形成数据集。 该py文件用于获取人脸关键点并根据关键点获取嘴唇区域。 思路 1.使用Dlib库加载预训练的人脸关键点检测模型。 2.使用OpenCV加载人脸检测器。 3.遍历指定目录下的所有图片文件。 4.使用OpenCV读取图片。 5.使用Dlib检测人脸关键点。 6.根据关键点获取嘴唇区域。 7.保存嘴唇区域。import cv2 import dlib import numpy as np import os import matplotlib.pyplot as plt# 配置 Dlib 关键点检测路径 # 文件可以从 http://dlib.net/files/ 下载 PREDICTOR_PATH ./Emotion_Recognition_File/face_detect_model/shape_predictor_68_face_landmarks.dat预训练的人脸关键点检测模型用于检测人脸的关键点。predictor dlib.shape_predictor(PREDICTOR_PATH)dlib.shape_predictor()函数用于加载一个预训练的人脸关键点检测模型。 这个函数接收一个参数表示模型文件的路径。# 配置人脸检测器路径 cascade_path ./Emotion_Recognition_File/face_detect_model/haarcascade_frontalface_default.xml cascade cv2.CascadeClassifier(cascade_path)def get_landmarks(im):函数获取人脸关键点参数im表示输入的图片返回值返回一个矩阵表示人脸关键点的坐标rects cascade.detectMultiScale(im, 1.3, 5) # 人脸检测x, y, w, h rects[0] # 获取人脸的四个属性值左上角坐标 x,y 、高宽 w、h#array([[209, 156, 289, 289]])#print(x, y, w, h)rect dlib.rectangle(int(x), int(y), int(x w), int(y h))目的将人脸检测的结果转换为dlib的矩形对象dlib.rectangle()函数用于创建一个矩形对象表示一个矩形区域。这个函数接收四个参数分别是矩形的左上角和右下角的坐标。 return np.matrix([[p.x, p.y] for p in predictor(im, rect).parts()])np.matrix()函数用于将列表转换为矩阵。predictor(im, rect)这个函数调用使用predictor对象之前通过dlib.shape_predictor加载的面部关键点检测器在图像im中的指定区域rect一个矩形通常是通过面部检测得到的上检测面部关键点。predictor函数返回一个包含检测到的面部关键点的对象。.parts()这个方法被调用来获取检测到的所有面部关键点。它返回一个包含多个点的对象每个点代表一个关键点的位置。[p.x, p.y for p in ...]这是一个列表推导式用于遍历parts()返回的所有关键点p并为每个关键点创建一个包含其x和y坐标的列表。np.matrix([...])这将上一步得到的坐标列表转换成一个NumPy矩阵。NumPy矩阵是一个二维数组这里每一行代表一个关键点的x和y坐标def annotate_landmarks(im, landmarks):目的在图片上标记关键点参数im表示输入的图片landmarks表示关键点坐标im im.copy()# 复制图片for idx, point in enumerate(landmarks):#enumerate()函数用于将一个可遍历的数据对象组合为一个索引序列同时列出数据和数据下标pos (point[0, 0], point[0, 1])cv2.putText(im,str(idx),# 文本内容pos,# 位置fontFacecv2.FONT_HERSHEY_SCRIPT_SIMPLEX,# 字体fontScale0.4,# 字体大小color(0, 0, 255))# 颜色cv2.circle(im, pos, 5, color(0, 255, 255))# 画圆return imdef getlipfromimage(im, landmarks):功能获取嘴唇区域参数im表示输入的图片landmarks表示关键点坐标返回值返回一个矩形区域表示嘴唇区域xmin 10000xmax 0ymin 10000ymax 0# 根据最外围的关键点获取包围嘴唇的最小矩形框# 68 个关键点是从# 左耳朵0 -下巴-右耳朵16-左眉毛17-21-右眉毛22-26-左眼睛36-41# 右眼睛42-47-鼻子从上到下27-30-鼻孔31-35# 嘴巴外轮廓48-59嘴巴内轮廓60-67for i in range(48, 67):for循环遍历关键点找到嘴唇区域的最小矩形框x landmarks[i, 0]y landmarks[i, 1]if x xmin:xmin xif x xmax:xmax xif y ymin:ymin yif y ymax:ymax yprint(xmin, xmin)print(xmax, xmax)print(ymin, ymin)print(ymax, ymax)roiwidth xmax - xmin# 嘴唇区域的宽度roiheight ymax - ymin# 嘴唇区域的高度roi im[ymin:ymax, xmin:xmax, 0:3]im[ymin:ymax, xmin:xmax, 0:3]这是一个NumPy数组切片操作用于从原始图像中提取嘴唇区域。它接收三个参数分别是ymin:ymax、xmin:xmax和0:3。ymin:ymax和xmin:xmax表示切片的范围0:3表示提取所有的通道RGB。该操作返回一个包含嘴唇区域的NumPy数组。# 将嘴唇区域扩大1.5倍if roiwidth roiheight:dstlen 1.5 * roiwidthelse:dstlen 1.5 * roiheight# 计算嘴唇区域的中心点diff_xlen dstlen - roiwidthdiff_ylen dstlen - roiheightnewx xminnewy yminimagerows, imagecols, channel im.shapeim.shape是一个元组包含三个元素分别是图像的行数、列数和通道数。if newx diff_xlen / 2 and newx roiwidth diff_xlen / 2 imagecols:newx newx - diff_xlen / 2elif newx diff_xlen / 2:newx 0else:newx imagecols - dstlenif newy diff_ylen / 2 and newy roiheight diff_ylen / 2 imagerows:newy newy - diff_ylen / 2elif newy diff_ylen / 2:newy 0else:newy imagerows - dstlen上述代码通过智能调整ROI的位置确保ROI始终位于图像的有效区域内既不会超出图像边界也尽可能保持其原始尺寸和形状。这在进行图像处理和分析时非常重要特别是在需要精确操作图像特定区域的应用中roi im[int(newy):int(newy dstlen), int(newx):int(newx dstlen), 0:3]使用了Python的切片语法来从图像中提取ROI。int(newy):int(newy dstlen)和int(newx):int(newx dstlen)分别定义了ROI在y方向和x方向上的范围。0:3指定了颜色通道的范围对于一个标准的BGR颜色图像这意味着选择所有三个颜色通道蓝色、绿色、红色return roidef listfiles(rootDir):list_dirs os.walk(rootDir)for root, dirs, files in list_dirs:for d in dirs:print(os.path.join(root, d))for f in files:fileid f.split(.)[0]filepath os.path.join(root, f)try:im cv2.imread(filepath, 1)landmarks get_landmarks(im)# 获取关键点roi getlipfromimage(im, landmarks)# 获取嘴唇区域roipath filepath.replace(.jpg, _mouth.png)# 保存嘴唇区域 # cv2.imwrite(roipath, roi)plt.imshow(roi[:, :, ::-1])plt.show()except: # print(error)continuelistfiles(./Emotion_Recognition_File/face_det_img/)4 模型搭建训练与测试 4.1 数据接口准备 #c 说明 数据接口准备 直接利用文件夹作为输入只需要把不同类的数据放到不同的文件夹中。输入一个文件夹输出图片路径以及标签在开始训练之前需要将数据集进行拆分拆分成训练集(train)和验证集(val)训练集和测试集的比例为9:1train_val_data文件结构如下所示其中 0 代表 none、 1 代表pouting、2 代表 smile、3 代表 openmouth #e 准备的代码 数据接口准备 data_transforms {train: transforms.Compose([transforms.RandomResizedCrop(48),# 随机裁剪调整为48*48像素大小增强泛化transforms.RandomHorizontalFlip(),# 随机水平翻转增强泛化transforms.ToTensor(),# 转换为张量transforms.Normalize([0.5,0.5,0.5], [0.5,0.5,0.5])# 标准化]),val: transforms.Compose([transforms.Resize(64),# 调整为64*64像素大小transforms.CenterCrop(48),# 中心裁剪调整为48*48像素大小transforms.ToTensor(),# 转换为张量transforms.Normalize([0.5,0.5,0.5], [0.5,0.5,0.5])# 标准化]),}data_dir ./Emotion_Recognition_File/train_val_data/ # 数据集所在的位置#创建图像数据集image_datasets {x: datasets.ImageFolder(os.path.join(data_dir, x),data_transforms[x]) for x in [train, val]}#创建数据加载器dataloders {x: torch.utils.data.DataLoader(image_datasets[x],# 数据集batch_size64,# 每个批次加载64个样本shuffleTrue if xtrain else False,# 训练集打乱验证集不打乱num_workers8) for x in [train, val]}# 使用8个子进程加载数据dataset_sizes {x: len(image_datasets[x]) for x in [train, val]}# 数据集大小4.2 模型定义 #c 说明 模型定义 创建数据接⼝后开始定义⼀个⽹络 simpleconv3。一个简单的 3 层卷积。在 torch.nn 下有各种网络层这里就用到了 nn.Conv2dnn.BatchNorm2d 和 nn.Linear分别是卷积层BN 层和全连接层。我们以一个卷积层为例 conv1 nn.Conv2d(in_channels3, out_channels12, kernel_size3, stride2) bn1 nn.BatchNorm2d(num_features12)in_channels输入通道数out_channels输出通道数kernel_size卷积核的大小stride卷积核的移动步长 #e 模型定义的代码 模型定义 # 定义一个简单的卷积神经网络 class simpleconv3(nn.Module):def __init__(self):super(simpleconv3,self).__init__()#调用父类的构造函数self.conv1 nn.Conv2d(3, 12, 3, 2)#定义第一个卷积层self.bn1 nn.BatchNorm2d(12)#定义第一个批标准化层self.conv2 nn.Conv2d(12, 24, 3, 2)#定义第二个卷积层self.bn2 nn.BatchNorm2d(24)#定义第二个批标准化层self.conv3 nn.Conv2d(24, 48, 3, 2)#定义第三个卷积层self.bn3 nn.BatchNorm2d(48)#定义第三个批标准化层self.fc1 nn.Linear(48 * 5 * 5 , 1200)#定义第一个全连接层self.fc2 nn.Linear(1200 , 128)#定义第二个全连接层self.fc3 nn.Linear(128 , 4)#定义第三个全连接层def forward(self , x):#前向传播x F.relu(self.bn1(self.conv1(x)))#卷积层-批标准化层-激活函数#print bn1 shape,x.shapex F.relu(self.bn2(self.conv2(x)))#卷积层-批标准化层-激活函数x F.relu(self.bn3(self.conv3(x)))x x.view(-1 , 48 * 5 * 5) #reshape操作x F.relu(self.fc1(x))#全连接层-激活函数x F.relu(self.fc2(x))x self.fc3(x)#全连接层return x4.3 模型训练 #c 说明 测试的意义 验证模型准确性通过测试可以验证模型的预测结果是否符合预期确保模型的准确性和可靠性。性能评估测试可以评估模型在不同条件下的性能包括处理速度、资源消耗等以确保模型在实际应用中的效率。发现问题通过对模型进行系统的测试可以发现模型设计或实现过程中的问题如过拟合、欠拟合等。模型优化测试结果可以为模型的进一步优化提供依据帮助开发者调整模型参数改进模型结构。 #e 训练代码 from __future__ import print_function, divisionimport torch import torch.nn as nn import torch.optim as optim from torch.optim import lr_scheduler from torch.autograd import Variable import torchvision from torchvision import datasets, models, transforms import time import os from tensorboardX import SummaryWriter import torch.nn.functional as F import numpy as npimport warnings# 定义一个简单的卷积神经网络 class simpleconv3(nn.Module):def __init__(self):super(simpleconv3,self).__init__()#调用父类的构造函数self.conv1 nn.Conv2d(3, 12, 3, 2)#定义第一个卷积层self.bn1 nn.BatchNorm2d(12)#定义第一个批标准化层self.conv2 nn.Conv2d(12, 24, 3, 2)#定义第二个卷积层self.bn2 nn.BatchNorm2d(24)#定义第二个批标准化层self.conv3 nn.Conv2d(24, 48, 3, 2)#定义第三个卷积层self.bn3 nn.BatchNorm2d(48)#定义第三个批标准化层self.fc1 nn.Linear(48 * 5 * 5 , 1200)#定义第一个全连接层self.fc2 nn.Linear(1200 , 128)#定义第二个全连接层self.fc3 nn.Linear(128 , 4)#定义第三个全连接层def forward(self , x):#前向传播x F.relu(self.bn1(self.conv1(x)))#卷积层-批标准化层-激活函数#print bn1 shape,x.shapex F.relu(self.bn2(self.conv2(x)))#卷积层-批标准化层-激活函数x F.relu(self.bn3(self.conv3(x)))x x.view(-1 , 48 * 5 * 5) #reshape操作x F.relu(self.fc1(x))#全连接层-激活函数x F.relu(self.fc2(x))x self.fc3(x)#全连接层return xwarnings.filterwarnings(ignore)#忽略警告writer SummaryWriter()#创建一个SummaryWriter对象用于记录训练过程中的损失和准确率def train_model(model, criterion, optimizer, scheduler, num_epochs25):功能训练神经网络参数 model表示要训练的神经网络criterion表示损失函数optimizer表示优化器scheduler表示学习率调度器num_epochs表示训练的轮次返回值model表示训练好的神经网络for epoch in range(num_epochs):print(Epoch {}/{}.format(epoch, num_epochs - 1))# 打印训练次数for phase in [train, val]:#训练和验证if phase train:#训练阶段scheduler.step()#学习率调度器更新学习率model.train(True) # Set model to training modeelse:model.train(False) # Set model to evaluate moderunning_loss 0.0#累计当前阶段的总损失有助于计算平均损失running_corrects 0.0#累计当前阶段的总准确率有助于计算平均准确率for data in dataloders[phase]:#遍历数据加载器inputs, labels data#获取输入数据和标签if use_gpu:#使用GPUinputs Variable(inputs.cuda())#将输入数据转换为Variable类型labels Variable(labels.cuda())#将标签转换为Variable类型else:inputs, labels Variable(inputs), Variable(labels)optimizer.zero_grad()#进行一次前向传播之前清零之前的梯度以防止梯度累积outputs model(inputs)#将输入数据喂给模型进行一次前向传播得到模型的输出。_, preds torch.max(outputs.data, 1)#从模型输出中找到每个样本预测概率最高的类别作为预测结果。loss criterion(outputs, labels)#计算模型输出和标签之间的损失if phase train:#训练阶段loss.backward()#进行一次反向传播计算梯度optimizer.step()#更新模型参数running_loss loss.data.item()#累计当前阶段的总损失running_corrects torch.sum(preds labels).item()#累计当前阶段的总准确率epoch_loss running_loss / dataset_sizes[phase]#计算平均损失epoch_acc running_corrects / dataset_sizes[phase]#计算平均准确率if phase train:writer.add_scalar(data/trainloss, epoch_loss, epoch)#记录训练阶段的平均损失writer.add_scalar(data/trainacc, epoch_acc, epoch)#记录训练阶段的平均准确率else:writer.add_scalar(data/valloss, epoch_loss, epoch)#记录验证阶段的平均损失writer.add_scalar(data/valacc, epoch_acc, epoch)#记录验证阶段的平均准确率print({} Loss: {:.4f} Acc: {:.4f}.format(phase, epoch_loss, epoch_acc))writer.export_scalars_to_json(./all_scalars.json)#将记录的数据保存为json文件writer.close()#关闭SummaryWriter对象return modelif __name__ __main__:data_transforms {train: transforms.Compose([transforms.RandomResizedCrop(48),# 随机裁剪调整为48*48像素大小增强泛化transforms.RandomHorizontalFlip(),# 随机水平翻转增强泛化transforms.ToTensor(),# 转换为张量transforms.Normalize([0.5,0.5,0.5], [0.5,0.5,0.5])# 标准化]),val: transforms.Compose([transforms.Resize(64),# 调整为64*64像素大小transforms.CenterCrop(48),# 中心裁剪调整为48*48像素大小transforms.ToTensor(),# 转换为张量transforms.Normalize([0.5,0.5,0.5], [0.5,0.5,0.5])# 标准化]),}data_dir ./Emotion_Recognition_File/train_val_data/ # 数据集所在的位置#创建图像数据集image_datasets {x: datasets.ImageFolder(os.path.join(data_dir, x),data_transforms[x]) for x in [train, val]}#创建数据加载器dataloders {x: torch.utils.data.DataLoader(image_datasets[x],# 数据集batch_size64,# 每个批次加载64个样本shuffleTrue if xtrain else False,# 训练集打乱验证集不打乱num_workers8) for x in [train, val]}# 使用8个子进程加载数据dataset_sizes {x: len(image_datasets[x]) for x in [train, val]}# 数据集大小use_gpu torch.cuda.is_available()# 是否使用GPUprint(是否使用 GPU, use_gpu)modelclc simpleconv3()# 创建模型print(modelclc)if use_gpu:modelclc modelclc.cuda()# 使用GPU#配置神经网络训练过程中的损失函数、优化器和学习率调度器的。criterion nn.CrossEntropyLoss()#选择交叉熵损失函数optimizer_ft optim.SGD(modelclc.parameters(), lr0.1, momentum0.9)随机梯度下降SGD优化器用于更新模型的权重。modelclc.parameters() 提供了模型中所有可训练的参数。lr0.1 设置了学习率为 0.1这是在训练过程中每次参数更新的步长。momentum0.9 设置了动量为 0.9这有助于加速优化器在相关方向上的速度并减少震荡。exp_lr_scheduler lr_scheduler.StepLR(optimizer_ft, step_size100, gamma0.1)这行代码定义了一个学习率调度器它会在每过 step_size这里是100个训练轮次后将学习率乘以 gamma这里是0.1。这意味着每100个训练轮次学习率会减少到原来的10%。这种方法有助于模型在训练早期快速收敛并在训练后期通过减小学习率来细化模型参数以避免过拟合modelclc train_model(modelmodelclc,# 模型criterioncriterion,# 损失函数optimizeroptimizer_ft,# 优化器schedulerexp_lr_scheduler,# 学习率调度器num_epochs10) # 这里可以调节训练的轮次#保存模型if not os.path.exists(models):os.mkdir(models)torch.save(modelclc.state_dict(),models/model.ckpt)# 保存模型参数4.4 模型测试 #e 测试代码 import sys import numpy as np import cv2 import os import dlibimport torch import torch.nn as nn import torch.optim as optim from torch.optim import lr_scheduler from torch.autograd import Variable import torchvision from torchvision import datasets, models, transforms import time from PIL import Image import torch.nn.functional as Fimport matplotlib.pyplot as plt import warningswarnings.filterwarnings(ignore)#忽略警告 class simpleconv3(nn.Module):#定义一个简单的三层卷积神经网络def __init__(self):super(simpleconv3,self).__init__()#复制并使用simpleconv3的父类的初始化方法即先运行nn.Module的初始化函数self.conv1 nn.Conv2d(3, 12, 3, 2)#定义conv1函数的是图像卷积层输入是3个feature输出是6个featurekernel是3*3步长为2self.bn1 nn.BatchNorm2d(12)self.conv2 nn.Conv2d(12, 24, 3, 2)self.bn2 nn.BatchNorm2d(24)self.conv3 nn.Conv2d(24, 48, 3, 2)self.bn3 nn.BatchNorm2d(48)self.fc1 nn.Linear(48 * 5 * 5 , 1200)self.fc2 nn.Linear(1200 , 128)self.fc3 nn.Linear(128 , 4)def forward(self , x):x F.relu(self.bn1(self.conv1(x)))#print bn1 shape,x.shapex F.relu(self.bn2(self.conv2(x)))x F.relu(self.bn3(self.conv3(x)))x x.view(-1 , 48 * 5 * 5) x F.relu(self.fc1(x))x F.relu(self.fc2(x))x self.fc3(x)return xPREDICTOR_PATH ./Emotion_Recognition_File/face_detect_model/shape_predictor_68_face_landmarks.dat predictor dlib.shape_predictor(PREDICTOR_PATH)#加载人脸关键点检测模型 cascade_path ./Emotion_Recognition_File/face_detect_model/haarcascade_frontalface_default.xml cascade cv2.CascadeClassifier(cascade_path)#加载人脸检测器if not os.path.exists(results):os.mkdir(results)def standardization(data):功能标准化数据参数data数据返回标准化后的数据mu np.mean(data, axis0)#计算每一列的均值axis0表示列axis1表示行sigma np.std(data, axis0)#计算每一列的标准差axis表示方向return (data - mu) / sigma数据按列减去其平均值后再除以其标准差。这一步是标准化的核心目的是让处理后的数据每一列的平均值为0标准差为1。这样处理后的数据符合标准正态分布有利于后续的数据处理和分析。def get_landmarks(im):功能获取人脸关键点参数im图像返回人脸关键点rects cascade.detectMultiScale(im, 1.3, 5)#检测人脸x, y, w, h rects[0]#获取人脸区域rect dlib.rectangle(int(x), int(y), int(x w), int(y h))#转换为dlib格式的人脸区域return np.matrix([[p.x, p.y] for p in predictor(im, rect).parts()])#获取人脸关键点def annotate_landmarks(im, landmarks):功能标注人脸关键点参数im图像landmarks人脸关键点返回标注后的图像im im.copy()for idx, point in enumerate(landmarks):pos (point[0, 0], point[0, 1])cv2.putText(im,str(idx),pos,fontFacecv2.FONT_HERSHEY_SCRIPT_SIMPLEX,fontScale0.4,color(0, 0, 255))cv2.circle(im, pos, 3, color(0, 255, 255))return imtestsize 48 # 测试图大小data_transforms transforms.Compose([transforms.ToTensor(),transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5]) ]) net simpleconv3()#创建模型实例 net.eval()#评估模式 modelpath ./models/model.ckpt # 模型路径 net.load_state_dict(#加载模型保存的模型权重torch.load(modelpath, map_locationlambda storage, loc: storage)) map_location参数用于指定加载模型的设备位置。这里使用了一个lambda函数lambda storage, loc: storage这意味着无论模型权重文件是在哪个设备上保存的例如GPU或CPU都将其加载到当前设备上。这对于跨设备加载模型非常有用特别是当原始训练环境与当前环境不同时。lambda语法lambda 参数:表达式# 一次测试一个文件 img_path ./Emotion_Recognition_File/test_img/ imagepaths os.listdir(img_path) # 图像文件夹 for imagepath in imagepaths:im cv2.imread(os.path.join(img_path, imagepath), 1)try:rects cascade.detectMultiScale(im, 1.3, 5)#检测人脸x, y, w, h rects[0]rect dlib.rectangle(int(x), int(y), int(x w), int(y h))landmarks np.matrix([[p.x, p.y]for p in predictor(im, rect).parts()])except: # print(没有检测到人脸)continue # 没有检测到人脸xmin 10000xmax 0ymin 10000ymax 0for i in range(48, 67):x landmarks[i, 0]y landmarks[i, 1]if x xmin:xmin xif x xmax:xmax xif y ymin:ymin yif y ymax:ymax yroiwidth xmax - xminroiheight ymax - yminroi im[ymin:ymax, xmin:xmax, 0:3]if roiwidth roiheight:dstlen 1.5 * roiwidthelse:dstlen 1.5 * roiheightdiff_xlen dstlen - roiwidthdiff_ylen dstlen - roiheightnewx xminnewy yminimagerows, imagecols, channel im.shapeif newx diff_xlen / 2 and newx roiwidth diff_xlen / 2 imagecols:newx newx - diff_xlen / 2elif newx diff_xlen / 2:newx 0else:newx imagecols - dstlenif newy diff_ylen / 2 and newy roiheight diff_ylen / 2 imagerows:newy newy - diff_ylen / 2elif newy diff_ylen / 2:newy 0else:newy imagecols - dstlenroi im[int(newy):int(newy dstlen), int(newx):int(newx dstlen), 0:3]#裁剪图像roi cv2.cvtColor(roi, cv2.COLOR_BGR2RGB)#转换颜色空间将BGR转为RGBroiresized cv2.resize(roi,#调整图像大小(testsize, testsize)).astype(np.float32) / 255.0imgblob data_transforms(roiresized).unsqueeze(0)#转换数据格式imgblob.requires_grad False#不需要梯度因为是验证阶段而不是训练阶段imgblob Variable(imgblob)#转换数据格式torch.no_grad()#通过上下文管理器禁用梯度计算predict F.softmax(net(imgblob))#net(imgblob)是模型的输出F.softmax()是softmax函数用于多分类问题print(predict)index np.argmax(predict.detach().numpy())#获取预测结果np.argmax()返回概率最大的类别im_show cv2.imread(os.path.join(img_path, imagepath), 1)im_h, im_w, im_c im_show.shape#获取图像的高、宽、通道数pos_x int(newx dstlen)pos_y int(newy dstlen)font cv2.FONT_HERSHEY_SIMPLEX#设置字体样式cv2.rectangle(im_show, (int(newx), int(newy)),#画矩形框(int(newx dstlen), int(newy dstlen)), (0, 255, 255), 2)if index 0:cv2.putText(im_show, none, (pos_x, pos_y), font, 1.5, (0, 0, 255), 2)if index 1:cv2.putText(im_show, pout, (pos_x, pos_y), font, 1.5, (0, 0, 255), 2)if index 2:cv2.putText(im_show, smile, (pos_x, pos_y), font, 1.5, (0, 0, 255), 2)if index 3:cv2.putText(im_show, open, (pos_x, pos_y), font, 1.5, (0, 0, 255), 2) # cv2.namedWindow(result, 0) # cv2.imshow(result, im_show)cv2.imwrite(os.path.join(results, imagepath), im_show) # print(os.path.join(results, imagepath))plt.imshow(im_show[:, :, ::-1]) # 这里需要交换通道因为 matplotlib 保存图片的通道顺序是 RGB而在 OpenCV 中是 BGRplt.show() # cv2.waitKey(0) # cv2.destroyAllWindows()5 相关概念 #d 级联选择器 级联分类器Cascade Classifier是一种基于机器学习的对象检测技术它能够在图像中快速识别出目标对象如人脸、行人等。这个概念主要用于解决对象检测问题特别是在实时应用中如视频监控、人脸识别等场景。 解决的问题 速度与准确性的平衡级联分类器通过一系列的简单到复杂的分类阶段称为“级联”来检测对象每个阶段使用不同的特征集。这种方法可以快速排除背景区域仅在可能包含目标对象的区域使用更复杂的特征从而实现高效率和较高准确性的平衡。实时检测由于其高效性级联分类器特别适合于需要实时处理的应用如实时视频分析。 没有这个概念的影响 检测速度下降没有级联分类器我们可能需要在整个图像上运行复杂的检测算法这会大大增加计算量降低检测速度尤其是在处理高分辨率视频或实时应用时。准确性和效率的挑战缺乏有效的筛选机制可能导致算法在背景区域浪费大量计算资源同时也可能降低检测的准确性因为算法需要在更广泛的区域中寻找目标对象。实时应用受限在没有高效检测算法的情况下很多需要实时反馈的应用如动态人脸识别系统、实时监控系统可能难以实现或者性能大打折扣。 #e 视频流中识别人脸 级联选择器 import cv2 # 加载预训练的Haar级联分类器 cascade_path ./haarcascade_frontalface_default.xml face_cascade cv2.CascadeClassifier(cascade_path)#级联选择器# 打开摄像头 cap cv2.VideoCapture(0) while True:# 读取一帧图像ret, frame cap.read()if not ret:break# 将图像转换为灰度图因为Haar分类器需要灰度图gray cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)# 使用级联分类器检测图像中的人脸faces face_cascade.detectMultiScale(gray, scaleFactor1.1, minNeighbors5, minSize(30, 30))# 为每个检测到的人脸画一个矩形框for (x, y, w, h) in faces:cv2.rectangle(frame, (x, y), (xw, yh), (255, 0, 0), 2)# 显示结果图像cv2.imshow(Face Detection, frame)# 按q退出循环if cv2.waitKey(1) 0xFF ord(q):break # 释放摄像头并关闭窗口 cap.release() cv2.destroyAllWindows()#e 公园里找朋友 级联选择器 想象一下你在一个拥挤的公园里寻找你的朋友。你不能一次性仔细观察每一个人这样做效率太低。相反你可以采用类似级联分类器的策略 远距离快速扫描首先你从远处开始快速扫视人群排除那些明显不符合你朋友特征比如身高、衣着颜色的人。中距离筛选接着对于剩下可能符合的人群你走近一些关注更多细节比如发型或者是特定的配饰进一步缩小范围。近距离确认最后对于少数几个高度匹配的目标你可以走到很近的地方确认是否是你的朋友。 这个过程就像是一个级联的过滤器每一步都排除了大量不符合条件的目标最终快速而准确地找到了你的朋友。 #d 字典推导式 字典推导式是一种简洁的构建字典的方法它可以通过一个表达式来创建一个字典其中包含了键值对key-value pairs。这个概念主要是为了解决在创建字典时需要通过循环和条件语句来添加键值对的复杂性问题。 没有字典推导式的影响 代码冗长在没有字典推导式的情况下你可能需要使用循环和条件语句来构建字典这会使代码变得更长、更复杂。效率低下手动通过循环添加键值对可能会比使用字典推导式慢特别是在处理大量数据时。可读性差字典推导式提供了一种更清晰、更直观的方式来表达如何从一个序列或者其他数据结构中构建字典没有它代码可能会更难理解。 字典推导式对以下概念起作用 简洁的代码它提供了一种更简洁的方法来创建字典。数据转换它可以用来轻松地从一个数据结构如列表、元组列表等转换为字典。条件过滤在字典推导式中可以使用if语句来过滤掉不符合条件的元素从而只包含满足特定条件的键值对。自动化处理它可以用于自动化地处理数据集合将其转换为字典形式特别是在数据预处理和数据分析中非常有用。 总的来说字典推导式是一种非常有用的工具它可以使代码更加简洁、高效并且提高代码的可读性。 #e 字符串转字典 字典推导式 # 字符串列表 words [apple, banana, cherry] # 使用字典推导式创建一个字典其中键是列表中的字符串值是对应字符串的长度 word_lengths {word: len(word) for word in words} print(word_lengths) # 输出{apple: 5, banana: 6, cherry: 6}#d 损失函数 损失函数Loss Function是机器学习和深度学习中的一个核心概念用于衡量模型预测值与真实值之间的差异。其主要目的是指导模型学习通过最小化损失函数来优化模型参数使模型的预测更加准确。损失函数是机器学习和深度学习中不可或缺的一部分它为模型训练提供了方向和目标是实现模型优化和提高预测准确性的关键。 解决的问题 提供反馈信号损失函数为模型训练提供了反馈信号指示模型当前的表现如何以及如何调整参数以改进性能。优化目标它定义了一个明确的优化目标。在训练过程中通过最小化损失函数模型能够学习到数据的内在规律和模式。适应不同问题不同的问题可以通过选择合适的损失函数来更好地优化例如分类问题常用交叉熵损失回归问题常用均方误差损失。 没有损失函数会导致的结果 无法衡量性能没有损失函数我们将无法量化模型预测的好坏也就无法判断模型是否在学习或进步。缺乏优化方向模型训练需要一个明确的目标或标准来进行参数的调整和优化。没有损失函数模型就没有明确的优化方向无法进行有效的参数更新。无法适应不同问题不同类型的问题需要不同的优化策略。没有损失函数就无法为不同的问题设计和选择最合适的优化目标从而降低模型的适用性和准确性。 线性回归是一种预测连续值的算法。假设我们有一组数据点我们想要找到一条直线这条直线能够尽可能地接近所有的数据点。这里损失函数的作用就是衡量这条直线与实际数据点之间的差距。 #e 均方误差MSE 损失函数 假设我们的直线方程为 y wx b其中 w 是权重b 是偏置。对于每个数据点 (x_i, y_i)直线给出的预测值是 ŷ_i wx_i b。均方误差MSE损失函数计算所有数据点的真实值 y_i 与预测值 ŷ_i 之间差值的平方和的平均值 MSE (1/n) * Σ(y_i - ŷ_i)^2 其中 n 是数据点的总数Σ 表示求和。通过最小化这个损失函数我们可以找到最佳的 w 和 b使得直线尽可能地接近所有的数据点。 #e 减肥 损失函数 假设你想要减肥你设定了一个目标在接下来的三个月内减掉10公斤。在这个过程中你每周都会称一次体重记录下来并与你的目标进行比较。 在这个例子中你的“损失函数”可以看作是每次称重时与目标体重差距的大小。如果这个差距在减小说明你的减肥计划正在取得进展如果这个差距在增大或不变说明你需要调整你的饮食或运动计划。 就像在机器学习中通过调整模型参数来最小化损失函数一样你也可以通过调整你的饮食习惯和运动计划来“最小化”你的体重差距更接近你的减肥目标。 #c 补充 相关概念 损失函数会影响的概念 优化器Optimizer优化器使用损失函数的梯度来更新模型的参数以减少损失。不同的优化器如SGD、Adam可能会对损失函数的下降速度和稳定性产生不同的影响。正则化Regularization正则化项可以添加到损失函数中以防止模型过拟合。正则化如L1、L2会影响损失函数的形式和模型的最终性能。学习率Learning Rate学习率决定了在优化过程中参数更新的步长大小。它直接影响损失函数下降的速度和是否能够收敛到最小值。 影响损失函数的概念 模型复杂度Model Complexity模型的复杂度决定了其拟合数据的能力。过于复杂的模型可能导致过拟合这时即使损失函数在训练集上很低也可能在测试集上表现不佳。数据预处理Data Preprocessing数据的预处理方式如标准化、归一化会影响模型的学习过程进而影响损失函数的表现。不同的数据分布可能需要不同的损失函数。特征工程Feature Engineering有效的特征工程可以提高模型的性能减少损失。选择和构造与预测任务高度相关的特征可以使损失函数更有效地指导模型学习。 #d 优化器 优化器Optimizer是机器学习和深度学习中用于更新和调整模型参数如权重和偏置以最小化损失函数的算法。优化器的目的是找到损失函数的最小值从而提高模型的预测准确性。 创造优化器解决的问题 参数更新在模型训练过程中需要一种方法来决定如何更新模型的参数以便于模型能够学习到数据的特征和规律。优化器提供了这样一种方法。收敛速度不同的优化算法会影响模型训练的速度。一些优化器能够加快模型收敛的速度使训练过程更高效。避免局部最小值在复杂的损失函数中可能存在多个局部最小值。优化器的设计旨在帮助模型避免陷入局部最小值寻找到全局最小值或较好的局部最小值。 没有优化器会导致的结果 无法有效更新模型参数没有优化器我们将缺乏一种系统性的方法来调整模型参数这将导致模型无法从训练数据中学习。训练效率低下即使可以手动调整模型参数但这种方法效率极低且难以找到损失函数的最小值导致训练时间长效果差。模型性能不佳缺乏有效的优化策略模型可能无法达到较好的性能特别是在处理复杂任务和大规模数据集时 #e 深度学习中优化器 优化器 在深度学习模型训练过程中优化器负责调整模型的权重以最小化损失函数。假设我们正在训练一个用于图像分类的卷积神经网络CNN。我们选择Adam优化器因为它结合了动量Momentum和自适应学习率AdaGrad的优点适合处理大规模数据和参数的优化问题。 import torch import torch.nn as nn import torch.optim as optimmodel MyCNN() # 假设MyCNN是我们定义的卷积神经网络 criterion nn.CrossEntropyLoss() # 选择交叉熵损失函数 optimizer optim.Adam(model.parameters(), lr0.001) # 使用Adam优化器学习率设置为0.001# 训练模型的简化代码 for epoch in range(num_epochs):for inputs, labels in dataloader:optimizer.zero_grad() # 清空之前的梯度outputs model(inputs) # 前向传播loss criterion(outputs, labels) # 计算损失loss.backward() # 反向传播计算梯度optimizer.step() # 更新权重优化器Adam负责在每次迭代中更新模型的权重以减少损失函数的值从而提高模型在图像分类任务上的准确率。 #e 减肥计划 优化器 假设你正在尝试减肥并设定了一个目标在三个月内减重8公斤。你的“优化器”就是你制定的减肥计划包括饮食控制和运动计划。 初始计划你开始时决定每天跑步30分钟每周五天同时减少碳水化合物的摄入。调整策略两周后你发现体重下降速度不如预期于是你决定增加运动量改为每天跑步45分钟并且加入两天的力量训练。反馈调整每周通过称重来评估减肥效果根据体重变化调整饮食和运动计划。 在这个过程中你不断地根据体重变化相当于“损失函数”调整你的减肥计划“优化器”以期达到减重的目标。这个过程类似于在机器学习中使用优化器调整模型参数以最小化损失函数。 #c 关联 相关概念 「优化器」影响的概念 学习率Learning Rate优化器通过学习率控制参数更新的步长。学习率太高可能导致训练不稳定太低则训练速度缓慢。动量Momentum动量帮助优化器在正确的方向上加速减少震荡从而更快地收敛。正则化Regularization虽然正则化通常定义在损失函数中但它也影响优化器的行为因为优化器需要考虑正则化项来更新参数以防止过拟合。学习率调度器Learning Rate Scheduler调度器根据预设策略调整学习率优化器需要根据这些调整来更新参数。这有助于在训练的不同阶段采取不同的学习策略。 影响「优化器」的概念 损失函数Loss Function优化器的目标是最小化损失函数。不同的损失函数可能会导致优化器的行为差异因为损失函数的形状直接影响梯度的计算。模型复杂度Model Complexity模型的复杂度决定了优化过程的难度。复杂模型可能有更多的局部最小值这对优化器的选择和配置提出了挑战。数据预处理Data Preprocessing数据的规模和分布会影响梯度的计算进而影响优化器的效率和策略。例如未经归一化的数据可能导致训练过程不稳定。参数初始化Parameter Initialization模型参数的初始值可以影响优化器的收敛速度和是否能够达到全局最小值。不同的初始化方法可能会导致训练过程中的不同表现。 #d 学习率调度器 学习率调度器Learning Rate Scheduler是一种在训练过程中动态调整学习率的策略。它根据预定的规则或实时的训练指标逐步调整学习率的大小以提高模型训练的效率和效果。学习率调度器通过在训练过程中动态调整学习率帮助模型更有效地学习提高训练的稳定性和效率最终获得更好的性能。 创造学习率调度器解决的问题 避免学习率过高如果学习率设置得过高可能会导致模型参数更新过猛从而使得「损失函数值」振荡甚至发散影响模型的稳定性和「收敛速度」。避免学习率过低在训练后期如果学习率过低模型参数的更新将非常缓慢这可能导致训练过程陷入「局部最小值」或者需要更长的时间来收敛。适应训练阶段不同的训练阶段可能需要不同的学习率。在初期可能需要较高的学习率以快速下降在接近最优解时则需要较低的学习率以细致调整避免过度震荡。 没有学习率调度器会导致的结果 训练效率低下固定的学习率可能无法同时满足训练初期和后期的需求导致训练效率不是最优甚至需要更多的训练周期才能达到相同的效果。模型性能不佳如果学习率始终过高或过低模型可能无法收敛到最佳状态导致最终的模型性能不佳。调参困难没有学习率调度器开发者可能需要手动多次尝试不同的学习率设置以找到最佳的学习率这个过程既耗时又低效。 #e StepLR调度器 学习率调度器 在PyTorch中学习率调度器用于根据预定策略动态调整学习率。以下是一个使用StepLR调度器的简单例子它在每过step_size个epoch后将学习率乘以gamma来减小学习率。 import torch import torch.optim as optim# 定义一个简单的模型 model torch.nn.Linear(10, 1) optimizer optim.SGD(model.parameters(), lr0.1)# 使用StepLR学习率调度器 scheduler torch.optim.lr_scheduler.StepLR(optimizer, step_size30, gamma0.1)for epoch in range(100):# 训练模型的代码...# 每个epoch结束后更新学习率scheduler.step()#e 马拉松训练 学习率调度器 想象你正在为一场马拉松比赛训练。在训练初期你可能会选择较高的强度相当于高学习率以快速提升你的体能和耐力。随着比赛日的临近接近最优解你可能会逐渐减少训练强度降低学习率进行更多的恢复性训练和技术细节的调整以避免受伤并确保在比赛日能有最佳表现。 这个过程类似于使用学习率调度器来动态调整训练强度确保在不同阶段采取最合适的训练策略以达到最佳的训练效果。 #c 关联 相关概念 学习率调度器的作用和受影响的概念 会影响的概念 模型收敛速度通过适时调整学习率学习率调度器可以加快模型的收敛速度特别是在训练初期通过使用较高的学习率。模型性能适当减小学习率可以帮助模型更细致地适应训练数据避免「过拟合」从而提高模型的泛化能力和最终性能。训练稳定性通过避免学习率过高导致的参数更新过猛学习率调度器有助于保持训练过程的稳定性减少损失函数的振荡。 影响学习率调度器的概念 优化器Optimizer学习率调度器直接作用于优化器调整其学习率参数。不同的优化器如SGD、Adam等可能对学习率的调整有不同的敏感度和效果。训练策略训练过程中的策略如批大小batch size、训练轮次epochs等会影响学习率调度器的设置。例如较大的批大小可能需要不同的学习率调整策略。模型复杂度和数据集模型的复杂度和数据集的特性也会影响学习率调度器的选择和配置。复杂模型或难以拟合的数据集可能需要更精细的学习率调整策略。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/85990.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

帝国系统怎样做网站地图优化师是一份怎样的工作

00. 目录 文章目录 00. 目录01. 串口简介02. 串口协议03. USART简介04. USART框图05. USART基本结构06. 数据帧07. 起始位侦测08. 数据采样09. 波特率发生器10. 附录 01. 串口简介 串口通讯(Serial Communication)是一种设备间非常常用的串行通讯方式,因为它简单便…

做的网站怎样更新收费小说网站怎么做

1、使用最新版本的 Node.js 仅仅是简单的升级 Node.js 版本就可以轻松地获得性能提升,因为几乎任何新版本的 Node.js 都会比老版本性能更好,为什么? Node.js 每个版本的性能提升主要来自于两个方面: V8 的版本更新;Nod…

建站教程pdf公司做网站让我们销售

在上家公司都是运维安装nginx,到新公司后代码开发完成部署测试服务器要求自己装nginx,研究了好久安装好之后,到正式上线还要自己安装,索性把安装步骤自己记载下来(好大一部分都是在网站找的)。一&#xff0…

云南网站建设哪家公司好东莞市门户网站建设怎么样

在日常的生活和工作当中不免会遇到一些无法进行复制但是又想要去将它摘录下来的文字。用手去进行输入的话及麻烦又费力,这个时候我们可以使用OCR技术来讲它们识别出来。而screenocr就是这样子的一款软件,还不是很了解screenocr都有哪些功能如何使用的用户…

营销型网站建设大概多少钱网络服务提供者不得为未满多少岁开展工作

面对日益增多的汽车数据安全事件,对于广大用户来说,有没有既廉价又安全的解决方案? 频发的汽车数据安全事件 随着汽车“新四化”大潮的来临,汽车用户从电动化、网联化、智能化、共享化中切实体验到了越来越多的便利,各…

弹性云主机做网站安徽省建设部干部网站

ISO27001审核主要针对组织的信息安全管理体系(ISMS)进行全面的审查,以确保其符合ISO/IEC 27001标准的要求。审核过程通常包括以下几个方面: 1. 组织环境:审核组织的信息安全管理体系是否能够在组织内部环境以及与外部供…

最流行的网站开发什么网站可以发布有偿做项目

构建数据库写程序避免不了使用日期和时间,对于数据库来说,有多种日期时间字段可供选择,如 timestamp 和 datetime 以及使用 int 来存储 unix timestamp。不仅新手,包括一些有经验的程序员还是比较迷茫,究竟我该用哪种类…

揭阳网站建设方案外包家在深圳坪山

DefaultReflectorFactory是反射工厂接口ReflectorFactory的默认实现,其主要是实现了对反射对象Reflector的创建和缓存。 有三个方法: // 判断是否开启缓存boolean isClassCacheEnabled();// 设置是否缓存void setClassCacheEnabled(boolean classCacheEn…

郑州网站制作哪家便宜seo网站内容更新

还记得被Java统治的时代吗?最近,这个格局已经被悄然打破,正是被来自曾经的小弟,新晋网红Python给硬生生拽下神坛。对此,Java曾表示强烈质疑,最近一份数据榜单悄悄来了!PLPY 8月榜单官宣&#xf…

做外贸的免费网站有哪些腾讯云服务器如何使用

这篇文章主要介绍了Python构建XML树结构的方法,结合实例形式分析了Python创建与打印xml数结构的实现步骤与相关操作技巧,需要的朋友可以参考下本文实例讲述了Python构建XML树结构的方法。分享给大家供大家参考,具体如下:1.构建XML元素#encodingutf-8from…

石家庄自己怎么做网站啊青州网站建设

连通分量 个数可以通过一次BFS或者DFS得到 割点和桥 可以枚举删除每一个点或者每一条边,判断连通分量个数是否增加 更好的方法 该算法是R.Tarjan发明的。对图深度优先搜索,定义DFS(u)为u在搜索树(以下简称为树)中被遍历到的次序号…

万网的网站建设好吗php网站开发优势

文章目录 一. 创建项目 引入依赖二. 设计数据库三. 编写数据库代码四. 创建实体类五. 封装数据库的增删查改六. 具体功能书写1. 博客列表页2. 博客详情页3. 博客登录页4. 检测登录状态5. 实现显示用户信息的功能6. 退出登录状态7. 发布博客 一. 创建项目 引入依赖 创建blog_sy…

网站开发就业培训阐述网络营销策略的内容

戳蓝字“CSDN云计算”关注我们哦!作者 | 刘丹出品 | CSDN云计算(ID:CSDNcloud)随着技术的飞速发展,云数据库在云计算的大背景下,作为一种新兴的共享基础架构方法逐渐发展起来,它极大地增强了数据…

个人网站建设设计persona响应式博客wordpress主题

HTML&#xff08;超文本标记语言&#xff09;是构建Web页面的标准语言&#xff0c;它包含了许多标签&#xff0c;用于定义和排列页面内容。在Web开发中&#xff0c;显示图像是非常常见的需求之一&#xff0c;为此HTML提供了<img>标签来插入图像。本文将详细介绍HTML图片标…

wordpress多站点插件网站设计方案怎么写

Django配置静态文件 目录 Django配置静态文件静态文件配置调用方法 一般我们将html文件都放在默认templates目录下 静态文件放在static目录下 static目录大致分为 js文件夹css文件夹img文件夹plugins文件夹 在浏览器输入url能够看到对应的静态资源&#xff0c;如果看不到说明…

北京 网站设计 地址通州页面设计总结

微软公司主办的Build 2016大会尚在进程中&#xff0c;但是两场重量级的主题演讲已经结束。下面列举了我个人非常关注的几个细节&#xff0c;介绍一些背景知识以饲读者。 Bash on Windows背后的历史和未来 微软和IBM二十多年前联合开发NT内核的时候就已经为接驳多种操作系统留下…

淮北市矿业工程建设公司网站中山谷歌推广

前段时间学习二叉树在处理删除操作的时候遇到一个头疼的问题&#xff1a;删除节点的时候明明已经置null了可树上该节点依旧存在&#xff0c;还必须执行node.father.left null;才可以删除node节点&#xff0c;寻找了一下原因发现还是因为对java内存管理理解不够深入。代码如下&…

wordpress获取站点链接wordpress 推荐文章

在日常开发中&#xff0c;我们需要关注 .NET 应用的资源使用情况&#xff0c;方便排查问题和扩容。通过 Ajax 请求获取统计信息&#xff0c;展示成图表&#xff0c;如下图&#xff1a;CLRStats 插件&#xff0c;一个统计 .NET 应用资源使用情况的插件&#xff0c;包含&#xff…

北京网站开发哪家专业文明网站建设情况

更大的成功&#xff0c;不是看我们用双腿走了多少路&#xff0c;而是要看我们总共行了多少路。一只萤火虫&#xff0c;靠自身的力量发出了光芒。夜晚&#xff0c;它仰头望天&#xff0c;对着月亮说&#xff1a;“我是靠自己而发光的&#xff0c;而你却是借助太阳的光芒。虽然你…

网上制作公章seo网络推广技巧

这是我自己早前听课时整理的java基础全套知识 使用于初学者 也可以适用于中级的程序员 我做成了chm文档的类型 你们可以下载 笔记是比较系统全面&#xff0c;可以抵得上市场上90%的学习资料。讨厌那些随便乱写的资料还有拿出来卖钱的人&#xff01;在这里我免费的分享出来供…