使用 PyTorch 的计算机视觉简介 (6/6)

news2024/11/18 19:37:56

一、说明

        本文主要介绍CNN中在pytorch的实现,其中MobileNet 网络,数据集来源,以及训练过程,模型生成和存储,模型调入等。

二、轻量级网络和移动网络

        我们已经看到,复杂的网络需要大量的计算资源,如GPU,用于训练和快速推理。然而,事实证明,在大多数情况下,参数数量明显较少的模型仍然可以被训练为表现得相当好。换句话说,模型复杂性的增加通常会导致模型性能的小幅(非成比例)增加。

        我们在模块开始时训练 MNIST 数字分类时观察到了这一点。简单密集模型的准确性并不明显低于强大的CNN。增加分类器中CNN层的数量和/或神经元的数量使我们能够获得百分之几的准确率。这让我们想到,我们可以尝试轻量级网络架构,以便训练更快的模型。如果我们希望能够在移动设备上执行我们的模型,这一点尤其重要。

        该模块将依赖于我们在上一个单元中下载的猫和狗数据集。首先,我们将确保数据集可用。

!wget https://raw.githubusercontent.com/MicrosoftDocs/pytorchfundamentals/main/computer-vision-pytorch/pytorchcv.py

 

import torch
import torch.nn as nn
import torchvision
import matplotlib.pyplot as plt
from torchinfo import summary
import os

from pytorchcv import train, display_dataset, train_long, load_cats_dogs_dataset, validate, common_transform
if not os.path.exists('data/kagglecatsanddogs_5340.zip'):
    !wget -P data -q https://download.microsoft.com/download/3/E/1/3E1C3F21-ECDB-4869-8368-6DEBA77B919F/kagglecatsanddogs_5340.zip

dataset, train_loader, test_loader = load_cats_dogs_dataset()
三、移动网络
        在上一个单元中,我们已经看到了用于图像分类的 ResNet 架构。ResNet的更轻量级模拟是MobileNet,它使用所谓的倒置残差块。让我们加载预先训练的移动网络,看看它是如何工作的:

model = torch.hub.load('pytorch/vision:v0.13.0', 'mobilenet_v2', weights='MobileNet_V2_Weights.DEFAULT')
model.eval()
print(model)
MobileNetV2(
  (features): Sequential(
    (0): ConvBNReLU(
      (0): Conv2d(3, 32, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
      (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (2): ReLU6(inplace=True)
    )
    (1): InvertedResidual(
      (conv): Sequential(
        (0): ConvBNReLU(
          (0): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=32, bias=False)
          (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (2): ReLU6(inplace=True)
        )
        (1): Conv2d(32, 16, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (2): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (2): InvertedResidual(
      (conv): Sequential(
        (0): ConvBNReLU(
          (0): Conv2d(16, 96, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (1): BatchNorm2d(96, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (2): ReLU6(inplace=True)
        )
        (1): ConvBNReLU(
          (0): Conv2d(96, 96, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), groups=96, bias=False)
          (1): BatchNorm2d(96, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (2): ReLU6(inplace=True)
        )
        (2): Conv2d(96, 24, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (3): BatchNorm2d(24, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (3): InvertedResidual(
      (conv): Sequential(
        (0): ConvBNReLU(
          (0): Conv2d(24, 144, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (1): BatchNorm2d(144, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (2): ReLU6(inplace=True)
        )
        (1): ConvBNReLU(
          (0): Conv2d(144, 144, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=144, bias=False)
          (1): BatchNorm2d(144, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (2): ReLU6(inplace=True)
        )
        (2): Conv2d(144, 24, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (3): BatchNorm2d(24, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (4): InvertedResidual(
      (conv): Sequential(
        (0): ConvBNReLU(
          (0): Conv2d(24, 144, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (1): BatchNorm2d(144, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (2): ReLU6(inplace=True)
        )
        (1): ConvBNReLU(
          (0): Conv2d(144, 144, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), groups=144, bias=False)
          (1): BatchNorm2d(144, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (2): ReLU6(inplace=True)
        )
        (2): Conv2d(144, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (3): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (5): InvertedResidual(
      (conv): Sequential(
        (0): ConvBNReLU(
          (0): Conv2d(32, 192, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (1): BatchNorm2d(192, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (2): ReLU6(inplace=True)
        )
        (1): ConvBNReLU(
          (0): Conv2d(192, 192, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=192, bias=False)
          (1): BatchNorm2d(192, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (2): ReLU6(inplace=True)
        )
        (2): Conv2d(192, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (3): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (6): InvertedResidual(
      (conv): Sequential(
        (0): ConvBNReLU(
          (0): Conv2d(32, 192, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (1): BatchNorm2d(192, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (2): ReLU6(inplace=True)
        )
        (1): ConvBNReLU(
          (0): Conv2d(192, 192, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=192, bias=False)
          (1): BatchNorm2d(192, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (2): ReLU6(inplace=True)
        )
        (2): Conv2d(192, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (3): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (7): InvertedResidual(
      (conv): Sequential(
        (0): ConvBNReLU(
          (0): Conv2d(32, 192, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (1): BatchNorm2d(192, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (2): ReLU6(inplace=True)
        )
        (1): ConvBNReLU(
          (0): Conv2d(192, 192, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), groups=192, bias=False)
          (1): BatchNorm2d(192, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (2): ReLU6(inplace=True)
        )
        (2): Conv2d(192, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (3): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (8): InvertedResidual(
      (conv): Sequential(
        (0): ConvBNReLU(
          (0): Conv2d(64, 384, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (1): BatchNorm2d(384, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (2): ReLU6(inplace=True)
        )
        (1): ConvBNReLU(
          (0): Conv2d(384, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=384, bias=False)
          (1): BatchNorm2d(384, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (2): ReLU6(inplace=True)
        )
        (2): Conv2d(384, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (3): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (9): InvertedResidual(
      (conv): Sequential(
        (0): ConvBNReLU(
          (0): Conv2d(64, 384, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (1): BatchNorm2d(384, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (2): ReLU6(inplace=True)
        )
        (1): ConvBNReLU(
          (0): Conv2d(384, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=384, bias=False)
          (1): BatchNorm2d(384, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (2): ReLU6(inplace=True)
        )
        (2): Conv2d(384, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (3): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (10): InvertedResidual(
      (conv): Sequential(
        (0): ConvBNReLU(
          (0): Conv2d(64, 384, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (1): BatchNorm2d(384, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (2): ReLU6(inplace=True)
        )
        (1): ConvBNReLU(
          (0): Conv2d(384, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=384, bias=False)
          (1): BatchNorm2d(384, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (2): ReLU6(inplace=True)
        )
        (2): Conv2d(384, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (3): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (11): InvertedResidual(
      (conv): Sequential(
        (0): ConvBNReLU(
          (0): Conv2d(64, 384, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (1): BatchNorm2d(384, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (2): ReLU6(inplace=True)
        )
        (1): ConvBNReLU(
          (0): Conv2d(384, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=384, bias=False)
          (1): BatchNorm2d(384, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (2): ReLU6(inplace=True)
        )
        (2): Conv2d(384, 96, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (3): BatchNorm2d(96, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (12): InvertedResidual(
      (conv): Sequential(
        (0): ConvBNReLU(
          (0): Conv2d(96, 576, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (1): BatchNorm2d(576, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (2): ReLU6(inplace=True)
        )
        (1): ConvBNReLU(
          (0): Conv2d(576, 576, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=576, bias=False)
          (1): BatchNorm2d(576, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (2): ReLU6(inplace=True)
        )
        (2): Conv2d(576, 96, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (3): BatchNorm2d(96, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (13): InvertedResidual(
      (conv): Sequential(
        (0): ConvBNReLU(
          (0): Conv2d(96, 576, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (1): BatchNorm2d(576, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (2): ReLU6(inplace=True)
        )
        (1): ConvBNReLU(
          (0): Conv2d(576, 576, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=576, bias=False)
          (1): BatchNorm2d(576, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (2): ReLU6(inplace=True)
        )
        (2): Conv2d(576, 96, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (3): BatchNorm2d(96, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (14): InvertedResidual(
      (conv): Sequential(
        (0): ConvBNReLU(
          (0): Conv2d(96, 576, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (1): BatchNorm2d(576, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (2): ReLU6(inplace=True)
        )
        (1): ConvBNReLU(
          (0): Conv2d(576, 576, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), groups=576, bias=False)
          (1): BatchNorm2d(576, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (2): ReLU6(inplace=True)
        )
        (2): Conv2d(576, 160, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (3): BatchNorm2d(160, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (15): InvertedResidual(
      (conv): Sequential(
        (0): ConvBNReLU(
          (0): Conv2d(160, 960, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (1): BatchNorm2d(960, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (2): ReLU6(inplace=True)
        )
        (1): ConvBNReLU(
          (0): Conv2d(960, 960, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=960, bias=False)
          (1): BatchNorm2d(960, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (2): ReLU6(inplace=True)
        )
        (2): Conv2d(960, 160, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (3): BatchNorm2d(160, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (16): InvertedResidual(
      (conv): Sequential(
        (0): ConvBNReLU(
          (0): Conv2d(160, 960, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (1): BatchNorm2d(960, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (2): ReLU6(inplace=True)
        )
        (1): ConvBNReLU(
          (0): Conv2d(960, 960, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=960, bias=False)
          (1): BatchNorm2d(960, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (2): ReLU6(inplace=True)
        )
        (2): Conv2d(960, 160, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (3): BatchNorm2d(160, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (17): InvertedResidual(
      (conv): Sequential(
        (0): ConvBNReLU(
          (0): Conv2d(160, 960, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (1): BatchNorm2d(960, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (2): ReLU6(inplace=True)
        )
        (1): ConvBNReLU(
          (0): Conv2d(960, 960, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=960, bias=False)
          (1): BatchNorm2d(960, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (2): ReLU6(inplace=True)
        )
        (2): Conv2d(960, 320, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (3): BatchNorm2d(320, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (18): ConvBNReLU(
      (0): Conv2d(320, 1280, kernel_size=(1, 1), stride=(1, 1), bias=False)
      (1): BatchNorm2d(1280, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (2): ReLU6(inplace=True)
    )
  )
  (classifier): Sequential(
    (0): Dropout(p=0.2, inplace=False)
    (1): Linear(in_features=1280, out_features=1000, bias=True)
  )
)

        让我们将模型应用于我们的数据集,并确保它有效。

sample_image = dataset[0][0].unsqueeze(0)
res = model(sample_image)
print(res[0].argmax())
tensor(281)

        结果 (281) 是 ImageNet 类号,我们在上一个单元中已经讨论过了。请注意,MobileNet 和全尺寸 ResNet 模型中的参数数量差异很大。在某些方面,MobileNet比VGG型号系列更紧凑,但精度较低。但是,参数数量的减少自然会导致模型精度有所下降。

三 使用移动网络进行迁移学习

        现在,让我们执行与上一单元相同的迁移学习过程,但使用MobileNet。首先,让我们冻结模型的所有参数:

for x in model.parameters():
    x.requires_grad = False

        然后,替换最终分类器。我们还将模型传输到默认训练设备(GPU 或 CPU):

device = 'cuda' if torch.cuda.is_available() else 'cpu'
model.classifier = nn.Linear(1280,2)
model = model.to(device)
summary(model,input_size=(1,3,244,244))
==========================================================================================
Layer (type:depth-idx)                   Output Shape              Param #
==========================================================================================
├─Sequential: 1-1                        [1, 1280, 8, 8]           --
|    └─ConvBNReLU: 2-1                   [1, 32, 122, 122]         --
|    |    └─Conv2d: 3-1                  [1, 32, 122, 122]         (864)
|    |    └─BatchNorm2d: 3-2             [1, 32, 122, 122]         (64)
|    |    └─ReLU6: 3-3                   [1, 32, 122, 122]         --
|    └─InvertedResidual: 2-2             [1, 16, 122, 122]         --
|    |    └─Sequential: 3-4              [1, 16, 122, 122]         (896)
|    └─InvertedResidual: 2-3             [1, 24, 61, 61]           --
|    |    └─Sequential: 3-5              [1, 24, 61, 61]           (5,136)
|    └─InvertedResidual: 2-4             [1, 24, 61, 61]           --
|    |    └─Sequential: 3-6              [1, 24, 61, 61]           (8,832)
|    └─InvertedResidual: 2-5             [1, 32, 31, 31]           --
|    |    └─Sequential: 3-7              [1, 32, 31, 31]           (10,000)
|    └─InvertedResidual: 2-6             [1, 32, 31, 31]           --
|    |    └─Sequential: 3-8              [1, 32, 31, 31]           (14,848)
|    └─InvertedResidual: 2-7             [1, 32, 31, 31]           --
|    |    └─Sequential: 3-9              [1, 32, 31, 31]           (14,848)
|    └─InvertedResidual: 2-8             [1, 64, 16, 16]           --
|    |    └─Sequential: 3-10             [1, 64, 16, 16]           (21,056)
|    └─InvertedResidual: 2-9             [1, 64, 16, 16]           --
|    |    └─Sequential: 3-11             [1, 64, 16, 16]           (54,272)
|    └─InvertedResidual: 2-10            [1, 64, 16, 16]           --
|    |    └─Sequential: 3-12             [1, 64, 16, 16]           (54,272)
|    └─InvertedResidual: 2-11            [1, 64, 16, 16]           --
|    |    └─Sequential: 3-13             [1, 64, 16, 16]           (54,272)
|    └─InvertedResidual: 2-12            [1, 96, 16, 16]           --
|    |    └─Sequential: 3-14             [1, 96, 16, 16]           (66,624)
|    └─InvertedResidual: 2-13            [1, 96, 16, 16]           --
|    |    └─Sequential: 3-15             [1, 96, 16, 16]           (118,272)
|    └─InvertedResidual: 2-14            [1, 96, 16, 16]           --
|    |    └─Sequential: 3-16             [1, 96, 16, 16]           (118,272)
|    └─InvertedResidual: 2-15            [1, 160, 8, 8]            --
|    |    └─Sequential: 3-17             [1, 160, 8, 8]            (155,264)
|    └─InvertedResidual: 2-16            [1, 160, 8, 8]            --
|    |    └─Sequential: 3-18             [1, 160, 8, 8]            (320,000)
|    └─InvertedResidual: 2-17            [1, 160, 8, 8]            --
|    |    └─Sequential: 3-19             [1, 160, 8, 8]            (320,000)
|    └─InvertedResidual: 2-18            [1, 320, 8, 8]            --
|    |    └─Sequential: 3-20             [1, 320, 8, 8]            (473,920)
|    └─ConvBNReLU: 2-19                  [1, 1280, 8, 8]           --
|    |    └─Conv2d: 3-21                 [1, 1280, 8, 8]           (409,600)
|    |    └─BatchNorm2d: 3-22            [1, 1280, 8, 8]           (2,560)
|    |    └─ReLU6: 3-23                  [1, 1280, 8, 8]           --
├─Linear: 1-2                            [1, 2]                    2,562
==========================================================================================
Total params: 2,226,434
Trainable params: 2,562
Non-trainable params: 2,223,872
Total mult-adds (M): 196.40
==========================================================================================
Input size (MB): 0.71
Forward/backward pass size (MB): 20.12
Params size (MB): 8.91
Estimated Total Size (MB): 29.74
==========================================================================================

现在让我们进行实际培训:

train_long(model,train_loader,test_loader,loss_fn=torch.nn.CrossEntropyLoss(),epochs=1,print_freq=90)
Epoch 0, minibatch 0: train acc = 0.5, train loss = 0.02309325896203518
Epoch 0, minibatch 90: train acc = 0.9443681318681318, train loss = 0.006317565729329874
Epoch 0, minibatch 180: train acc = 0.9488950276243094, train loss = 0.00590015182178982
Epoch 0, minibatch 270: train acc = 0.9492619926199262, train loss = 0.006072205810969167
Epoch 0, minibatch 360: train acc = 0.9500519390581718, train loss = 0.00641324315374908
Epoch 0, minibatch 450: train acc = 0.9494872505543237, train loss = 0.006945275943189397
Epoch 0, minibatch 540: train acc = 0.9521141404805915, train loss = 0.0067323536617257896
Epoch 0 done, validation acc = 0.98245, validation loss = 0.002347727584838867

四、结语

        请注意,MobileNet 的精度几乎与 VGG-16 相同,只是略低于满量程 ResNet。小型模型(如MobileNet或ResNet-18)的主要优点是它们可以在移动设备上使用。

V笔记本

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

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

相关文章

4位密码锁可修改密码及错误报警VHDL

名称:4位密码锁可修改密码及错误报警(代码在文末付费下载) 软件:Quartus 语言:VHDL 要求: 按键包括,0~9,确认,重置,修改,密码4位 要能设定密码&#xff0c…

【PowerQuery】Python自动刷新本地数据

Python数据刷新是开发爱好者和开发人员开发的PowerBI刷新模块进行数据刷新的手段,Python进行数据刷新是通过刷新PowerBI Desktop 的模式进行数据刷新。目前常用的Python的数据刷新模块是PbixRefresher,图为相关的模块和版本。 由于当前的脚本基于英文版本的PowerBI Desktop进…

罗德里格斯公式

1.点乘 A ⃗ ⋅ B ⃗ ∣ A ⃗ ∣ ∣ B ⃗ ∣ c o s ⟨ A ⃗ , B ⃗ ⟩ \vec{A} \cdot \vec{B} \left | \vec{A} \right | \left | \vec{B} \right | cos\left \langle \vec{A}, \vec{B} \right \rangle A ⋅B ​A ​ ​B ​cos⟨A ,B ⟩ 对应几何意义:向量 A ⃗…

驱动代码整理

一&#xff0c;控制LED灯控制实验 头文件 #ifndef __HEAD_H__ #define __HEAD_H__#define LED1_MODER 0X50006000 #define LED1_ODR 0X50006014 #define LED1_RCC 0X50000A28#endif 驱动 #include <linux/init.h> #include <linux/module.h> #include &l…

Vue模板语法【下】事件处理器,表单、自定义组件、通信组件

目录 一、事件处理器 1.1常用的事件修饰符 1.2常用的按键修饰符 二&#xff0c;vue中的表单 三、自定义组件 四&#xff0c;通信组件 一、事件处理器 1.1常用的事件修饰符 Vue的事件修饰符是用来改变事件的默认行为或者添加额外的功能。以下是一些常用的事件修饰符及其…

Github 上很火的开源网页图标

Devicon https://devicon.dev 一系列关于编程语言、设计和开发工具的图标&#xff0c;提供了字体格式和 SVG 代码可以直接应用在你的项目中 VSCode Icons https://github.com/microsoft/vscode-icons#readme 收藏了 Visual Studio Code 软件上的所有的图标 Weather Icons https…

【06】FISCOBCOS中的节点前置服务

WeBASE管理平台 微众银行开源的自研区块链中间件平台——WeBASE(WeBank Blockchain Application Software Extension) 是区块链应用和FISCO BCOS节点之间搭建的中间件平台。WeBASE屏蔽了区块链底层的复杂度,降低区块链使用的门槛,大幅提高区块链应用的开发效率,包含节点前置…

【深度学习】图像去噪(2)——常见网络学习

【深度学习】图像去噪 是在 【深度学习】计算机视觉 系列文章的基础上&#xff0c;再次针对深度学习&#xff08;尤其是图像去噪方面&#xff09;的基础知识有更深入学习和巩固。 1 DnCNN 1.1 网络结构 1.1.1 残差学习 1.1.2 Batch Normalization (BN) 1.1.2.1 背景和目标…

手机也可以将声音转为字幕!支持中英日韩4种语言

快去看看你的华为手机有没有这个功能——AI字幕&#xff0c;可以将手机里的音频转换为文字&#xff08;以字幕形式展现&#xff0c;可保存在手机备忘录&#xff09; AI字幕有什么用途&#xff1f; 1. 在听觉不太好使的环境下&#xff0c;将音频信息转化到视觉&#xff08;文本…

OpenGLES:单纹理贴图

一.概述 最近疏于写博客&#xff0c;接下来会陆续更新这段时间OpenGLES的一些开发过程。 前两篇OpenGLES的博客讲解了怎样使用OpenGLES实现相机普通预览和多宫格滤镜 在相机实现过程中&#xff0c;虽然使用到了纹理&#xff0c;但只是在生成一个纹理之后&#xff0c;使用纹理…

基于SpringBoot+Vue+支付宝支付的汽车租赁系统(可做毕设/课设)

技术栈 前后端分离 前端使用: Vue Element 后端使用: SpringBoot Mysql8.0 Mybatis 支付宝支付 功能 分为 管理员端 和 普通用户端 和 维修人员端 普通用户端 1.首页 展示所有品牌,汽车,公告,按关键字搜索汽车名 2.汽车详情页 展示汽车详情和评价 3.下单支付和退押金 立即下单…

vue3 - 开发和生产环境通过Mock模拟真实接口请求

GitHub Demo 地址 在线预览 在前端开发中&#xff0c;常常需要与后端接口进行交互。然而&#xff0c;在接口尚未实现或者正在开发的情况下&#xff0c;前端开发人员往往无法得到真实的接口数据&#xff0c;这给开发和测试工作带来了一定的困扰。对此&#xff0c;可以通过Mock模…

《动手学深度学习 Pytorch版》 7.7 稠密连接网络

7.7.1 从 ResNet 到 DenseNet DenseNet 可以视为 ResNet 的逻辑扩展。 ResNet 将函数展开为 f ( x ) x g ( x ) f(\boldsymbol{x})xg(\boldsymbol{x}) f(x)xg(x)&#xff0c;即一个简单的线性项和一个复杂的非线性项。 若将 f f f 拓展成超过两部分&#xff0c;则 Dense…

CRM客户管理系统英文专业版

外资公司日常沟通的语言以英文为主&#xff0c;业务往来也是涉及到国内外&#xff0c;专业的英文版CRM系统很适合这样的业务团队&#xff0c;尤其CRM供应商是国际化企业&#xff0c;在海外也有分公司、办事处。 多语言 ZOHO支持多语种如英语、汉语、日语等28种语言&#xff0…

Next.js 13.5 正式发布,速度大幅提升!

9 月 19 日&#xff0c;Next.js 13.5 正式发布&#xff0c;该版本通过以下方式提高了本地开发性能和可靠性&#xff1a; 本地服务器启动速度提高 22%&#xff1a;使用App和Pages Router可以更快地进行迭代 HMR&#xff08;快速刷新&#xff09;速度提高 29%&#xff1a;在保存…

C++之指向引用的指针和指向指针的引用总结(二百三十四)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

【计算机视觉】图像的获取和表示——图像传感器技术|主要参数解析、成像原理剖析、传感器处理

博主简介&#xff1a;努力学习的22级计算机科学与技术本科生&#x1f338;博主主页&#xff1a; 是瑶瑶子啦每日一言&#x1f33c;: 每一个不曾起舞的日子&#xff0c;都是对生命的辜负。——尼采 前言 文章目录 前言一、图像传感器技术1.0&#xff1a;前言1.1&#xff1a;两种…

自定义类型详解(上)

结构体 1 结构体的声明 1.1 结构的基础知识 结构是一些值的集合&#xff0c;这些值称为成员变量。结构的每个成员可以是不同类型的变量。 1.2 结构的声明 struct tag//struct是结构体的标志&#xff0c;tag是标签;名字。 {member-list;//成员变量 }variable-list;//变量列…

Nginx 关闭/屏蔽 PUT、DELETE、OPTIONS 请求

1、修改 nginx 配置 在 nginx 配置文件中&#xff0c;增加如下配置内容&#xff1a; if ($request_method !~* GET|POST|HEAD) {return 403; }修改效果如下&#xff1a; 2、重启 nginx 服务 systemctl restart nginx或者 service nginx restart3、功能验证 使用如下方式…

【计算机网络】互联网公司的网络架构和业务场景

互联网公司的网络架构和业务场景 1. 互联网公司网络的组成1.1 网络的物理组成1.2 骨干网组成1.3 数据中心网络组成 2.互联网公司网络服务场景2.1 通用服务场景2.1.1 客户端到服务端请求真实网络过程2.1.2 客户端到服务端请求抽象网络过程2.1.3 负载均衡网络模型 2.2 边缘服务场…