Colab/PyTorch - 002 Pre Trained Models for Image Classification

news2024/11/16 22:01:08

Colab/PyTorch - 002 Pre Trained Models for Image Classification

  • 1. 源由
  • 2. 图像分类的预训练模型
  • 3. 示例 - AlexNet/ResNet101
    • 3.1 模型推断过程
    • 3.2 使用TorchVision加载预训练网络
    • 3.3 使用AlexNet进行图像分类
      • 3.3.1 Step1:加载预训练模型
      • 3.3.2 Step2:指定图像转换
      • 3.3.3 Step3:切换至eval模式
      • 3.3.4 Step4:定义图像处理函数
      • 3.3.5 Step5 评估推理结果
        • 图像1 - 拉布拉多犬(42.5%)
        • 图像2 - 草莓(99.9%)
        • 图像3 - 汽车(33.9%)
        • 图像4 - 穿越机(识别错误!!!)
    • 3.4 ResNet用于图像分类
      • 3.4.1 定义图像处理函数
      • 3.4.2 评估推理结果
        • 图像1 - 拉布拉多犬(48.8%)
        • 图像2 - 草莓(99.7%)
        • 图像3 - 汽车(86.7%)
        • 图像4 - 穿越机(识别错误!!!)
  • 4. 分析
    • 4.1 模型准确性比较
    • 4.2 推断时间比较
    • 4.3 模型大小比较
    • 4.4 总体比较
  • 5. 总结
  • 6. 参考资料

1. 源由

这篇文章中,我们将深入探讨在TorchVision模块中使用的预训练网络的一些实际示例,图像分类的预训练模型。

Torchvision包含流行的数据集、模型架构以及常用的图像转换功能,用于计算机视觉。

基本上,如果对计算机视觉感兴趣并且正在使用PyTorch,Torchvision将会帮助很大!

2. 图像分类的预训练模型

预训练模型是在诸如ImageNet之类的大型基准数据集上训练的神经网络模型。深度学习社区从这些开源模型中受益匪浅。此外,预训练模型是计算机视觉研究迅速进步的主要因素。其他研究人员和实践者可以使用这些最先进的模型,而不是从头开始重新发明一切。

下面是随着时间推移,最先进模型如何改进的大致时间轴,列出了Torchvision包中存在的那些模型。
在这里插入图片描述在深入讨论如何使用预训练模型进行图像分类之前,先看看有哪些可用的预训练模型。在这里,将讨论AlexNet和ResNet101这两个主要示例。这两个网络都是在ImageNet数据集上进行训练的。

ImageNet数据集由斯坦福大学维护,拥有超过1400万张图像。它被广泛用于各种图像相关的深度学习项目。这些图像属于各种不同的类别或标签。虽然我们可以互换使用这两个术语,但将坚持使用“类别”。像AlexNet和ResNet101这样的预训练模型的目的是接受一张图像作为输入,并预测其所属的类别。

这里的“预训练”一词意味着深度学习架构,比如AlexNet和ResNet101,已经在某个(庞大的)数据集上进行了训练,并携带了相应的权重和偏差。

3. 示例 - AlexNet/ResNet101

架构与权重和偏差之间的区别应该非常清楚,因为正如将要看到的那样,TorchVision既有架构,也有预训练模型。

3.1 模型推断过程

由于我们将专注于如何使用预训练模型来预测输入的类别(标签),让我们也讨论涉及其中的过程。这个过程被称为模型推断。整个过程包括以下主要步骤:

  1. 读取输入图像
  2. 对图像执行转换。例如 - 调整大小、中心裁剪、归一化等。
  3. 前向传播:使用预训练权重来找出输出向量。输出向量中的每个元素描述了模型预测输入图像属于特定类别的置信度。
  4. 根据获得的分数(第3步中提到的输出向量的元素),显示预测结果。

3.2 使用TorchVision加载预训练网络

现在已经掌握了模型推断的知识,并知道了预训练模型的含义,让我们看看如何借助TorchVision模块来使用它们。

首先,让我们使用下面给出的命令安装TorchVision模块。

$ pip install torchvision

接下来,让我们从torchvision模块中导入models,并查看我们可以使用的不同模型和架构。

from torchvision import models
import torch
 
dir(models)
['AlexNet',
 'AlexNet_Weights',
 'ConvNeXt',
 'ConvNeXt_Base_Weights',
 'ConvNeXt_Large_Weights',
 'ConvNeXt_Small_Weights',
 'ConvNeXt_Tiny_Weights',
 'DenseNet',
 'DenseNet121_Weights',
 'DenseNet161_Weights',
 'DenseNet169_Weights',
 'DenseNet201_Weights',
 'EfficientNet',
 'EfficientNet_B0_Weights',
 'EfficientNet_B1_Weights',
 'EfficientNet_B2_Weights',
 'EfficientNet_B3_Weights',
 'EfficientNet_B4_Weights',
 'EfficientNet_B5_Weights',
 'EfficientNet_B6_Weights',
 'EfficientNet_B7_Weights',
 'EfficientNet_V2_L_Weights',
 'EfficientNet_V2_M_Weights',
 'EfficientNet_V2_S_Weights',
 'GoogLeNet',
 'GoogLeNetOutputs',
 'GoogLeNet_Weights',
 'Inception3',
 'InceptionOutputs',
 'Inception_V3_Weights',
 'MNASNet',
 'MNASNet0_5_Weights',
 'MNASNet0_75_Weights',
 'MNASNet1_0_Weights',
 'MNASNet1_3_Weights',
 'MaxVit',
 'MaxVit_T_Weights',
 'MobileNetV2',
 'MobileNetV3',
 'MobileNet_V2_Weights',
 'MobileNet_V3_Large_Weights',
 'MobileNet_V3_Small_Weights',
 'RegNet',
 'RegNet_X_16GF_Weights',
 'RegNet_X_1_6GF_Weights',
 'RegNet_X_32GF_Weights',
 'RegNet_X_3_2GF_Weights',
 'RegNet_X_400MF_Weights',
 'RegNet_X_800MF_Weights',
 'RegNet_X_8GF_Weights',
 'RegNet_Y_128GF_Weights',
 'RegNet_Y_16GF_Weights',
 'RegNet_Y_1_6GF_Weights',
 'RegNet_Y_32GF_Weights',
 'RegNet_Y_3_2GF_Weights',
 'RegNet_Y_400MF_Weights',
 'RegNet_Y_800MF_Weights',
 'RegNet_Y_8GF_Weights',
 'ResNeXt101_32X8D_Weights',
 'ResNeXt101_64X4D_Weights',
 'ResNeXt50_32X4D_Weights',
 'ResNet',
 'ResNet101_Weights',
 'ResNet152_Weights',
 'ResNet18_Weights',
 'ResNet34_Weights',
 'ResNet50_Weights',
 'ShuffleNetV2',
 'ShuffleNet_V2_X0_5_Weights',
 'ShuffleNet_V2_X1_0_Weights',
 'ShuffleNet_V2_X1_5_Weights',
 'ShuffleNet_V2_X2_0_Weights',
 'SqueezeNet',
 'SqueezeNet1_0_Weights',
 'SqueezeNet1_1_Weights',
 'SwinTransformer',
 'Swin_B_Weights',
 'Swin_S_Weights',
 'Swin_T_Weights',
 'Swin_V2_B_Weights',
 'Swin_V2_S_Weights',
 'Swin_V2_T_Weights',
 'VGG',
 'VGG11_BN_Weights',
 'VGG11_Weights',
 'VGG13_BN_Weights',
 'VGG13_Weights',
 'VGG16_BN_Weights',
 'VGG16_Weights',
 'VGG19_BN_Weights',
 'VGG19_Weights',
 'ViT_B_16_Weights',
 'ViT_B_32_Weights',
 'ViT_H_14_Weights',
 'ViT_L_16_Weights',
 'ViT_L_32_Weights',
 'VisionTransformer',
 'Weights',
 'WeightsEnum',
 'Wide_ResNet101_2_Weights',
 'Wide_ResNet50_2_Weights',
 '_GoogLeNetOutputs',
 '_InceptionOutputs',
 '__builtins__',
 '__cached__',
 '__doc__',
 '__file__',
 '__loader__',
 '__name__',
 '__package__',
 '__path__',
 '__spec__',
 '_api',
 '_meta',
 '_utils',
 'alexnet',
 'convnext',
 'convnext_base',
 'convnext_large',
 'convnext_small',
 'convnext_tiny',
 'densenet',
 'densenet121',
 'densenet161',
 'densenet169',
 'densenet201',
 'detection',
 'efficientnet',
 'efficientnet_b0',
 'efficientnet_b1',
 'efficientnet_b2',
 'efficientnet_b3',
 'efficientnet_b4',
 'efficientnet_b5',
 'efficientnet_b6',
 'efficientnet_b7',
 'efficientnet_v2_l',
 'efficientnet_v2_m',
 'efficientnet_v2_s',
 'get_model',
 'get_model_builder',
 'get_model_weights',
 'get_weight',
 'googlenet',
 'inception',
 'inception_v3',
 'list_models',
 'maxvit',
 'maxvit_t',
 'mnasnet',
 'mnasnet0_5',
 'mnasnet0_75',
 'mnasnet1_0',
 'mnasnet1_3',
 'mobilenet',
 'mobilenet_v2',
 'mobilenet_v3_large',
 'mobilenet_v3_small',
 'mobilenetv2',
 'mobilenetv3',
 'optical_flow',
 'quantization',
 'regnet',
 'regnet_x_16gf',
 'regnet_x_1_6gf',
 'regnet_x_32gf',
 'regnet_x_3_2gf',
 'regnet_x_400mf',
 'regnet_x_800mf',
 'regnet_x_8gf',
 'regnet_y_128gf',
 'regnet_y_16gf',
 'regnet_y_1_6gf',
 'regnet_y_32gf',
 'regnet_y_3_2gf',
 'regnet_y_400mf',
 'regnet_y_800mf',
 'regnet_y_8gf',
 'resnet',
 'resnet101',
 'resnet152',
 'resnet18',
 'resnet34',
 'resnet50',
 'resnext101_32x8d',
 'resnext101_64x4d',
 'resnext50_32x4d',
 'segmentation',
 'shufflenet_v2_x0_5',
 'shufflenet_v2_x1_0',
 'shufflenet_v2_x1_5',
 'shufflenet_v2_x2_0',
 'shufflenetv2',
 'squeezenet',
 'squeezenet1_0',
 'squeezenet1_1',
 'swin_b',
 'swin_s',
 'swin_t',
 'swin_transformer',
 'swin_v2_b',
 'swin_v2_s',
 'swin_v2_t',
 'vgg',
 'vgg11',
 'vgg11_bn',
 'vgg13',
 'vgg13_bn',
 'vgg16',
 'vgg16_bn',
 'vgg19',
 'vgg19_bn',
 'video',
 'vision_transformer',
 'vit_b_16',
 'vit_b_32',
 'vit_h_14',
 'vit_l_16',
 'vit_l_32',
 'wide_resnet101_2',
 'wide_resnet50_2']

注意,其中一个条目名为AlexNet,另一个名为alexnet。大写的名称指的是Python类(AlexNet),而alexnet是一个方便的函数,它返回从AlexNet类实例化的模型。这些便利函数也可能具有不同的参数集。例如,densenet121、densenet161、densenet169、densenet201,都是DenseNet类的实例,但具有不同数量的层 - 分别为121、161、169和201层。

3.3 使用AlexNet进行图像分类

让我们首先从AlexNet开始。它是图像识别领域的早期突破性网络之一。

在这里插入图片描述

3.3.1 Step1:加载预训练模型

在第一步中,创建网络的一个实例,将传递一个参数,以便函数可以加载模型的权重。

alexnet = models.alexnet(pretrained=True)
 
# You will see a similar output as below
# Downloading: "https://download.pytorch.org/models/alexnet-owt- 4df8aa71.pth" to /home/hp/.cache/torch/checkpoints/alexnet-owt-4df8aa71.pth

请注意,通常PyTorch模型的扩展名为.pt或.pth。

一旦权重已经下载,我们可以继续进行其他步骤。我们也可以查看网络架构的一些细节,如下所示。

print(alexnet)

不用担心输出过多。这基本上说明了AlexNet架构中的各种操作和层。

AlexNet(
  (features): Sequential(
    (0): Conv2d(3, 64, kernel_size=(11, 11), stride=(4, 4), padding=(2, 2))
    (1): ReLU(inplace=True)
    (2): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
    (3): Conv2d(64, 192, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
    (4): ReLU(inplace=True)
    (5): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
    (6): Conv2d(192, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (7): ReLU(inplace=True)
    (8): Conv2d(384, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (9): ReLU(inplace=True)
    (10): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (11): ReLU(inplace=True)
    (12): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
  )
  (avgpool): AdaptiveAvgPool2d(output_size=(6, 6))
  (classifier): Sequential(
    (0): Dropout(p=0.5, inplace=False)
    (1): Linear(in_features=9216, out_features=4096, bias=True)
    (2): ReLU(inplace=True)
    (3): Dropout(p=0.5, inplace=False)
    (4): Linear(in_features=4096, out_features=4096, bias=True)
    (5): ReLU(inplace=True)
    (6): Linear(in_features=4096, out_features=1000, bias=True)
  )
)

3.3.2 Step2:指定图像转换

一旦拥有了模型,下一步是转换输入图像,使其具有正确的形状和其他特征,如均值和标准差。这些值应与训练模型时使用的值相似。这可以确保网络会产生有意义的答案。

可以使用TochVision模块中的变换来预处理输入图像。在这种情况下,我们可以为AlexNet和ResNet都使用以下变换。

# Specify image transformations
from torchvision import transforms

transform = transforms.Compose([            #[1]
 transforms.Resize(256),                    #[2]
 transforms.CenterCrop(224),                #[3]
 transforms.ToTensor(),                     #[4]
 transforms.Normalize(                      #[5]
 mean=[0.485, 0.456, 0.406],                #[6]
 std=[0.229, 0.224, 0.225]                  #[7]
 )])

# Line [1]: Here we are defining a variable transform which is a combination of all the image transformations to be carried out on the input image.

# Line [2]: Resize the image to 256×256 pixels.

# Line [3]: Crop the image to 224×224 pixels about the center.

# Line [4]: Convert the image to PyTorch Tensor data type.

# Line [5-7]: Normalize the image by setting its mean and standard deviation to the specified values.

3.3.3 Step3:切换至eval模式

使用预训练模型来看看模型认为图像是什么了。

首先,我们需要将我们的模型置于评估模式。

alexnet.eval()

3.3.4 Step4:定义图像处理函数

  1. 加载输入图像并进行预处理作为入参img
  2. 加载输入图像并执行上述指定的图像转换
  3. 对图像进行推理
  4. 读取并存储所有1000个标签的列表
  5. 找到输出向量out中最大分数出现的索引,使用这个索引来确定预测结果
  6. 将模型预测的前5个候选类别及概率均打印出来进行评估
def process_images_by_AlexNet(img):
    img_t = transform(img)
    batch_t = torch.unsqueeze(img_t, 0)

    # Carry out inference on image1
    out = alexnet(batch_t)
    print(out.shape)

    # Load labels
    with open('imagenet_classes.txt') as f:
        classes = [line.strip() for line in f.readlines()]

    _, index = torch.max(out, 1)
    percentage = torch.nn.functional.softmax(out, dim=1)[0] * 100
    print(classes[index[0]], percentage[index[0]].item())

    # Forth, print the top 5 classes predicted by the model
    _, indices = torch.sort(out, descending=True)
    print([(classes[idx], percentage[idx].item()) for idx in indices[0][:5]])

3.3.5 Step5 评估推理结果

图像1 - 拉布拉多犬(42.5%)
# Import Pillow
from PIL import Image
img = Image.open("dog.jpg")
process_images_by_AlexNet(img)
torch.Size([1, 1000])
Labrador retriever 42.46743392944336
[('Labrador retriever', 42.46743392944336), ('golden retriever', 16.608755111694336), ('Saluki, gazelle hound', 15.473681449890137), ('whippet', 2.7881901264190674), ('Ibizan hound, Ibizan Podenco', 2.3616936206817627)]

在这里插入图片描述

图像2 - 草莓(99.9%)
# Import Pillow
from PIL import Image
img = Image.open("strawberries.jpg")
process_images_by_AlexNet(img)
torch.Size([1, 1000])
strawberry 99.99411010742188
[('strawberry', 99.99411010742188), ('banana', 0.0008383101085200906), ('custard apple', 0.0008333695586770773), ('orange', 0.0007468032999895513), ('lemon', 0.0005674762651324272)]

在这里插入图片描述

图像3 - 汽车(33.9%)
# Import Pillow
from PIL import Image
img = Image.open("automotive.jpg")
process_images_by_AlexNet(img)
torch.Size([1, 1000])
cab, hack, taxi, taxicab 33.94831466674805
[('cab, hack, taxi, taxicab', 33.94831466674805), ('sports car, sport car', 15.606391906738281), ('racer, race car, racing car', 10.1033296585083), ('beach wagon, station wagon, wagon, estate car, beach waggon, station waggon, waggon', 7.658527851104736), ('convertible', 6.8374223709106445)]

在这里插入图片描述

图像4 - 穿越机(识别错误!!!)

尽然识别成了割草机,哈哈!!!估计训练集里面压根没有这个类别,不过确实曾经有“割草”功能!

# Import Pillow
from PIL import Image
img = Image.open("aos5.jpg")
process_images_by_AlexNet(img)
torch.Size([1, 1000])
lawn mower, mower 36.8341064453125
[('lawn mower, mower', 36.8341064453125), ('harvester, reaper', 22.15677833557129), ('half track', 6.54979944229126), ('thresher, thrasher, threshing machine', 4.788162708282471), ('forklift', 3.2068734169006348)]

在这里插入图片描述

3.4 ResNet用于图像分类

由于AlexNet和ResNet都是在相同的ImageNet数据集上训练的,我们可以对这两个模型使用相同的方法。 ResNet101是一个拥有 101 层卷积神经网络。ResNet101 在训练过程中调整了约 4450 万个参数。这参数太庞大了!

# First, load the model
resnet = models.resnet101(pretrained=True)
 
# Second, put the network in eval mode
resnet.eval()

3.4.1 定义图像处理函数

def process_images_by_resnet(img):
    img_t = transform(img)
    batch_t = torch.unsqueeze(img_t, 0)

    # Carry out inference on image1
    out = resnet(batch_t)
    print(out.shape)

    # Load labels
    with open('imagenet_classes.txt') as f:
        classes = [line.strip() for line in f.readlines()]

    _, index = torch.max(out, 1)
    percentage = torch.nn.functional.softmax(out, dim=1)[0] * 100
    print(classes[index[0]], percentage[index[0]].item())

    # Forth, print the top 5 classes predicted by the model
    _, indices = torch.sort(out, descending=True)
    print([(classes[idx], percentage[idx].item()) for idx in indices[0][:5]])

3.4.2 评估推理结果

# We will evaluate dog, strawberries, automotive, and download function is disabled here.
from PIL import Image
img1 = Image.open("dog.jpg")
img2 = Image.open("strawberries.jpg")
img3 = Image.open("automotive.jpg")
img4 = Image.open("aos5.jpg")
图像1 - 拉布拉多犬(48.8%)
process_images_by_resnet(img1)
torch.Size([1, 1000])
Labrador retriever 48.86875915527344
[('Labrador retriever', 48.86875915527344), ('dingo, warrigal, warragal, Canis dingo', 8.17887020111084), ('golden retriever', 6.944704055786133), ('Eskimo dog, husky', 3.563750982284546), ('bull mastiff', 3.0799338817596436)]
图像2 - 草莓(99.7%)
process_images_by_resnet(img2)
torch.Size([1, 1000])
strawberry 99.76702117919922
[('strawberry', 99.76702117919922), ('trifle', 0.02754645235836506), ('pineapple, ananas', 0.013453328981995583), ('strainer', 0.012202989310026169), ('thimble', 0.012185103259980679)]
图像3 - 汽车(86.7%)
process_images_by_resnet(img3)
torch.Size([1, 1000])
sports car, sport car 86.77729797363281
[('sports car, sport car', 86.77729797363281), ('convertible', 8.948866844177246), ('racer, race car, racing car', 1.7048405408859253), ('cab, hack, taxi, taxicab', 1.2756531238555908), ('grille, radiator grille', 0.5685423016548157)]
图像4 - 穿越机(识别错误!!!)
process_images_by_resnet(img4)
torch.Size([1, 1000])
radio, wireless 29.244718551635742
[('radio, wireless', 29.244718551635742), ("carpenter's kit, tool kit", 18.641035079956055), ('power drill', 18.24420738220215), ('joystick', 12.940756797790527), ('mousetrap', 3.2342422008514404)]

4. 分析

到目前为止,已经讨论了如何使用预训练模型进行图像分类,但尚未回答的一个问题是,如何决定为特定任务选择哪个模型。

根据以下标准比较预训练模型:

  1. Top-1 错误:如果由置信度最高的模型预测的类与真实类不同,则会发生 Top-1 错误。
  2. Top-5 错误:如果真实类不在模型预测的前 5 个类中(按置信度排序),则会发生 Top-5 错误。
  3. CPU 推断时间:推断时间是模型推断步骤所需的时间。
  4. GPU 推断时间:GPU的特殊性,其计算时间应该小于CPU时间
  5. 模型大小:此处的大小指的是由 PyTorch 提供的预训练模型的 .pth 文件所占据的物理空间。

一个好的模型将具有较低的 Top-1 错误、较低的 Top-5 错误、较低的 CPU 和 GPU 推断时间以及较低的模型大小。

所有实验都在相同的输入图像上进行了多次,以便分析特定模型所有结果的平均值。实验在 Google Colab 上进行。

4.1 模型准确性比较

Top-1错误是指顶级预测类别与真实情况不同。由于问题相当困难,因此还有另一个错误度量称为Top-5错误。如果前5个预测类别都不正确,则将预测分类为错误。
在这里插入图片描述从图表可以看出,这两种错误都呈现出类似的趋势。AlexNet是基于深度学习的第一次尝试,自那时以来,错误率有所改善。

4.2 推断时间比较

接下来,将根据模型推断所需的时间进行比较。每个模型都被提供了相同的图像多次,对所有迭代的推断时间进行了平均。类似的过程在 Google Colab 上针对 CPU 和 GPU 都进行了。尽管在顺序上存在一些变化,但我们可以看到 SqueezeNet、ShuffleNet 和 ResNet-18 的推断时间非常低;GPU都比CPU的耗时低。
在这里插入图片描述

在这里插入图片描述

4.3 模型大小比较

很多时候,当我们在安卓或iOS设备上使用深度学习模型时,模型大小成为决定因素,有时甚至比准确性更重要。SqueezeNet 的模型大小最小(5 MB),其次是ShuffleNet V2(6 MB)和MobileNet V2(14 MB)。显而易见的是,这些模型在利用深度学习的移动应用程序中更受青睐的原因。

在这里插入图片描述

4.4 总体比较

我们讨论了基于特定标准哪个模型表现更好。我们可以将所有这些重要细节压缩在一个气泡图中,然后根据我们的需求决定选择哪个模型。

我们使用的x坐标是Top-1错误(越低越好)。y坐标是GPU推断时间(毫秒,越低越好)。气泡大小代表模型大小(越低越好)。

  • 模型大小较小的气泡更好。
  • 靠近原点的气泡在准确性和速度方面都更好。

在这里插入图片描述

5. 总结

从上图可以清楚地看出,

  • ResNet50是在所有三个参数方面(体积小且靠近原点)表现最佳的模型。
  • DenseNets 和 ResNext101 在推断时间上较为昂贵。
  • AlexNet 和 SqueezeNet 的错误率相当高。

测试代码:002 Pre Trained Models for Image Classification

6. 参考资料

【1】Colab/PyTorch - Getting Started with PyTorch

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

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

相关文章

【系统架构师】-选择题(十二)计算机网络

1、网闸的作用:实现内网与互联网通信,但内网与互联网不是直连的 2、管理距离是指一种路由协议的路由可信度。15表示该路由信息比较可靠 管理距离越小,它的优先级就越高,也就是可信度越高。 0是最可信赖的,而255则意味…

减瘦误区、雷点、陷阱和挑战怎么应对

在减瘦过程中,很多肥胖人群都容易踩到坑。比如陷入误区,认为只有短期快速的减调方式方法,才值得尝试,而忽视身体健康;或是踩到雷点,轻信强速方剂或方法,结果身体产生了排斥或根本没效用白花钱&a…

RabbitMQ的用途

RabbitMQ主要有四个用途,分别是应用解耦、异步提速、削峰填谷、消息分发。详情讲解如下: RabbitMQ介绍、解耦、提速、削峰、分发 详解、RabbitMQ安装 可视化界面讲解 1.应用解耦:提高系统容错性和可维护性 2.异步提速:提升用户体验…

LabVIEW学习记录4-局部变量、全局变量、共享变量

【LabVIEW】局部变量、全局变量、共享变量 一、变量定义二、内存分配三、竞争状态四、变量创建及简单使用示例4.1 局部变量4.1.1 局部变量的创建4.1.2 局部变量的编程实例 4.2 全局变量4.2.1 创建4.2.2 调用4.2.3 编程实例 4.3 共享变量 一、变量定义 LabVIEW(Labor…

怎么把图片改成1920*1080的?一键修改图片尺寸小技巧

一张合适尺寸的图片,不仅可以适应不同设备的屏幕尺寸,保证视觉效果的舒适和协调,还可以有效降低图片的存储空间占用,比如我们有时候想要把一张图片改成1920*1080尺寸的,该如何修改图片尺寸呢?其实可以使用图…

【ZZULI数据结构实验】压缩与解码的钥匙:赫夫曼编码应用

📃博客主页: 小镇敲码人 💚代码仓库,欢迎访问 🚀 欢迎关注:👍点赞 👂🏽留言 😍收藏 🌏 任尔江湖满血骨,我自踏雪寻梅香。 万千浮云遮碧…

虚拟化数据恢复—误还原虚拟机快照怎么办?怎么恢复最新虚拟机数据?

虚拟化技术原理是将硬件虚拟化给不同的虚拟机使用,利用虚拟化技术可以在一台物理机上安装多台虚拟机。误操作或者物理机器出现故障都会导致虚拟机不可用,虚拟机中的数据丢失。 虚拟化数据恢复环境: 有一台虚拟机是由物理机迁移到ESXI上面的&a…

继电器测试负载箱的常见故障和解决方法有哪些?

继电器测试负载箱是用于模拟各种电气负载的设备,广泛应用于继电器、接触器等电气元件的测试和校验。在使用过程中,可能会出现一些故障,影响测试的准确性和效率。以下是一些常见的故障及其解决方法: 电源问题:如果电源电…

FMEA助力医疗设备研发制造:领跑未来,实现弯道超车!

医疗设备作为保障人类健康的重要工具,其研发与制造水平直接关系到医疗技术的进步。然而,在激烈的市场竞争中,如何能够让自家医疗设备研发制造实现弯道超车,成为行业佼佼者?答案就在于——FMEA(失效模式与影…

C语言中数组与指针的区别

一. 简介 本文学习了 C语言中数组与指针的区别。这样的话,可以在编写C代码时规避掉出错的问题。 二. C语言中数组与指针的区别 1. 数组 定义字符串数组时,必须让编译器知道需要多少空间。 一种方法是用足够空间的数组存储字符串。例如如下&#xf…

Spring MVC(三) 参数传递

1 Controller到View的参数传递 在Spring MVC中,把值从Controller传递到View共有5中操作方法,分别是。 使用HttpServletRequest或HttpSession。使用ModelAndView。使用Map集合使用Model使用ModelMap 使用HttpServletRequest或HttpSession传值 使用HttpSe…

GEE数据集——高分辨率全球树冠高度地图(1 米)Meta 公司

高分辨率 1 米全球树冠高度地图 简介 全球树冠高度地图数据集提供了对全球树冠高度的全面了解,有助于对森林生态系统、碳固存和气候变化减缓工作进行精确监测。该数据集由 Meta 和世界资源研究所合作开发,是了解森林结构和动态的基石。通过融合最先进的卫星图像和先进的人工…

python代码学习案例-用turtle库绘制爱心图形效果

Python爱心代码,我们可以使用多种方法,包括使用turtle库来绘制图形,或者使用字符打印来在控制台中显示爱心。 首先,确保你已经安装了Python,并且你的环境支持turtle库(它通常是Python标准库的一部分&#…

Python中批量提取[]括号内第一个元素的四种方法

目录 一、引言 二、方法介绍 使用正则表达式(Regular Expression) 使用字符串分割(String Split) 使用ast模块解析字符串为列表 使用JSON模块解析字符串 三、方法比较与选择 四、总结 一、引言 在Python数据处理过程中&a…

c++游戏小技巧16:实例1(地牢生成算法)

1.前言 (头图) (其实最开始是想写恶魔轮盘的,但没想到它竟然更新了) (等我有时间在更,最近很忙,玩第五玩的) 想法来源:房间和迷宫:一个地牢生成算法https://indienova…

百面算法工程师 | 正则优化函数——BN、LN、Dropout

本文给大家带来的百面算法工程师是正则优化函数,文章内总结了常见的提问问题,旨在为广大学子模拟出更贴合实际的面试问答场景。在这篇文章中,我们将总结一些BN、LN、Dropout的相关知识,并提供参考的回答及其理论基础,以…

redis深入理解之数据存储

1、redis为什么快 1)Redis是单线程执行,在执行时顺序执行 redis单线程主要是指Redis的网络IO和键值对读写是由一个线程来完成的,Redis在处理客户端的请求时包括获取(socket 读)、解析、执行、内容返回 (socket 写)等都由一个顺序串行的主线…

网络编程套接字 (二)---udosocket

本专栏内容为:Linux学习专栏,分为系统和网络两部分。 通过本专栏的深入学习,你可以了解并掌握Linux。 💓博主csdn个人主页:小小unicorn ⏩专栏分类:网络 🚚代码仓库:小小unicorn的代…

mikefile函数与实用模板

文章目录 0.概述1.函数调用语法2.字符串处理函数2.1 subst(字符串替换函数)2.2 patsubst(模式字符串替换函数)2.3 strip(去空格函数)2.4 findstring(查找字符串函数)2.5 filter&…

大型模型技术构建本地知识库

使用大型模型技术构建本地知识库是一个复杂的过程,涉及到数据科学、机器学习和软件工程等多个领域的知识。以下是构建本地知识库的一般步骤。北京木奇移动技术有限公司,专业的软件外包开发公司,欢迎交流合作。 1.需求分析: 确定知…