PyTorch示例——ResNet34模型和Fruits图像数据

news/2024/5/14 9:06:18/文章来源:https://blog.csdn.net/alionsss/article/details/131524573

PyTorch示例——ResNet34模型和Fruits图像数据

    • 前言
    • 导包
    • 数据探索查看
    • 数据集构建
    • 构建模型 ResNet34
    • 模型训练
    • 绘制训练曲线

前言

  • ResNet34模型,做图像分类
  • 数据使用水果图片数据集,下载见Kaggle Fruits Dataset (Images)
  • Kaggle的Notebook示例见 PyTorch——ResNet34模型和Fruits数据
  • 下面见代码

导包

from PIL import Image
import os
import random
import matplotlib.pyplot as plt
import torch
from torch import nn
from torch.utils.data import Dataset, DataLoader
from torch.nn import functional as F
from torchvision import transforms as T
from torchvision.datasets import ImageFolder
import tqdm

数据探索查看

  • 查看图像
path = "/kaggle/input/fruits-dataset-images/images"
fruit_path = "apple fruit"
apple_files = os.listdir(path + "/" + fruit_path)Image.open(path + "/"+fruit_path+"/" + apple_files[2])

apple

  • 展示多张图片
def show_images(n_rows, n_cols, x_data):assert n_rows * n_cols <= len(x_data)plt.figure(figsize=(n_cols * 1.5, n_rows * 1.5))for row in range(n_rows):for col in range(n_cols):index = row * n_cols + colplt.subplot(n_rows, n_cols, index + 1)plt.imshow(x_data[index][0], cmap="binary", interpolation="nearest")  # 图像plt.axis("off")plt.title(x_data[index][1])  # 标签plt.show()def show_fruit_imgs(fruit, cols, rows):files = os.listdir(path + "/" + fruit)images = []for _ in range(cols * rows):file = files[random.randint(0, len(files) -1)]image = Image.open(path + "/" + fruit + "/" + file)label = file.split(".")[0]images.append((image, label))show_images(cols, rows, images)
  • 苹果
show_fruit_imgs("apple fruit", 3, 3)

apples

  • 樱桃
show_fruit_imgs("cherry fruit", 3, 3)

cherry

数据集构建

  • 直接使用ImageFolder加载数据,按目录解析水果类别
transforms = T.Compose([T.Resize(224),T.CenterCrop(224),T.ToTensor(),T.Normalize(mean=[5., 5., 5.], std=[.5, .5, .5])
])train_dataset = ImageFolder(path, transform=transforms)
classification = os.listdir(path)train_dataset[2]
  • 输出如下
(tensor([[[-8., -8., -8.,  ..., -8., -8., -8.],[-8., -8., -8.,  ..., -8., -8., -8.],[-8., -8., -8.,  ..., -8., -8., -8.],...,[-8., -8., -8.,  ..., -8., -8., -8.],[-8., -8., -8.,  ..., -8., -8., -8.],[-8., -8., -8.,  ..., -8., -8., -8.]],[[-8., -8., -8.,  ..., -8., -8., -8.],[-8., -8., -8.,  ..., -8., -8., -8.],[-8., -8., -8.,  ..., -8., -8., -8.],...,[-8., -8., -8.,  ..., -8., -8., -8.],[-8., -8., -8.,  ..., -8., -8., -8.],[-8., -8., -8.,  ..., -8., -8., -8.]],[[-8., -8., -8.,  ..., -8., -8., -8.],[-8., -8., -8.,  ..., -8., -8., -8.],[-8., -8., -8.,  ..., -8., -8., -8.],...,[-8., -8., -8.,  ..., -8., -8., -8.],[-8., -8., -8.,  ..., -8., -8., -8.],[-8., -8., -8.,  ..., -8., -8., -8.]]]),0)

构建模型 ResNet34

  • ResidualBlock
class ResidualBlock(nn.Module):def __init__(self, in_channels, out_channels, stride=1, shortcut=None):super().__init__()self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=(3, 3), stride=stride, padding=1, bias=False)self.bn1 = nn.BatchNorm2d(out_channels)self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=(3, 3), stride=1, padding=1, bias=False)self.bn2 = nn.BatchNorm2d(out_channels)self.right = shortcutdef forward(self, X):out = self.conv1(X)out = self.bn1(out)out = F.relu(out, inplace=True)out = self.conv2(out)out = self.bn2(out)residual = self.right(X) if self.right else Xout += residualout = F.relu(out)return out
  • ResNet34
class ResNet34(nn.Module):def __init__(self):super().__init__()self.pre = nn.Sequential(nn.Conv2d(3, 64, 7, 2, 3, bias=False),nn.BatchNorm2d(64),nn.ReLU(inplace=True),nn.MaxPool2d(3, 2, 1))self.layer1 = self._make_layer(64, 64, 3, 1, False)self.layer2 = self._make_layer(64, 128, 4, 2, True)self.layer3 = self._make_layer(128, 256, 6, 2, True)self.layer4 = self._make_layer(256, 512, 3, 2, True)self.fc = nn.Linear(512, len(classification))def _make_layer(self, in_channels, out_channels, block_num, stride, is_shortcut):shortcut = Noneif is_shortcut:shortcut = nn.Sequential(nn.Conv2d(in_channels, out_channels, 1, stride, bias=False),nn.BatchNorm2d(out_channels))layers = []rb = ResidualBlock(in_channels, out_channels, stride, shortcut)layers.append(rb)for i in range(1, block_num):layers.append(ResidualBlock(out_channels, out_channels))return nn.Sequential(*layers)def forward(self, X):out = self.pre(X)out = self.layer1(out)out = self.layer2(out)out = self.layer3(out)out = self.layer4(out)out = F.avg_pool2d(out, 7)out = out.view(out.size(0), -1)out = self.fc(out)return out

模型训练

  • 准备代码
def pad(num, target) -> str:"""将num长度与target对齐"""return str(num).zfill(len(str(target)))# 参数配置
epoch_num = 50
batch_size = 32
learning_rate = 0.0005device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')# 数据
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True, num_workers=4)# 构建模型
model = ResNet34().to(device)
criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)print(model)
ResNet34((pre): Sequential((0): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)(1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True)(3): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False))(layer1): Sequential((0): ResidualBlock((conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True))(1): ResidualBlock((conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True))(2): ResidualBlock((conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)))(layer2): Sequential((0): ResidualBlock((conv1): Conv2d(64, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)(bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(right): Sequential((0): Conv2d(64, 128, kernel_size=(1, 1), stride=(2, 2), bias=False)(1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)))(1): ResidualBlock((conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True))(2): ResidualBlock((conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True))(3): ResidualBlock((conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)))(layer3): Sequential((0): ResidualBlock((conv1): Conv2d(128, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(right): Sequential((0): Conv2d(128, 256, kernel_size=(1, 1), stride=(2, 2), bias=False)(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)))(1): ResidualBlock((conv1): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True))(2): ResidualBlock((conv1): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True))(3): ResidualBlock((conv1): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True))(4): ResidualBlock((conv1): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True))(5): ResidualBlock((conv1): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)))(layer4): Sequential((0): ResidualBlock((conv1): Conv2d(256, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)(bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(right): Sequential((0): Conv2d(256, 512, kernel_size=(1, 1), stride=(2, 2), bias=False)(1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)))(1): ResidualBlock((conv1): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True))(2): ResidualBlock((conv1): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)))(fc): Linear(in_features=512, out_features=9, bias=True)
)
  • 开始训练
# 开始训练
train_loss_list = []
total_step = len(train_loader)
for epoch in range(1, epoch_num + 1):model.traintrain_total_loss, train_total, train_correct  = 0, 0, 0train_progress = tqdm.tqdm(train_loader, desc="Train...")for i, (X, y) in enumerate(train_progress, 1):X, y = X.to(device), y.to(device)out = model(X)loss = criterion(out, y)loss.backward()optimizer.step()optimizer.zero_grad()_, pred = torch.max(out, 1)train_total += y.size(0)train_correct += (pred == y).sum().item()train_total_loss += loss.item()train_progress.set_description(f"Train... [epoch {pad(epoch, epoch_num)}/{epoch_num}, loss {(train_total_loss / i):.4f}, accuracy {train_correct / train_total:.4f}]")train_loss_list.append(train_total_loss / total_step) 
Train... [epoch 01/50, loss 2.3034, accuracy 0.2006]: 100%|██████████| 12/12 [00:15<00:00,  1.32s/it]
Train... [epoch 02/50, loss 1.9193, accuracy 0.3064]: 100%|██████████| 12/12 [00:16<00:00,  1.36s/it]
Train... [epoch 03/50, loss 1.6338, accuracy 0.3482]: 100%|██████████| 12/12 [00:15<00:00,  1.30s/it]
Train... [epoch 04/50, loss 1.6031, accuracy 0.3649]: 100%|██████████| 12/12 [00:16<00:00,  1.38s/it]
Train... [epoch 05/50, loss 1.5298, accuracy 0.4401]: 100%|██████████| 12/12 [00:15<00:00,  1.31s/it]
Train... [epoch 06/50, loss 1.4189, accuracy 0.4429]: 100%|██████████| 12/12 [00:16<00:00,  1.34s/it]
Train... [epoch 07/50, loss 1.5439, accuracy 0.4708]: 100%|██████████| 12/12 [00:15<00:00,  1.31s/it]
Train... [epoch 08/50, loss 1.4378, accuracy 0.4596]: 100%|██████████| 12/12 [00:16<00:00,  1.36s/it]
Train... [epoch 09/50, loss 1.4005, accuracy 0.5348]: 100%|██████████| 12/12 [00:15<00:00,  1.32s/it]
Train... [epoch 10/50, loss 1.2937, accuracy 0.5599]: 100%|██████████| 12/12 [00:16<00:00,  1.34s/it]
......
Train... [epoch 45/50, loss 0.7966, accuracy 0.7354]: 100%|██████████| 12/12 [00:15<00:00,  1.27s/it]
Train... [epoch 46/50, loss 0.8075, accuracy 0.7660]: 100%|██████████| 12/12 [00:15<00:00,  1.33s/it]
Train... [epoch 47/50, loss 0.8587, accuracy 0.7131]: 100%|██████████| 12/12 [00:15<00:00,  1.27s/it]
Train... [epoch 48/50, loss 0.7171, accuracy 0.7604]: 100%|██████████| 12/12 [00:16<00:00,  1.35s/it]
Train... [epoch 49/50, loss 0.9715, accuracy 0.7047]: 100%|██████████| 12/12 [00:15<00:00,  1.27s/it]
Train... [epoch 50/50, loss 0.7050, accuracy 0.7855]: 100%|██████████| 12/12 [00:15<00:00,  1.33s/it]

绘制训练曲线

plt.plot(range(len(train_loss_list)), train_loss_list)
plt.xlabel("epoch")
plt.ylabel("loss_val")
plt.show()

plot

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

综合实验---基于卷积神经网络的目标分类案例

文章目录 配置环境猫狗数据分类建模猫狗分类的实例基准模型猫狗分类的实例基准模型之数据增强问题回答 配置环境 ①首先打开 cmd&#xff0c;创建虚拟环境。 conda create -n tf1 python3.6如果报错&#xff1a;‘conda’ 不是内部或外部命令,也不是可运行的程序 或批处理文件…

[github-100天机器学习]day1 data preprocessing

https://github.com/LiuChuang0059/100days-ML-code/blob/master/Day1_Data_preprocessing/README.md#step-6-feature-scaling—特征缩放 数据预处理 数据帧(Data Frame) 二维的表格形式&#xff0c;类似于电子表格或关系型数据库中的表。数据帧通常被用来存储和操作结构化数据…

科技项目验收测试报告有什么注意事项和疑惑?

科技项目验收测试报告是一份重要的文件&#xff0c;用于评估科技项目的质量和可靠性&#xff0c;对项目的成功交付具有关键作用。在项目完成的最后阶段&#xff0c;通过对项目进行全面测试和评估&#xff0c;以确保项目符合预期的目标和需求&#xff0c;并满足用户的期望。 一…

3D深度视觉与myCobot 320机械臂无序抓取

今天我记录使用myCobot320 M5跟FS820-E1深度相机进行一个无序抓取物体的分享。 为什么会选择深度相机和机械臂做一个案例呢&#xff1f; 2D相机&#xff08;最常见使用的相机&#xff09;可以捕捉二维图像&#xff0c;也就是在水平和垂直方向上的像素值。它们通常用于拍摄静态…

卷积神经网络--猫狗系列【VGG16】

数据集&#xff1a;【文末】 ​ 数据集预处理 定义读取数据辅助类&#xff08;继承torch.utils.data.Dataset&#xff09; import osimport PILimport torchimport torchvisionimport matplotlib.pyplot as pltimport torch.utils.dataimport PIL.Image # 数据集路径train_p…

nohup命令解决SpringBoot/java -jar命令启动项目运行一段时间自动停止问题

问题描述&#xff1a; 在centos7上部署多个springcloud项目。出现了服务莫名其妙会挂掉一两个的问题&#xff0c;重新启动挂掉的服务之后又会出现其他服务挂掉的情况&#xff0c;查看启动日志也并没有发现有异常抛出。令人费解的是所有的服务都是通过nohup java -jar xxx.jar …

强化学习路径优化:基于Q-learning算法的机器人路径优化(MATLAB)

一、强化学习之Q-learning算法 Q-learning算法是强化学习算法中的一种&#xff0c;该算法主要包含&#xff1a;Agent、状态、动作、环境、回报和惩罚。Q-learning算法通过机器人与环境不断地交换信息&#xff0c;来实现自我学习。Q-learning算法中的Q表是机器人与环境交互后的…

图像视频基础

图像视频基础 文章目录 图像视频基础图像颜色深度分辨率 视频帧率比特率帧类型 YUV模型色度子采样 图像 颜色深度 存储颜色的强度&#xff0c;需要占用一定大小的数据空间&#xff0c;这个大小被称为颜色深度。假如每个颜色的强度占用 8 bit&#xff08;取值范围为 0 到 255&…

nginx+tomcat负载均衡和动静分离

目录 1.部署nginx 2.部署两台tomcat 3.配置nginx 1.部署nginx vim /vim/lib/systemd/system/nginx.service 2.部署两台tomcat 进入第一台装第一个tomcat vim /etc/profile vim /usr/local/tomcat/webapps/test/index.jsp 重启 进入第二台安装第二台tomcat vim /usr/local/tom…

(0021) H5-Vuejs配合 mint-ui 开发移动端web

mint-ui 初衷 element-ui主打pcweb&#xff0c;导致移动端上UI适配问题突出&#xff0c;趟了很多坑。这次更加理智些&#xff0c;选择了饿了么团队的主打移动端的mint-ui&#xff0c;目前来说体验很好。 认识Mint-ui 首先在手机上体验其demo&#xff0c;扫描链接&#xff1a;…

在 Jetpack Compose 中创建 Drawer

Jetpack Compose 是一个现代的构建 Android UI 的工具集&#xff0c;它使得构建 UI 变得更加简单快速。在本篇博客中&#xff0c;我们将讨论如何在 Jetpack Compose 中创建 Drawer&#xff0c;也就是我们常见的侧边抽屉。 什么是 Drawer&#xff1f; Drawer 是一个提供导航选项…

基于Transformer视觉分割综述

基于Transformer视觉分割综述 SAM &#xff08;Segment Anything &#xff09;作为一个视觉的分割基础模型&#xff0c;在短短的 3 个月时间吸引了很多研究者的关注和跟进。如果你想系统地了解 SAM 背后的技术&#xff0c;并跟上内卷的步伐&#xff0c;并能做出属于自己的 SAM…

GC回收器演进之路

目录 未来演进方向 历经之路 引用计数法 标记清除法 复制法 标记整理 分代式 三色标记法的诞生 三色标记法的基本概念 产生的问题 问题 1&#xff1a;浮动垃圾 问题 2&#xff1a;对象消失 遍历对象图不需要 STW 的解决方案 屏障机制 插入屏障&#xff08;Dijks…

Autosar诊断系列介绍17 - 物理寻址及功能寻址详解

本文框架 前言1. 物理寻址及功能寻址基本概念1.1物理寻址及功能寻址-定义1.2两种寻址方式区别1.3不同诊断服务寻址方式配置 2.不同寻址方式的应用场景 前言 UDS&#xff08;Unified Diagnostic Services&#xff09;协议&#xff0c;即统一的诊断服务&#xff0c;是面向整车所…

基于SQLI的SQL字符型报错注入

基于SQLI的SQL字符型报错注入 一. 实验目的 理解数字型报错SQL注入漏洞点的定位方法&#xff0c;掌握利用手工方式完成一次完整SQL注入的过程&#xff0c;熟悉常见SQL注入命令的操作。 二. 实验环境 渗透主机&#xff1a;KALI平台 用户名: college 密码: 360College 目标网…

JAVA麻将胡牌算法深度解析

目录 麻将的基本概念 麻将牌的构成 麻将的碰&#xff0c;杠&#xff0c;吃&#xff0c;听&#xff0c;胡 麻将胡牌条件 胡牌算法简介 选将拆分法 算法数据结构 构建数据结构 数据结构使用 牌花色的获取 获取某一花色的牌值 获取某一张牌相邻牌 算法代码实现 基础代…

Web3.0 应用开发:选择合适的框架和工具至关重要

随着 Web3.0 时代的到来&#xff0c;区块链技术的普及和应用让去中心化的应用开发变得更加可行。然而&#xff0c;要开发出高效、稳定和安全的 Web3.0 应用&#xff0c;选择合适的框架和工具至关重要。本文将介绍 Web3.0 应用开发的关键因素&#xff0c;帮助开发者做出明智的选…

Hive Metastore 表结构

Hive MetaStore 的ER 图如下。 部分表结构和说明。 CTLGS(CATALOGS) catalogs 可以隔离元数据。默认只有1行。一个 CATALOG 可以有多个数据库。 mysql> DESC CTLGS; -------------------------------------------------------- | Field | Type | Null |…

海康明眸设备SDK二次开发NET_DVR_SetupAlarmChan_V41老是报109错误

请仔细阅读图2中的文件&#xff0c;这里详细介绍了怎么样 放置DLL&#xff0c;务必按照图3中的说明步骤进行放置。HCNetSDKCom文件夹一定也要拷贝到debug目录&#xff0c;否则就会出现类似于109的错误提示。

NR 吞吐量测试

前言 参考文档&#xff1a; 5G NR TBS (Transport Block size) Calculator | 5G-Tools.com 5G NR Transport Block Size (TBS) Calculation - Techplayon 5G MCS _ 搜索结果_哔哩哔哩_Bilibili 4/5G无线资源和数据调度流程:CQI上报、基站AMC调度、调度信息DCI下发、CQI到MCS的对…