当前位置: 首页 > news >正文

1_初识pytorch

之前完全没有了解过深度学习和pytorch,但现在因为某些原因不得不学了。不得不感叹,深度学习是真的火啊。纯小白,有错的欢迎指正~

参考视频:PyTorch深度学习快速入门教程(绝对通俗易懂!)【小土堆】_哔哩哔哩_bilibili

不得不夸一句,这个老师讲的很仔细了,并且他排查错误和查找函数使用方法的方式让我受益匪浅。

顺带提一嘴,因为项目原因,我没有使用老师用的pycharm,用的是vscode。

教学视频中所使用的数据集可以去翻找评论区,里面就有。

下载过程我就不重复了,其实我也重下了好几次,一度崩溃了,一不小心c盘就爆了o(╥﹏╥)o。

---------------------------------------------------------------------------------------------------------------------------------

目录

加载数据初认识

Dataset

Dataloader

Tensorboard的使用

 Transform的使用

常见的Transform.py文件中所使用的类

ToPILImage类

Normalize类

Resize类

 Compose类

RandomCrop类

总结

torchvision中的数据集使用


---------------------------------------------------------------------------------------------------------------------------------

加载数据初认识

pytorch中带有加载处理数据的工具,以下就是其中两个很常用到的工具。

Dataset

作用:提供一种方式获取数据及label、告诉我们总共有多少数据。

也就是说,我们可以通过重写这个类,来构造我们自己的数据集,方便后面进行深度学习的训练操作。

引入方式如下:

#注意大小写,这里导入的是Dataset类,不是dataset文件
from torch.utils.data import Dataset

 跟着up主学习了一种新的掌握新工具的方式,使用python中自带的help函数可以快速查看用法。比如这个dataset。

在vscode中直接输入:

help(Dataset)

 运行之后会在终端出现如下内容:

class Dataset(typing.Generic)|  Dataset(*args, **kwds)||  An abstract class representing a :class:`Dataset`.|
'''
以下这段提到,所有继承Dataset的子类都需要重写__getitem__方法,可有选择的重写__len__方法
'''|  All datasets that represent a map from keys to data samples should subclass|  it. All subclasses should overwrite :meth:`__getitem__`, supporting fetching a|  data sample for a given key. Subclasses could also optionally overwrite|  :meth:`__len__`, which is expected to return the size of the dataset by many|  :class:`~torch.utils.data.Sampler` implementations and the default options|  of :class:`~torch.utils.data.DataLoader`.||  .. note::|    :class:`~torch.utils.data.DataLoader` by default constructs a index|    sampler that yields integral indices.  To make it work with a map-style|    dataset with non-integral indices/keys, a custom sampler must be provided.||  Method resolution order:|      Dataset|      typing.Generic|      builtins.object||  Methods defined here:||  __add__(self, other: 'Dataset[T_co]') -> 'ConcatDataset[T_co]'||  __getitem__(self, index) -> +T_co
-- More  --

 那么接下来,我们就来写一个类继承Dataset类:

from torch.utils.data import Dataset
from PIL import image
import os
class MyData(Dataset):#自定义构造方法,这里我们希望获取图片路径,把图片读入def __init__(self,root_dir,label_dir):self.root_dir=root_dirself.label_dir=label_dirself.path=os.path.join(root_dir,label_dir)self.img_path=os.listdir(self.path)#重写__getitem__方法,这个方法的重写可以帮助我们调取数据集中的某一个数据def __getitem__(self, index):img_name=self.img_path[index]img_item_path=os.path.join(self.root_dir,self.label_dir,img_name)img=image.open(img_item_path)label=self.label_dirreturn img,label#返回数据集长度(数据的个数)def __len__(self):return len(self.img_path)root_dir="d:\\Desktop\\hymenoptera_data\\train"
ants_label_dir="ants"
#实例化对象,传入构造参数后,这个对象就已经导入了我们想要的数据集
ants_dataset=MyData(root_dir,ants_label_dir)
#使用索引的方式,这里的[index]与上面__getitem__函数中的index相对应,可以单独调出其中某一张图片(数据)
img,label=ants_dataset[0]

Dataloader

作用:为后面的网络提供不同的数据形式

提示:这个可以放到这一篇结尾看。有用到后面的知识!

DataLoader 在内部使用 Dataset 对象来加载数据。它接收一个 Dataset 对象作为参数,并从该对象中按需加载数据。因此,Dataset 提供了数据的抽象表示和访问接口,而 DataLoader 则封装了批处理和数据加载的逻辑。

个人理解为,dataset之前有讲,其实是我们自定义一个类继承它,就可以实现完整的数据集的导入(它会告诉程序数据集在什么地方);而在训练模型过程中,我们使用dataloader来抽取其中的某一些数据。

这里照搬官方文档的定义,当然大家可以选择自己去官网看:

网址:torch.utils.data — PyTorch 2.4 documentation

torch.utils.data.DataLoader(dataset, batch_size=1, shuffle=None, sampler=None, batch_sampler=None, num_workers=0, collate_fn=None, pin_memory=False, drop_last=False, timeout=0, worker_init_fn=None, multiprocessing_context=None, generator=None, *, prefetch_factor=None, persistent_workers=False, pin_memory_device='')

 介绍一下这个类的常用参数,部分会以视频上老师说的打牌例子来介绍,假如说dataset就是一摞牌,那么dataloader就是我们抽到手里的牌:

  • dataset:我们的数据集
  • batch_size:指定每一次取数据集中的多少个数据,默认1(一次抽取多少张牌)
  • shuffle:指定数据集在每次抽取时是否重新排列,默认False(每次抽牌前是否洗牌)
  • num_workers:采用单进程还是多进程,默认为0
  • drop_last:当除不尽时,是否舍弃)(比如一共有100张牌,要求每次取三张,那么到最后有1张多余,这个参数用于设置是否把最后一张舍弃掉)

 上视频截图:

 

 当设置batch_size为4时,dataloader会从dataset中抽取四个数据出来,并将他们的img打包为imgs,把target打包为targets。

import torchvision
from torch.utils.data import DataLoader
tensor_trans=torchvision.transforms.ToTensor()
#注意这里传入的是一个列表
trans_compose=torchvision.transforms.Compose([tensor_trans])
#准备一个测试数据集
test_set=torchvision.datasets.CIFAR10(root="./dataset",train=False,download=True,transform=trans_compose)
test_loader=DataLoader(dataset=test_set,batch_size=4,shuffle=True,num_workers=0,drop_last=False)#测试集中的第一张图片及target
img,target=test_set[0]
print(img.shape)
print(target)for data in test_loader:imgs,targets=dataprint(imgs.shape)print(targets)

打印结果的部分截图:

imgs打印:torch,Size([4,3,32,32]):4代表4张图片;3代表3通道;32,32代表32*32大小的图片

下面的tensor代表targets

我们也可以使用tensorboard查看一下结果:

import torchvision
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
tensor_trans=torchvision.transforms.ToTensor()
#注意这里传入的是一个列表
trans_compose=torchvision.transforms.Compose([tensor_trans])
#准备一个测试数据集
test_set=torchvision.datasets.CIFAR10(root="./dataset",train=False,download=True,transform=trans_compose)
test_loader=DataLoader(dataset=test_set,batch_size=4,shuffle=True,num_workers=0,drop_last=False)#测试集中的第一张图片及target
# img,target=test_set[0]
# print(img.shape)
# print(target)writer=SummaryWriter("Logs")
step=0
for data in test_loader:imgs,targets=data# print(imgs.shape)# print(targets)writer.add_images("test_data",imgs,step)step=step+1writer.close()

 这里忘改batch_size了,老师视频上把这个改成了64,所以我这里仍是4张图片一组,可以看到结果是这样的:

Tensorboard的使用

TensorBoard 是 TensorFlow 的一个可视化工具,用于展示 TensorFlow 训练过程中的各种数据和指标。它提供了一个直观的界面,帮助开发者更好地理解、调试和优化他们的机器学习模型。

主要功能包括:

  1. 可视化模型图

    • TensorBoard 可以展示 TensorFlow 模型的计算图,这对于理解模型的结构和流程非常有帮助。你可以在 TensorBoard 中清晰地看到各个层之间的连接和数据流动。
  2. 训练指标

    • 在训练过程中,TensorBoard 可以实时地展示训练和验证集的损失值、准确率、学习率等指标的变化情况。这些指标可以帮助开发者监控模型的训练进度和性能表现。
  3. 直方图和分布图

    • TensorBoard 可以展示各个变量的直方图和分布图。这些图表能够帮助你了解权重、偏置和梯度等变量的分布情况,有助于调试和优化模型的训练过程。
  4. 嵌入式数据可视化

    • 如果你的模型包含嵌入层(Embedding),TensorBoard 可以将嵌入向量在高维空间中进行可视化,帮助你理解和分析这些向量的含义和关系。
  5. 计算图的操作和时间线

    • TensorBoard 还提供了一个操作面板,显示图中的操作(ops)和其用法。此外,时间线功能可以帮助你查看 TensorFlow 操作在时间上的分布和性能瓶颈。

使用 TensorBoard 需要将相关数据写入到 TensorFlow 的事件文件中,然后通过命令行启动 TensorBoard 服务,可以在浏览器中查看可视化界面。

但现在,tensorboard不仅可以在tensorflow中使用,也可以单独使用,它将会对我们理解模型的训练过程十分有帮助,因此来简单学习它的使用方法。

在py文件中导入tensorboard:

from torch.utils.tensorboard import SummaryWriter

按住ctrl鼠标单击SummaryWriter可以查看这个类的使用方法,其中提供了一个使用例子:

"""
Examples::from torch.utils.tensorboard import SummaryWriter# create a summary writer with automatically generated folder name.writer = SummaryWriter()# folder location: runs/May04_22-14-54_s-MacBook-Pro.local/# create a summary writer using the specified folder name.writer = SummaryWriter("my_experiment")# folder location: my_experiment# create a summary writer with comment appended.writer = SummaryWriter(comment="LR_0.1_BATCH_16")# folder location: runs/May04_22-14-54_s-MacBook-Pro.localLR_0.1_BATCH_16/"""

接下来,我们介绍两个常用的方法:

from torch.utils.tensorboard import SummaryWriter
#实例化对象
writer=SummaryWriter("Logs")
'''
将要介绍的方法:
writer.add_scalar()
writer.add_image()
'''
writer.close()

先来看add_scalar(),还是查看官方文档中给的:

"""Add scalar data to summary.Args:tag (str): Data identifierscalar_value (float or string/blobname): Value to saveglobal_step (int): Global step value to recordwalltime (float): Optional override default walltime (time.time())with seconds after epoch of eventnew_style (boolean): Whether to use new style (tensor field) or oldstyle (simple_value field). New style could lead to faster data loading.
-----------------------------------------------------------------------------------以上这段话在介绍这个方法所包含的形参,tag其实就是图表的标题,global_step是横轴,      
scalar_value是纵轴。其他参数相对不重要
-----------------------------------------------------------------------------------Examples::from torch.utils.tensorboard import SummaryWriterwriter = SummaryWriter()x = range(100)for i in x:writer.add_scalar('y=2x', i * 2, i)writer.close()Expected result:.. image:: _static/img/tensorboard/add_scalar.png:scale: 50 %"""

 如图所示:

就拿上述代码给的例子来实践一下:

from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter()
x = range(100)
for i in x:writer.add_scalar('y=2x', i * 2, i)
writer.close()

运行代码,可以看到右边文件夹中多了一个子文件夹(Logs):

接下来在终端找到Logs文件夹下,然后输入:


tensorboard --logdir=D:\vscodeProjects\Logs

 ↑ 记得是使用绝对地址,相对地址会出错的。如图:

打开链接就可以看到:

 Transform的使用

在 PyTorch 的 torchvision 库中,transform(转换)指的是一系列的图像预处理操作,用于在数据加载过程中对图像进行变换和处理。这些变换可以应用于数据集的图像,以便于在训练过程中增强数据、标准化数据或使数据更适合于模型训练。

导入:

from torchvision import transforms

通过transform.py文件中的ToTensor类,可以实现图像转换为张量的操作,方便后续数据的训练。

from torchvision import transforms
from PIL import Image
#导入图片
img_path="D:\\Desktop\\hymenoptera_data\\train\\ants\\0013035.jpg"
img=Image.open(img_path)#转换张量
tensor_trans=transforms.ToTensor()
tensor_img=tensor_trans(img)

 视频讲解截图:

这里有一个小的注意事项,ToTensor类接受两种类型的数据:PIL的image类型和numpy的ndarray,因此:

img_path="D:\\Desktop\\hymenoptera_data\\train\\ants\\0013035.jpg"'''可以使用Image读取图像'''
img=Image.open(img_path)'''也可以使用opencv读取图像,这个读入的类型就是ndarray'''
cv_img=cv2.imread(img_path)

常见的Transform.py文件中所使用的类

以上的讲解把图像的输入和输出给讲解了。总结一下,输入其实就是两种方式:一个是image格式,一个是ndarray格式,而输出则是使用Transform.py文件中的ToTendor类将上述两种格式转换成tensor(张量)输出,方便后续的操作。

ToPILImage类

作用:把tensor类型或ndarray类型转换回image类型

"""Convert a tensor or an ndarray to PIL Image - this does not scale values.This transform does not support torchscript.Converts a torch.*Tensor of shape C x H x W or a numpy ndarray of shapeH x W x C to a PIL Image while preserving the value range.Args:mode (`PIL.Image mode`_): color space and pixel depth of input data (optional).If ``mode`` is ``None`` (default) there are some assumptions made about the input data:- If the input has 4 channels, the ``mode`` is assumed to be ``RGBA``.- If the input has 3 channels, the ``mode`` is assumed to be ``RGB``.- If the input has 2 channels, the ``mode`` is assumed to be ``LA``.- If the input has 1 channel, the ``mode`` is determined by the data type (i.e ``int``, ``float``,``short``)... _PIL.Image mode: https://pillow.readthedocs.io/en/latest/handbook/concepts.html#concept-modes"""

Normalize类

transforms.Normalize 是 torchvision 中的一个转换函数,用于对张量进行标准化处理。它的作用主要是将输入张量的每个通道进行标准化,使得每个通道的均值和标准差符合指定的数值,从而使数据分布更加标准化和稳定。

具体来说,transforms.Normalize 的作用包括:

  1. 数据标准化

    • 对每个通道进行标准化处理,使得数据在经过标准化后,每个通道的均值为给定的 mean,标准差为给定的 std。
    • 这种标准化确保了数据分布的稳定性和一致性,有助于提升模型训练的效果和稳定性。
  2. 影响模型收敛速度

    • 标准化后的数据分布更加接近标准正态分布或者某个预期的分布,有助于优化算法(如梯度下降)更快地收敛到最优解。
  3. 防止数据范围过大

    • 在深度学习中,如果输入数据的范围过大,可能会导致激活函数输出非常大的值,从而使得梯度消失或爆炸。标准化可以帮助限制数据的范围,避免这些问题的发生。
"""Normalize a tensor image with mean and standard deviation.This transform does not support PIL Image.Given mean: ``(mean[1],...,mean[n])`` and std: ``(std[1],..,std[n])`` for ``n``channels, this transform will normalize each channel of the input``torch.*Tensor`` i.e.,``output[channel] = (input[channel] - mean[channel]) / std[channel]``.. note::This transform acts out of place, i.e., it does not mutate the input tensor.Args:mean (sequence): Sequence of means for each channel.std (sequence): Sequence of standard deviations for each channel.inplace(bool,optional): Bool to make this operation in-place."""

示例:

from torchvision import transforms
from PIL import Imageimg_path = "D:\\Desktop\\hymenoptera_data\\train\\ants\\0013035.jpg"
img = Image.open(img_path)# 将 PIL 图片转换为 PyTorch 的张量
tensor_trans = transforms.ToTensor()
tensor_img = tensor_trans(img)# 输出张量中第一个通道、第一个像素的像素值
print(tensor_img[0][0][0])# 定义标准化转换,均值和标准差都为 0.5
trans_norm = transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])# 对张量化后的图像进行标准化
img_norm = trans_norm(tensor_img)# 输出标准化后张量中第一个通道、第一个像素的像素值
print(img_norm[0][0][0])

Resize类

transform.Resize 类是 torchvision 中的一个转换类,用于调整图像的尺寸大小。其主要作用是将输入的 PIL 图像或者张量(Tensor)调整为指定的尺寸。

"""Resize the input image to the given size.If the image is torch Tensor, it is expectedto have [..., H, W] shape, where ... means an arbitrary number of leading dimensionsArgs:size (sequence or int): Desired output size. If size is a sequence like(h, w), output size will be matched to this. If size is an int,smaller edge of the image will be matched to this number.i.e, if height > width, then image will be rescaled to(size * height / width, size)."""
from torchvision import transforms
from PIL import Image
import cv2
#导入图片
img_path="D:\\Desktop\\hymenoptera_data\\train\\ants\\0013035.jpg"
img=Image.open(img_path)#转换张量
tensor_trans=transforms.ToTensor()
tensor_img=tensor_trans(img)trans_resize=transforms.Resize((512,512))
img_resize=trans_resize(img)
print(img_resize)'''
运行输出:
<PIL.Image.Image image mode=RGB size=512x512 at 0x272ACCEE7C0>'''

 Compose类

可以注意到,上述使用resize变换前后都是image类型,为了方便操作,transform提供了一个类专门用来自定义流水线工程。我们可以把任意多个transform组合起来封装成一个compose对象,然后就可以简化我们的步骤了。

作用:把多个transform操作结合在一起。

"""Composes several transforms together. This transform does not support torchscript.Please, see the note below.Args:transforms (list of ``Transform`` objects): list of transforms to compose.Example:>>> transforms.Compose([>>>     transforms.CenterCrop(10),>>>     transforms.PILToTensor(),>>>     transforms.ConvertImageDtype(torch.float),>>> ]).. note::In order to script the transformations, please use ``torch.nn.Sequential`` as below.>>> transforms = torch.nn.Sequential(>>>     transforms.CenterCrop(10),>>>     transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)),>>> )>>> scripted_transforms = torch.jit.script(transforms)Make sure to use only scriptable transformations, i.e. that work with ``torch.Tensor``, does not require`lambda` functions or ``PIL.Image``."""
from torchvision import transforms
from PIL import Image
import cv2
#导入图片
img_path="D:\\Desktop\\hymenoptera_data\\train\\ants\\0013035.jpg"
img=Image.open(img_path)#将resize和totensor操作流水线化
trans_resize=transforms.Resize((512,512))
tensor_trans=transforms.ToTensor()
#注意这里传入的是一个列表
trans_compose=transforms.Compose([trans_resize,tensor_trans])
#对图像只需要调用compose对象即可进行resize和totensor操作
img_resize_2=trans_compose(img)

RandomCrop类

主要作用是从输入的图像或张量中随机裁剪出指定大小的区域。

from torchvision import transforms
from PIL import Image
import cv2
#导入图片
img_path="D:\\Desktop\\hymenoptera_data\\train\\ants\\0013035.jpg"
img=Image.open(img_path)
transforms.RandomCrop
tensor_trans=transforms.ToTensor()
trans_random=transforms.RandomCrop(512)
#注意这里传入的是一个列表
trans_compose_1=transforms.Compose([trans_random,tensor_trans])
#对图像只需要调用compose对象即可进行resize和totensor操作
img_compose_1=trans_compose_1(img)
print(img_compose_1)

总结

1、关注每个工具的输入输出类型。

2、多看官方文档。

3、关注方法所需要的参数。

torchvision中的数据集使用

官方文档网址:

https://pytorch.org/docs/stable/index.html

import torchvision
train_set=torchvision.datasets.CIFAR10(root="./dataset",train=True,download=True)
test_set=torchvision.datasets.CIFAR10(root="./dataset",train=False,download=True)
print(test_set[0])

这里提一嘴,用相对路径下载后,我以为它会在当前py文件所在的文件夹的上级文件夹下新建dataset文件夹,但没想到它跑到了我之前建立的那个Logs文件夹下:

原因在于我的命令行仍停留在Logs文件夹里,记得执行cd..命令返回:

import torchvision
from torch.utils.tensorboard import SummaryWriter
dataset_transform=torchvision.transforms.Compose([torchvision.transforms.ToTensor()
])
train_set=torchvision.datasets.CIFAR10(root="./dataset",train=True,download=True,transform=dataset_transform)
test_set=torchvision.datasets.CIFAR10(root="./dataset",train=False,download=True,transform=dataset_transform)writer=SummaryWriter('p1')
for i in range(10):img,tarfet=test_set[i]writer.add_image("test_set",img,i)writer.close()

命令行运行:

结果成功:

相关文章:

1_初识pytorch

之前完全没有了解过深度学习和pytorch&#xff0c;但现在因为某些原因不得不学了。不得不感叹&#xff0c;深度学习是真的火啊。纯小白&#xff0c;有错的欢迎指正~ 参考视频&#xff1a;PyTorch深度学习快速入门教程&#xff08;绝对通俗易懂&#xff01;&#xff09;【小土堆…...

c++typeid()的使用

用处: typeid()函数主要用来获取对应类型或者变量的类型信息&#xff0c;其返回一个std::type_info的对象&#xff0c;这个对象中存放了对应类型的具体信息。 所以typeid()函数就是获取一个type_info的类型&#xff0c;然后可以通过此类型来获取到相应的类型信息。 type_info的…...

【面向就业的Linux基础】从入门到熟练,探索Linux的秘密(十四)-租云服务器及配环境、docker基本命令

主要介绍了租云服务器和docker配置、基本命令&#xff01;&#xff01;&#xff01; 文章目录 前言 一、云平台 二、租云服务器及安装docker 1.阿里云 2.安装docker 三、docker命令 将当前用户添加到docker用户组 镜像&#xff08;images&#xff09; 容器(container) 四、实战…...

实现一个全栈模糊搜索匹配的功能

提供一个全栈实现的方案&#xff0c;包括 Vue 3 前端、Express 后端和 MySQL 数据库的分类模糊搜索功能。让我们逐步来看&#xff1a; 1. 数据库设计 (MySQL) 首先&#xff0c;我们需要一个存储分类的表&#xff1a; CREATE TABLE categories (id INT AUTO_INCREMENT PRIMAR…...

智慧景区导览系统小程序开发

智慧景区导览系统小程序的开发是一个综合性的过程&#xff0c;旨在通过先进的技术手段提升游客的游览体验。以下是开发智慧景区导览系统小程序的主要步骤和关键点&#xff1a; 一、需求分析 市场调研&#xff1a;了解旅游市场的最新趋势和游客的实际需求&#xff0c;包括游客…...

HIVE调优方式及原因

3.HIVE 调优&#xff1a; 需要调优的几个方面&#xff1a; 1.HIVE语句执行不了 2.HIVE查询语句&#xff0c;在集群中执行时&#xff0c;数据无法落地 HIVE执行时&#xff0c;一开始语句检查没有问题&#xff0c;生成了多个JOB&#xff0c; …...

deploy local llm ragflow

CPU > 4 cores RAM > 16 GB Disk > 50 GB Docker > 24.0.0 & Docker Compose > v2.26.1 下载docker&#xff1a; 官方下载方式&#xff1a;https://docs.docker.com/desktop/install/ubuntu/ 其中 DEB package需要手动下载并传输到服务器 国内下载方式&…...

测桃花运(算姻缘)的网站系统源码

简介&#xff1a; 站长安装本源码后只要有人在线测算&#xff0c;就可以获得收入哦。是目前市面上最火的变现利器。 本版本无后台&#xff0c;无数据。本版本为开发的逗号联盟接口版本。直接对接逗号联盟&#xff0c;修改ID就可以直接运营收费赚钱。 安装环境&#xff1a;PH…...

电商平台优惠券

优惠券业务逻辑 优惠券的发放&#xff1a; 来源&#xff1a;优惠券可以由平台统一发放&#xff0c;也可以由商家自行发放。平台优惠券的优惠由平台承担&#xff0c;而店铺优惠券则由商家承担。类型&#xff1a;优惠券可以分为满减优惠券、无门槛优惠券等&#xff0c;根据使用限…...

内衣洗衣机多维度测评对比,了解觉飞、希亦、鲸立哪款内衣洗衣机更好

想要代替手洗内衣物&#xff0c;那么一台内衣专用的小型洗衣机就必不可少啦&#xff0c;不仅能够为我们节约更多的时间以及精力&#xff0c;还能大大提高内衣物的卫生&#xff0c;面对于市面上各种各样的小型内衣洗衣机&#xff0c;相信很多小伙伴都无从下手&#xff01; 为一…...

数据结构和算法入门

1.了解数据结构和算法 1.1 二分查找 二分查找&#xff08;Binary Search&#xff09;是一种在有序数组中查找特定元素的搜索算法。它的基本思想是将数组分成两半&#xff0c;然后比较目标值与中间元素的大小关系&#xff0c;从而确定应该在左半部分还是右半部分继续查找。这个…...

基于OpenCV C++的网络实时视频流传输——Windows下使用TCP/IP编程原理

1.TCP/IP编程 1.1 概念 IP 是英文 Internet Protocol &#xff08;网络之间互连的协议&#xff09;的缩写&#xff0c;也就是为计算机网络相互连接进行通信而设计的协议。任一系统&#xff0c;只要遵守 IP协议就可以与因特网互连互通。 所谓IP地址就是给每个遵循tcp/ip协议连…...

(BS ISO 11898-1:2015)CAN_FD 总线协议详解6- PL(物理层)规定3

目录 6.4 AUI 规范 6.4.1 一般规定 6.4.2 PCS 到 PMA 消息 6.4.2.1 输出消息 6.4.2.2 Bus_off 消息 6.4.2.3 Bus_off 释放消息 6.4.2.4 FD_Transmit 消息 6.4.2.5 FD_Receive 消息 6.4.3 PMA 到 PCS 消息 6.4.3.1 输入消息 如果有不懂的问题可在评论区点赞后留言&…...

docker环境下php安装扩展步骤 以mysqli为例

docker环境下php安装扩展步骤 以mysqli为例 1.0 前言2.0 php 扩展安装原理3.0 docker 环境下 php 扩展安装3.1 docker php 容器扩展安装路径及原理3.2 docker php 扩展脚本安装过程 同步发布在个人笔记[docker环境下php安装扩展步骤 以mysqli为例]( https://blog.lichenrobo.co…...

医院综合绩效核算系统,绩效核算系统源码,采用springboot+avue+MySQL技术开发,可适应医院多种绩效核算方式。

一、系统概述 作为医院用综合绩效核算系统&#xff0c;系统需要和his系统进行对接&#xff0c;按照设定周期&#xff0c;从his系统获取医院科室和医生、护士、其他人员工作量&#xff0c;对没有录入信息化系统的工作量&#xff0c;绩效考核系统设有手工录入功能&#xff08;可…...

ROOM数据快速入门

ROOM数据库快速入门 文章目录 ROOM数据库快速入门第一章 准备工作第01节 引入库第02节 布局文件第03节 activity类第04节 效果图 第二章 数据类第01节 实体类&#xff08;表&#xff09;第02节 数据访问类&#xff08;DAO&#xff09;第03节 数据Service层第04节 RoomDataBase …...

刷新,前面接口的返回值没有到,第二个接口已经请求完了,导致第二个接口返回数据错误

刷新&#xff0c;前面接口的返回值没有到&#xff0c;&#xff08;前端&#xff09;第二个接口已经请求完了&#xff08;入参没有拿前面那个接口返回的数据&#xff09;&#xff0c;导致第二个接口返回数据错误...

pdcj设计

为了实现这些功能需求&#xff0c;我们需要设计多个数据库表来存储相关的数据&#xff0c;并编写相应的Java代码来处理业务逻辑。下面是各个功能需求对应的MySQL表结构以及部分Java代码示例。 商品设置管理 商品分类管理 商品分类表 (product_categories)CREATE TABLE produ…...

【数据结构】哈希表的模拟实现

文章目录 1. 哈希的概念2. 哈希表与哈希函数2.1 哈希冲突2.2 哈希函数2.3 哈希冲突的解决2.3.1 闭散列&#xff08;线性探测&#xff09;2.3.2 闭散列的实现2.3.3 开散列(哈希桶)2.3.4 开散列的实现 2.4 开散列与闭散列比较 1. 哈希的概念 在我们之前所接触到的所有的数据结构…...

面试经典算法150题系列-数组/字符串操作之多数元素

序言&#xff1a;今天是第五题啦&#xff0c;前面四题的解法还清楚吗&#xff1f;可以到面试算法题系列150题专栏 进行复习呀。 温故而知新&#xff0c;可以为师矣&#xff01;加油&#xff0c;未来的技术大牛们。 多数元素 给定一个大小为 n 的数组 nums &#xff0c;返回其…...

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

Go 语言接口详解

Go 语言接口详解 核心概念 接口定义 在 Go 语言中&#xff0c;接口是一种抽象类型&#xff0c;它定义了一组方法的集合&#xff1a; // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的&#xff1a; // 矩形结构体…...

ETLCloud可能遇到的问题有哪些?常见坑位解析

数据集成平台ETLCloud&#xff0c;主要用于支持数据的抽取&#xff08;Extract&#xff09;、转换&#xff08;Transform&#xff09;和加载&#xff08;Load&#xff09;过程。提供了一个简洁直观的界面&#xff0c;以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

Spring AI 入门:Java 开发者的生成式 AI 实践之路

一、Spring AI 简介 在人工智能技术快速迭代的今天&#xff0c;Spring AI 作为 Spring 生态系统的新生力量&#xff0c;正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务&#xff08;如 OpenAI、Anthropic&#xff09;的无缝对接&…...

Java面试专项一-准备篇

一、企业简历筛选规则 一般企业的简历筛选流程&#xff1a;首先由HR先筛选一部分简历后&#xff0c;在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如&#xff1a;Boss直聘&#xff08;招聘方平台&#xff09; 直接按照条件进行筛选 例如&#xff1a…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中&#xff0c;新增了一个本地验证码接口 /code&#xff0c;使用函数式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...