1_初识pytorch

news2024/9/19 11:05:17

之前完全没有了解过深度学习和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_dir
        self.label_dir=label_dir
        self.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_dir
        return 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=data
    print(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+1

writer.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 identifier
            scalar_value (float or string/blobname): Value to save
            global_step (int): Global step value to record
            walltime (float): Optional override default walltime (time.time())
              with seconds after epoch of event
            new_style (boolean): Whether to use new style (tensor field) or old
              style (simple_value field). New style could lead to faster data loading.
-----------------------------------------------------------------------------------
        以上这段话在介绍这个方法所包含的形参,tag其实就是图表的标题,global_step是横轴,      
scalar_value是纵轴。其他参数相对不重要
-----------------------------------------------------------------------------------
        Examples::

            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()

        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 shape
    H 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 Image


img_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 expected
    to have [..., H, W] shape, where ... means an arbitrary number of leading dimensions

    Args:
        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()

命令行运行:

结果成功:

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

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

相关文章

企业官网后台管理|网站后台管理系统PHP源码 开源

效果展示 提交反馈 获得更多开源资料 技术交流

在 Google Cloud 上大规模部署 dbt 项目

使用 Artifact Registry、Cloud Composer、GitHub Actions 和 dbt-airflow 容器化并运行 dbt 项目 欢迎来到雲闪世界。&#xff0c;大规模管理数据模型是使用dbt&#xff08;数据构建工具&#xff09;的数据团队面临的常见挑战。最初&#xff0c;团队通常从易于管理和部署的简单…

【日记】9 个发箍只有 2 个能压住头发……(513 字)

正文 今天下午实在有些受不了&#xff0c;从正大门外走了出去。抬头望着天空&#xff0c;望着那些悠然自在纯白无暇的云&#xff0c;竟然有些眼睛疼&#xff0c;刺激到想要流泪。 我在室内待得太久太久了。似乎很久没有在这种时间段出来过了。 下午快下班的时候&#xff0c;有个…

前端面试宝典【设计模式】【2】

欢迎来到《前端面试宝典》,这里是你通往互联网大厂的专属通道,专为渴望在前端领域大放异彩的你量身定制。通过本专栏的学习,无论是一线大厂还是初创企业的面试,都能自信满满地展现你的实力。 核心特色: 独家实战案例:每一期专栏都将深入剖析真实的前端面试案例,从基础知…

二进制部署k8s集群之cni网络插件flannel和calico工作原理

3、部署 CNI 网络组件 在 master01 节点上操作 上传flannel-v0.21.5.zip并解压 unzip flannel-v0.21.5.zipscp flannel*.tar 192.168.80.20:/opt/k8s/ scp flannel*.tar 192.168.80.30:/opt/k8s/ node两个节点操作 cd /opt/k8s/ docker load -i flannel.tar docker load -i …

Vue3开源Tree组件研发:节点勾选支持v-model

自研Tree组件有两个原因&#xff1a;1. 目前开源UI对Tree组件的用户API不太友好&#xff0c;2. 提升Vue3组件自研能力。 目前已实现的功能见上面思维导图。想象Tree组件的一个使用场景&#xff1a;后台管理员通过Tree组件来完成用户角色授权&#xff0c;同时支持对权限进行新增…

自动化测试概念篇

目录 一、自动化 1.1 自动化概念 1.2 自动化分类 1.3 自动化测试金字塔 二、web自动化测试 2.1 驱动 2.2 安装驱动管理 三、selenium 3.1 ⼀个简单的web自动化示例 3.2 selenium驱动浏览器的工作原理 一、自动化 1.1 自动化概念 在生活中&#xff1a; 自动洒水机&am…

cv::convexityDefects异常

cv::convexityDefects捕捉到cv::Exception OpenCV(4.8.0) C:\GHA-OCV-1\_work\ci-gha-workflow\ci-gha-workflow\opencv\modules\imgproc\src\convhull.cpp:360: error: (-5:Bad argument) The convex hull indices are not monotonous, which can be in the case when the inp…

拓扑排序(初中组)

有向无环图 定义 边有向&#xff0c;无环。英文名叫 Directed Acyclic Graph&#xff0c;缩写是 DAG。一些实际问题中的二元关系都可使用 DAG 来建模。 性质 能 拓扑排序 的图&#xff0c;一定是有向无环图&#xff1b; 如果有环&#xff0c;那么环上的任意两个节点在任意序…

特征构造和降维

特征构造&#xff08;Feature Engineering&#xff09; 特征构造是从现有数据中创建新的特征&#xff0c;以揭示数据中的隐藏关系&#xff0c;从而提高模型表现。这是数据预处理中一个关键步骤&#xff0c;可以显著提升模型的性能。 原理 通过特征构造&#xff0c;我们可以利…

“云计算环境下的等保测评要点分析“

随着云计算技术的广泛应用&#xff0c;企业越来越多地将业务迁移到云端&#xff0c;这不仅带来了灵活性和效率的提升&#xff0c;也对信息安全提出了新的挑战。等保测评作为我国信息安全等级保护制度的重要组成部分&#xff0c;其在云计算环境下的实施具有特殊性。本文将围绕“…

nginx 简单使用方法

nginx是用于 Web 服务、反向代理、内容缓存、负载均衡、媒体流传输等场景的开源软件。 主要作用有三个&#xff1a;1、反向代理 负载均衡动静分离 下载地址&#xff1a;nginx: download nginx执行命令及启动 //假设安装在E:\server\nginx-1.20.0目录下 //cmd命令进入安装文…

如何在 VitePress 中增加一个全局自定义组件

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storm…

【Python实战】轻松实现自动发送邮件

本文收录于 《一起学Python趣味编程》专栏,从零基础开始,分享一些Python编程知识,欢迎关注,谢谢! 文章目录 一、前言二、开发准备三、正式开始四、总结一、前言 本文介绍如何使用Python开源项目“PythonSendMail”,快速实现自动发送带Excel报表附件的邮件。只需要进行简…

操作系统篇--八股文学习第十天| 进程和线程之间有什么区别;并行和并发有什么区别;解释一下用户态和核心态,什么场景下,会发生内核态和用户态的切换?

进程和线程之间有什么区别 答&#xff1a; 进程是资源调度和分配的基本单位。 线程是程序执行的最小单位&#xff0c;线程是进程的子任务&#xff0c;是进程内的执行单元。 一个进程至少有一个线程&#xff0c;一个进程可以运行多个线程&#xff0c;这些线程共享同一块内存…

oracle rac-> rac配置adg避坑注意点

例如源主库db_name为aaa db_unique_name为aaa&#xff0c;实例名为aaa1,aaa2 ORACLE_SID为aaa1,aaa2 tnsnames.ora的服务名配置&#xff1a;aaa/dgaaa 则备库设置参考&#xff1a;db_name相同为aaa&#xff0c;db_unique_name不同为dgaaa&#xff0c;实例名为dgaaa1,dgaaa2…

【LeetCode】56. 区间合并

区间合并 题目描述&#xff1a; 以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间&#xff0c;并返回 一个不重叠的区间数组&#xff0c;该数组需恰好覆盖输入中的所有区间 。 示例 1&#xff1a; …

Oracle的一些脚本工具总结

一、操作系统性能 在linux 6 之后&#xff0c;建议使用dstat监控操作系统的各项指标。 使用方法&#xff1a; yum install dstat dstat -cdlrgmnpsy 二、we.sql https://download.csdn.net/download/zengxiangbo/89601165 详见文章关联附件。 Oracle脚本工具&#xff0c;查…

企业安全生产管理是否将成为新的朝阳产业?

这个答案我可以肯定的告诉你&#xff0c;是的&#xff01; 首先朝阳产业是啥&#xff1f;朝阳产业指的是具有广阔发展前景、高成长性和创新性的产业。 但你也有可能不信我说的这句。因为在大多数人看来&#xff0c;安全生产管理这块儿&#xff0c;企业的关注度不多&#xff0…

Oracle Database 确认表空间大小的方法

Oracle Database 确认表空间大小的方法 sql: WITH object_size AS (SELECT segment_name,owner,segment_type,tablespace_name,SUM(bytes) total_bytesFROM dba_segmentsGROUP BY segment_name, owner, segment_type, tablespace_name ), table_size AS (SELECT segment_name …