Colab/PyTorch - 004 Torchvision Semantic Segmentation

news2024/9/21 4:26:59

Colab/PyTorch - 004 Torchvision Semantic Segmentation

  • 1. 源由
  • 2. 语义分割 - 应用
    • 2.1 自动驾驶
    • 2.2 面部分割
    • 2.3 室内物体分割
    • 2.4 地理遥感
  • 3. 语义分割 - torchvision
    • 3.1 FCN 使用 ResNet-101 语义分割
      • 3.1.1 加载模型
      • 3.1.2 加载图像
      • 3.1.3 预处理图像
      • 3.1.4 网络的前向传播
      • 3.1.5 解码输出
      • 3.1.6 最终结果
    • 3.2 使用 DeepLab 语义分割
    • 3.3 多物体语义分割
  • 4. 总结
    • 4.1 推理时间
    • 4.2 模型大小
  • 5. 参考资料

1. 源由

循序渐进的原则:

  1. 逻辑上模型是否具备合理性
  2. 实测能否线性拟合
  3. 实测能否非线性拟合
  4. 实测能否多因素(图像)分类问题分析
  5. 实测能否多因素(图像)分类模型收敛
  6. 实测能否多因素(图像)轮廓勾画
  7. 实测能否多因素(图像)目标关联关系分析
  8. 实测能否多因素(图像)目标场景分析
  9. 。。。 。。。

识别物体类别后,接下来就是轮廓勾画了。这样就能在一张大图中将不同类型的目标进行区分,为后面的关联关系,甚至场景分析做好准备。当然,从一个静态的图片分析关联关系,场景分析是非常难的。

对以下图像进行语义分割,轮廓勾画:

在这里插入图片描述
我们可以得到以下图像:正如您所看到的,图像中的每个像素都被分类到其相应的类别。例如,人是一类,自行车是另一类,第三类是背景。简单来说,这就是语义分割的基本原理 - 识别和分离图像中的每个对象,并相应地对它们进行标记。
在这里插入图片描述

2. 语义分割 - 应用

2.1 自动驾驶

在自动驾驶中,驾驶汽车的计算机需要对其前方的道路场景有很好的理解。将汽车、行人、车道和交通标志等物体分割出来非常重要。

在这里插入图片描述

2.2 面部分割

面部分割用于将脸部的每个部分分割成语义上相似的区域——如嘴唇、眼睛等。这在许多现实世界的应用中都非常有用。一个非常有趣的应用可以是虚拟化妆。

在这里插入图片描述

2.3 室内物体分割

在增强现实(AR)和虚拟现实(VR)中。AR 应用可以对整个室内区域进行分割,以了解椅子、桌子、人、墙壁和其他类似物体的位置,从而可以有效地放置和操作虚拟物体。

在这里插入图片描述

2.4 地理遥感

地理遥感是将卫星图像中的每个像素分为一类的一种方式,以便我们可以跟踪每个区域的土地覆盖情况。如果有地区发生严重的森林砍伐,可以采取适当的措施。利用卫星图像进行语义分割可以有许多其他应用。

在这里插入图片描述

3. 语义分割 - torchvision

我们将研究两种基于深度学习的语义分割模型——全卷积网络(FCN)和DeepLab v3。这些模型已经在 COCO 2017 训练集的子集上进行了训练,该子集对应于 PASCAL VOC 数据集。模型支持共计 20 个类别。

在我们开始之前,让我们了解一下模型的输入和输出。

这些模型期望一个三通道图像(RGB),并使用Imagenet的均值和标准差进行归一化,即
mean = [0.485, 0.456, 0.406], std = [0.229, 0.224, 0.225]

因此,输入维度是[Ni x Ci x Hi x Wi]
其中,

Ni -> 批量大小
Ci -> 通道数(即3)
Hi -> 图像的高度
Wi -> 图像的宽度

模型的输出维度是[No x Co x Ho x Wo]
其中,

No -> 批量大小(与Ni相同)
Co -> 数据集的类别数
Ho -> 图像的高度(在几乎所有情况下与Hi相同)
Wo -> 图像的宽度(在几乎所有情况下与Wi相同)

注意:torchvision模型的输出是一个OrderedDict而不是torch.Tensor。在推断(.eval()模式)期间,输出是一个OrderedDict,只有一个键 - out。这个out键保存输出,相应的值的形状是[No x Co x Ho x Wo]。

3.1 FCN 使用 ResNet-101 语义分割

3.1.1 加载模型

现在,我们有一个带有 Resnet101 主干的 FCN 预训练模型。如果缓存中不存在该模型,设置 pretrained=True 标志将会下载模型。.eval 方法将以推断模式加载模型。

from torchvision import models
fcn = models.segmentation.fcn_resnet101(pretrained=True).eval()
/usr/local/lib/python3.10/dist-packages/torchvision/models/_utils.py:208: UserWarning: The parameter 'pretrained' is deprecated since 0.13 and may be removed in the future, please use 'weights' instead.
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/torchvision/models/_utils.py:223: UserWarning: Arguments other than a weight enum or `None` for 'weights' are deprecated since 0.13 and may be removed in the future. The current behavior is equivalent to passing `weights=FCN_ResNet101_Weights.COCO_WITH_VOC_LABELS_V1`. You can also use `weights=FCN_ResNet101_Weights.DEFAULT` to get the most up-to-date weights.
  warnings.warn(msg)
Downloading: "https://download.pytorch.org/models/fcn_resnet101_coco-7ecb50ca.pth" to /root/.cache/torch/hub/checkpoints/fcn_resnet101_coco-7ecb50ca.pth
100%|██████████| 208M/208M [00:03<00:00, 57.5MB/s]

3.1.2 加载图像

接下来,让我们获取一张图片!我们直接从 URL 下载一张鸟的图片并保存下来。正如你在代码中将看到的,我们使用 PIL 加载图片。

from PIL import Image
import matplotlib.pyplot as plt
import torch

!wget -nv https://static.independent.co.uk/s3fs-public/thumbnails/image/2018/04/10/19/pinyon-jay-bird.jpg -O bird.png
img = Image.open('./bird.png')
plt.imshow(img); plt.show()
2024-05-15 02:18:38 URL:https://static.independent.co.uk/s3fs-public/thumbnails/image/2018/04/10/19/pinyon-jay-bird.jpg [182904/182904] -> "bird.png" [1]

在这里插入图片描述

3.1.3 预处理图像

为了将图像准备成模型推断所需的正确格式,我们需要对其进行预处理和归一化!因此,对于预处理步骤,我们执行以下操作:

  • 将图像调整大小为 (256 x 256)
  • 对其进行中心裁剪为 (224 x 224)
  • 将其转换为张量 —— 图像中的所有值将被缩放,使它们位于 [0, 1] 范围内,而不是原始的 [0, 255] 范围。
  • 使用特定于Imagenet的值对其进行标准化,其中 mean = [0.485, 0.456, 0.406],std = [0.229, 0.224, 0.225]

最后,我们将图像维度进行扩展,使其从 [C x H x W] 变为 [1 x C x H x W]。这是必需的,因为在通过网络时我们需要一个批次。

# Apply the transformations needed
import torchvision.transforms as T
trf = T.Compose([T.Resize(256),
                 T.CenterCrop(224),
                 T.ToTensor(),
                 T.Normalize(mean = [0.485, 0.456, 0.406],
                             std = [0.229, 0.224, 0.225])])
inp = trf(img).unsqueeze(0)

Torchvision有许多有用的函数。其中之一是Transforms,用于对图像进行预处理。T.Compose 是一个函数,它接受一个列表,其中每个元素都是 transforms 类型。这将返回一个对象,通过该对象我们可以传递图像的批次,所有所需的变换都将应用于所有图像。

让我们看一下应用在图像上的变换:

  • T.Resize(256):将图像调整大小为 256 x 256
  • T.CenterCrop(224):将图像居中裁剪,使结果大小为 224 x 224
  • T.ToTensor():将图像转换为 torch.Tensor 类型,并将值缩放到 [0, 1] 范围内
  • T.Normalize(mean, std):使用给定的均值和标准差对图像进行归一化。

3.1.4 网络的前向传播

现在我们有了一个经过预处理和准备好的图像,让我们将其通过模型并获取输出键。

如前所述,模型的输出是一个 OrderedDict,因此我们需要从中获取 out 键来获得模型的输出。

# Pass the input through the net
out = fcn(inp)['out']
print (out.shape)
torch.Size([1, 21, 224, 224])

因此,out 是模型的最终输出。正如之前讨论的,它的形状是 [1 x 21 x H x W]。由于模型是在 21 个类上训练的,输出有 21 个通道!

现在我们需要做的是,将这个具有 21 个通道的输出转换成一个 2D 图像或一个 1 通道图像,其中该图像的每个像素对应一个类!

这个 2D 图像(形状为 [H x W])将每个像素对应到一个类别标签。请注意,该 2D 图像中的每个(x,y)像素对应于一个介于 0 - 20 之间的数字,代表一个类别。

现在的问题是,我们如何从当前具有维度 [1 x 21 x H x W] 的图像得到这个?

很简单!我们对每个像素位置取最大索引,它代表了该类别。

import numpy as np 
om = torch.argmax(out.squeeze(), dim=0).detach().cpu().numpy() 
print(om.shape)
print(np.unique(om))
(224, 224)
[0 3]

通过处理后,我们现在有了一个 2D 图像,其中每个像素对应一个类别。最后要做的是将这个 2D 图像转换成一个分割地图,其中每个类别标签都转换成一个 RGB 颜色,从而帮助可视化。

3.1.5 解码输出

我们将使用以下函数将这个 2D 图像转换为一个 RGB 图像,其中每个标签都映射到其对应的颜色。

# Define the helper function
def decode_segmap(image, nc=21):

  label_colors = np.array([(0, 0, 0),  # 0=background
               # 1=aeroplane, 2=bicycle, 3=bird, 4=boat, 5=bottle
               (128, 0, 0), (0, 128, 0), (128, 128, 0), (0, 0, 128), (128, 0, 128),
               # 6=bus, 7=car, 8=cat, 9=chair, 10=cow
               (0, 128, 128), (128, 128, 128), (64, 0, 0), (192, 0, 0), (64, 128, 0),
               # 11=dining table, 12=dog, 13=horse, 14=motorbike, 15=person
               (192, 128, 0), (64, 0, 128), (192, 0, 128), (64, 128, 128), (192, 128, 128),
               # 16=potted plant, 17=sheep, 18=sofa, 19=train, 20=tv/monitor
               (0, 64, 0), (128, 64, 0), (0, 192, 0), (128, 192, 0), (0, 64, 128)])

  r = np.zeros_like(image).astype(np.uint8)
  g = np.zeros_like(image).astype(np.uint8)
  b = np.zeros_like(image).astype(np.uint8)

  for l in range(0, nc):
    idx = image == l
    r[idx] = label_colors[l, 0]
    g[idx] = label_colors[l, 1]
    b[idx] = label_colors[l, 2]

  rgb = np.stack([r, g, b], axis=2)
  return rgb

让我们来看看这个函数的内部操作!

首先,变量 label_colors 存储了每个类别的颜色,按照索引顺序存储。因此,第一个类别(背景)的颜色存储在 label_colors 列表的第 0 个索引位置。第二个类别(飞机)存储在索引 1 处,依此类推。

现在,我们需要从我们拥有的 2D 图像创建一个 RGB 图像。我们创建了三个通道的空 2D 矩阵。

因此,r、g 和 b 是形成最终图像的 RGB 通道的数组。每个数组的形状都是 [H x W](与 2D 图像的形状相同)。

现在,我们循环遍历我们在 label_colors 中存储的每个类别颜色,并在图像中获取该特定类别标签存在的相应索引。然后,对于每个通道,我们将其对应的颜色放置在具有该类别标签的像素上。

最后,我们将三个单独的通道堆叠在一起,形成一个 RGB 图像。

现在,让我们使用这个函数来查看最终的分割输出!

rgb = decode_segmap(om)
plt.imshow(rgb); plt.show()

在这里插入图片描述
好了!我们已经对图像的输出进行了分割。

那就是那只鸟!

注意:分割后的图像比原始图像小,因为在预处理步骤中对图像进行了调整大小和裁剪。

3.1.6 最终结果

接下来,让我们将所有这些内容整合到一个单一的函数中,并尝试使用更多的图像!

def segment(net, path, show_orig=True, dev='cuda'):
  img = Image.open(path)
  if show_orig: plt.imshow(img); plt.axis('off'); plt.show()
  # Comment the Resize and CenterCrop for better inference results
  trf = T.Compose([T.Resize(640),
                   #T.CenterCrop(224),
                   T.ToTensor(),
                   T.Normalize(mean = [0.485, 0.456, 0.406],
                               std = [0.229, 0.224, 0.225])])
  inp = trf(img).unsqueeze(0).to(dev)
  out = net.to(dev)(inp)['out']
  om = torch.argmax(out.squeeze(), dim=0).detach().cpu().numpy()
  rgb = decode_segmap(om)
  plt.imshow(rgb); plt.axis('off'); plt.show()
!wget -nv https://www.learnopencv.com/wp-content/uploads/2021/01/horse-segmentation.jpeg -O horse.png
segment(fcn, './horse.png')
2024-05-15 02:18:46 URL:http://learnopencv.com/wp-content/uploads/2021/01/horse-segmentation.jpeg [128686/128686] -> "horse.png" [1]

在这里插入图片描述
在这里插入图片描述

3.2 使用 DeepLab 语义分割

DeepLab 是一种语义分割架构,是由 Google Brain 提出的。让我们看看如何使用它。

dlab = models.segmentation.deeplabv3_resnet101(pretrained=1).eval()
/usr/local/lib/python3.10/dist-packages/torchvision/models/_utils.py:223: UserWarning: Arguments other than a weight enum or `None` for 'weights' are deprecated since 0.13 and may be removed in the future. The current behavior is equivalent to passing `weights=DeepLabV3_ResNet101_Weights.COCO_WITH_VOC_LABELS_V1`. You can also use `weights=DeepLabV3_ResNet101_Weights.DEFAULT` to get the most up-to-date weights.
  warnings.warn(msg)
Downloading: "https://download.pytorch.org/models/deeplabv3_resnet101_coco-586e9e4e.pth" to /root/.cache/torch/hub/checkpoints/deeplabv3_resnet101_coco-586e9e4e.pth
100%|██████████| 233M/233M [00:01<00:00, 154MB/s]

让我们看看如何使用这个模型对同一张图片进行语义分割!我们将使用我们上面定义的同一个函数。

segment(dlab, './horse.png')

在这里插入图片描述
在这里插入图片描述

3.3 多物体语义分割

当我们使用具有多个对象的更复杂的图像时,我们可以开始看到使用这两个模型获得的结果之间的一些差异。

让我们来试试吧!

!wget -nv "https://www.learnopencv.com/wp-content/uploads/2021/01/person-segmentation.jpeg" -O person.png
img = Image.open('./person.png')
plt.imshow(img); plt.show()

print ('Segmenatation Image on FCN')
segment(fcn, path='./person.png', show_orig=False)

print ('Segmenatation Image on DeepLabv3')
segment(dlab, path='./person.png', show_orig=False)

在这里插入图片描述

  • Segmenatation Image on FCN
    在这里插入图片描述

  • Segmenatation Image on DeepLabv3

在这里插入图片描述

好的!现在你可以看到模型之间的差异了吧?

你可以看到 FCN 在捕捉牛腿的连续性方面失败了,而 DeepLabv3 能够捕捉到!

此外,如果我们更仔细地观察牛身上的人手,我们会发现 FCN 模型捕捉得还不错,虽然不是非常完美,但仍然可以,而 DeepLabv3 模型也捕捉到了,但不是那么好!

这些是肉眼可见的一些模型差异!

注意:正如我们之前看到的,输出图像的尺寸比原始图像小,因为原始图像在预处理步骤中被调整大小和裁剪。

尽情尝试一些更多的图像,看看这些模型在不同情况下的表现吧!

4. 总结

到目前为止,已经看到了代码的工作原理以及输出在质量上的表现。

我们将讨论模型的定量方面的特性:

在CPU和GPU上的推断时间
模型的大小。
推断时使用的GPU内存。

测试代码:004 Torchvision Semantic Segmentation

4.1 推理时间

import time

def infer_time(net, path='./horse.png', dev='cuda'):
  img = Image.open(path)
  trf = T.Compose([T.Resize(256),
                   T.CenterCrop(224),
                   T.ToTensor(),
                   T.Normalize(mean = [0.485, 0.456, 0.406],
                               std = [0.229, 0.224, 0.225])])

  inp = trf(img).unsqueeze(0).to(dev)

  st = time.time()
  out1 = net.to(dev)(inp)
  et = time.time()

  return et - st
avg_over = 100

fcn_infer_time_list_cpu = [infer_time(fcn, dev='cpu') for _ in range(avg_over)]
fcn_infer_time_avg_cpu = sum(fcn_infer_time_list_cpu) / avg_over

dlab_infer_time_list_cpu = [infer_time(dlab, dev='cpu') for _ in range(avg_over)]
dlab_infer_time_avg_cpu = sum(dlab_infer_time_list_cpu) / avg_over


print ('Inference time for first few calls for FCN      : {}'.format(fcn_infer_time_list_cpu[:10]))
print ('Inference time for first few calls for DeepLabv3: {}'.format(dlab_infer_time_list_cpu[:10]))

print ('The Average Inference time on FCN is:     {:.2f}s'.format(fcn_infer_time_avg_cpu))
print ('The Average Inference time on DeepLab is: {:.2f}s'.format(dlab_infer_time_avg_cpu))
  • On CPU
Inference time for first few calls for FCN      : [1.0962293148040771, 1.41335129737854, 1.4978973865509033, 1.1366255283355713, 0.994088888168335, 1.0438227653503418, 1.0235023498535156, 1.0187690258026123, 1.045358657836914, 1.0086448192596436]
Inference time for first few calls for DeepLabv3: [1.2838966846466064, 1.1889286041259766, 1.4854016304016113, 1.5590059757232666, 1.4725146293640137, 1.1244769096374512, 1.0172410011291504, 0.9699416160583496, 0.9643347263336182, 0.909754753112793]
The Average Inference time on FCN is:     1.11s
The Average Inference time on DeepLab is: 1.04s
  • On GPU
avg_over = 100

fcn_infer_time_list_gpu = [infer_time(fcn) for _ in range(avg_over)]
fcn_infer_time_avg_gpu = sum(fcn_infer_time_list_gpu) / avg_over

dlab_infer_time_list_gpu = [infer_time(dlab) for _ in range(avg_over)]
dlab_infer_time_avg_gpu = sum(dlab_infer_time_list_gpu) / avg_over

print ('Inference time for first few calls for FCN      : {}'.format(fcn_infer_time_list_gpu[:10]))
print ('Inference time for first few calls for DeepLabv3: {}'.format(dlab_infer_time_list_gpu[:10]))

print ('The Average Inference time on FCN is:     {:.3f}s'.format(fcn_infer_time_avg_gpu))
print ('The Average Inference time on DeepLab is: {:.3f}s'.format(dlab_infer_time_avg_gpu))
Inference time for first few calls for FCN      : [0.16111516952514648, 0.018294334411621094, 0.01825737953186035, 0.01937079429626465, 0.018789291381835938, 0.01917719841003418, 0.018662691116333008, 0.01843094825744629, 0.018068552017211914, 0.018398046493530273]
Inference time for first few calls for DeepLabv3: [0.11033177375793457, 0.020525217056274414, 0.020010948181152344, 0.020022869110107422, 0.0229949951171875, 0.022975921630859375, 0.01997232437133789, 0.02288365364074707, 0.02026224136352539, 0.019922971725463867]
The Average Inference time on FCN is:     0.025s
The Average Inference time on DeepLab is: 0.022s
plt.bar([0.1, 0.2], [fcn_infer_time_avg_cpu, dlab_infer_time_avg_cpu], width=0.08)
plt.ylabel('Time taken in Seconds')
plt.xticks([0.1, 0.2], ['FCN', 'DeepLabv3'])
plt.title('Inference time of FCN and DeepLabv3 on CPU')
plt.show()

在这里插入图片描述

plt.bar([0.1, 0.2], [fcn_infer_time_avg_gpu, dlab_infer_time_avg_gpu], width=0.08)
plt.ylabel('Time taken in Seconds')
plt.xticks([0.1, 0.2], ['FCN', 'DeepLabv3'])
plt.title('Inference time of FCN and DeepLabv3 on GPU')
plt.show()

在这里插入图片描述

我们可以看到 DeepLab 模型比 FCN 更快一些。

4.2 模型大小

import os

#/root/.cache/torch/hub/checkpoints/fcn_resnet101_coco-7ecb50ca.pth
#/root/.cache/torch/hub/checkpoints/deeplabv3_resnet101_coco-586e9e4e.pth
#resnet101_size = os.path.getsize('/root/.cache/torch/hub/checkpoints/resnet101-5d3b4d8f.pth')

fcn_size = os.path.getsize('/root/.cache/torch/hub/checkpoints/fcn_resnet101_coco-7ecb50ca.pth')
dlab_size = os.path.getsize('/root/.cache/torch/hub/checkpoints/deeplabv3_resnet101_coco-586e9e4e.pth')

fcn_total = fcn_size # + resnet101_size
dlab_total = dlab_size # + resnet101_size

print ('Size of the FCN model with Resnet101 backbone is:       {:.2f} MB'.format(fcn_total /  (1024 * 1024)))
print ('Size of the DeepLabv3 model with Resnet101 backbone is: {:.2f} MB'.format(dlab_total / (1024 * 1024)))
Size of the FCN model with Resnet101 backbone is:       207.71 MB
Size of the DeepLabv3 model with Resnet101 backbone is: 233.22 MB
plt.bar([0, 1], [fcn_total / (1024 * 1024), dlab_total / (1024 * 1024)])
plt.ylabel('Size of the model in MegaBytes')
plt.xticks([0, 1], ['FCN', 'DeepLabv3'])
plt.title('Comparison of the model size of FCN and DeepLabv3')
plt.show()

在这里插入图片描述

模型大小是指模型的权重文件的大小。DeepLab 模型比 FCN 模型稍微大一些。

5. 参考资料

【1】Colab/PyTorch - Getting Started with PyTorch

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

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

相关文章

红酒与美食的完善搭配艺术

在美食的世界里&#xff0c;红酒总是扮演着不可或缺的角色。它与美食的搭配&#xff0c;是一门深奥的艺术。云仓酒庄雷盛红酒&#xff0c;作为一款备受欢迎的红酒品牌&#xff0c;以其卓着的品质和丰富的口感&#xff0c;成为了红酒与美食搭配的典范。 雷盛红酒&#xff0c;源…

中国农业大学:学硕11408复试线上涨40分,今年还会持续涨吗?中国农业大学计算机考研考情分析!

中国农业大学&#xff08;China Agricultural University&#xff09;&#xff0c;简称“中国农大”&#xff0c;坐落于中国首都北京&#xff0c;由中华人民共和国教育部直属&#xff0c;中央直管副部级建制&#xff0c;水利部、农业部和北京市共建&#xff0c;位列国家“双一流…

CNN卷积神经网络初学

1.为什么要学CNN 在传统神经网络中&#xff0c;我们要识别下图红色框中的图像时&#xff0c;我们很可能识别不出来&#xff0c;因为这六张图的位置都不通&#xff0c;计算机无法分辨出他们其实是一种形状或物体。 这是传统的神经网络图&#xff0c;通过权重调整神经元和神经元…

云曦实验室期中考核题

Web_SINGIN 解题&#xff1a; 点击打开环境&#xff0c;得 查看源代码&#xff0c;得 点开下面的超链接&#xff0c;得 看到一串base64编码&#xff0c;解码得flag 简简单单的文件上传 解题&#xff1a; 点击打开环境&#xff0c;得 可以看出这是一道文件上传的题目&#x…

智慧变电站守护者:TSINGSEE青犀AI视频智能管理系统引领行业革新

一、方案概述 随着科技的不断进步&#xff0c;人工智能&#xff08;AI&#xff09;技术已经深入到各个领域。在变电站安全监控领域&#xff0c;引入AI视频监控智能分析系统&#xff0c;可以实现对站内环境、设备状态的实时监控与智能分析&#xff0c;从而提高变电站的安全运行…

(实测验证)【移远EC800M-CN 】GNSS功能打开和关闭关闭步骤验证

引言 本文章使用自研“超小体积TTL转4GGPS集成模块”进行实测验证&#xff1b; 一、打开GNSS功能 步骤一、通过 ATQGPSCFG 配置 GNSS 参数 &#xff08;1&#xff09;该命令用于查询和配置 GNSS 不同的设置&#xff0c;包括 NMEA 语句输出端口、NMEA 语句的输出类型等。 1.1…

【图神经网络——消息传递】

消息传递机制 画图先&#xff1a;导包&#xff1a;画图&#xff1a; 实现消息传递&#xff1a;例子一&#xff1a;例子二&#xff1a; 画图先&#xff1a; 导包&#xff1a; import networkx as nx import matplotlib.pyplot as plt import torch from torch_geometric.nn im…

基于Java的飞机大战游戏的设计与实现(论文 + 源码)

关于基于Java的飞机大战游戏.zip资源-CSDN文库https://download.csdn.net/download/JW_559/89313362 基于Java的飞机大战游戏的设计与实现 摘 要 现如今&#xff0c;随着智能手机的兴起与普及&#xff0c;加上4G&#xff08;the 4th Generation mobile communication &#x…

用友GRP-U8 bx_dj_check.jsp SQL注入漏洞复现(XVE-2024-10537)

0x01 免责声明 请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;作者不为此承担任何责任。工具来自网络&#xff0c;安全性自测&#xff0c;如有侵权请联系删…

WebSocket or SSE?即时通讯的应用策略【送源码】

最近在研究H5推送&#xff0c;发现除了我们常用的WebSocket以外&#xff0c;其实还有一种协议也能实现H5推送&#xff0c;那就是SSE协议。 而且&#xff0c;当前主流的大模型平台&#xff0c;比如ChatGPT、通义千问、文心一言&#xff0c;对话时采用的就是SSE。 什么是SSE协议…

分布式系统的一致性与共识算法(三)

顺序一致性(Sequential Consistency) ZooKeeper 一种说法是ZooKeeper是最终一致性&#xff0c;因为由于多副本、以及保证大多数成功的ZAB协议&#xff0c;当一个客户端进程写入一个新值&#xff0c;另外一个客户端进程不能保证马上就能读到这个值&#xff0c;但是能保证最终能…

VB6连接各种类型的数据库

VB6连接各种类型的数据库 一、连接VFP数据库 Dim CNN As New ADODB.Connection Dim rssys As New ADODB.Recordset If CNN.state 1 Then CNN.Close CNN.ConnectionString "Driver{Microsoft Visual FoxPro Driver};SourceType.DBc;SourceDb" Trim(Text1) CNN…

掌握这些神器,让你的编程之路更加“丝滑”

前言&#xff1a; 在软件开发的旅程中&#xff0c;程序员的实用神器确实如同指南针&#xff0c;帮助他们在复杂的代码海洋中导航。以下是从三个方向——自动化测试工具、持续集成/持续部署&#xff08;CI/CD&#xff09;以及代码审查与质量分析——来探讨这些实用神器的应用和影…

Google Ads谷歌广告账户被封停怎么办?

跨境出海业务少不了需要做Google Ads推广业务&#xff1b;其中让投手们闻风丧胆的消息就是帐户被暂停。当 Google 检测到任何违反其政策且可能损害用户在线体验的行为时&#xff0c;就会发生这种情况。那么如何在做广告推广的同时&#xff0c;保证账号不被封禁呢&#xff1f;看…

如何向全国各大新闻网站投稿?

在信息爆炸的时代,新闻媒体的投稿工作对于单位的信息宣传员来说,既是一项重要的职责,也是一项充满挑战的任务。作为一名信息宣传员,我负责着单位的对外信息宣传投稿工作,每个月都需要在各大媒体上发表文章,以展示单位的成果和风采。 然而,刚开始的投稿之路并不顺畅。我习惯性地…

scp服务器之间相互传输文件命令

一、格式 scp -r 文件夹路径或者文件路径(绝对路径) 用户名ip地址:目标位置路径选项含义– h显示帮助文档-p尝试保留副本的修改时间和原文件的模式-x在主机之间传输加密所有信息-r如果原文件是目录&#xff0c;复制该目录中每个字树-D<端口>指定连接到远程主机上的端口-…

54.指针

目录 一.什么是指针&#xff1f; 二&#xff0e;定义一个指针变量 三&#xff0e;指针变量类型 四&#xff0e;取地址运算符& 五.取值运算符* 六.视频教程 一.什么是指针&#xff1f; 口语中的指针一般指指针变量&#xff0c;指针变量存放的是一个地址。普通变量存放…

大模型算法(一):从Transformer到ViT再到LLaMA

单任务/单领域模型 深度学习最早的研究集中在针对单个领域或者单个任务设计相应的模型。 对于CV计算机视觉领域&#xff0c;最常用的模型是CNN卷积模型。其中针对计算机视觉中的不同具体任务例如分类任务&#xff0c;目标检测任务&#xff0c;图像分割任务&#xff0c;以CNN作…

双向RNN和双向LSTM

双向RNN和双向LSTM 一、双向循环神经网络BiRNN 1、为什么要用BiRNN 双向RNN&#xff0c;即可以从过去的时间点获取记忆&#xff0c;又可以从未来的时间点获取信息,也就是说具有以下两个特点&#xff1a; 捕捉前后文信息&#xff1a;传统的单向 RNN 只能利用先前的上下文信息…

电路板维修【四】

【开关电源输出电压偏低不稳&#xff0c;用示波器立马锁定故障范围】&#xff1a;https://www.bilibili.com/video/BV1pf421D73K?vd_source3cc3c07b09206097d0d8b0aefdf07958 可以用示波器查看MOS的输出波形来查看其是否损坏&#xff1a; 电源芯片的供电电压来回跳变&#xf…