PyTorch深度学习实战(44)——基于 DETR 实现目标检测

PyTorch深度学习实战(44)——基于 DETR 实现目标检测

    • 0. 前言
    • 1. Transformer
      • 1.1 Transformer 基础
      • 1.2 Transformer 架构
    • 2. DETR
      • 2.1 DETR 架构
      • 2.2 实现 DETR 模型
    • 3. 基于 DETR 实现目标检测
      • 3.1 数据加载与模型构建
      • 3.2 模型训练与测试
    • 小结
    • 系列链接

0. 前言

在使用 R-CNN/YOLO 执行目标检测时,利用区域提议/锚框完成目标分类和检测,这些方法通常需要多个步骤流程才能完成目标检测任务。 DETR (Detection Transformer) 是一种基于 Transformer 技术的端到端的管道,可极大的简化目标检测网络架构。Transformer 是在 NLP 中较为流行的技术之一,可以用于执行多种任务和最新的技术之一。在本节中,我们将学习 transformerDETR 的原理,并使用 PyTorch 实现 DETR 以执行目标检测任务。

1. Transformer

1.1 Transformer 基础

Transformer 是用于解决序列到序列问题的高性能架构,当前几乎所有自然语言处理 (Natural Language Processing, NLP) 任务都是基于 Transformer 实现的。这类网络仅使用全连接层和 softmax 创建自注意力机制,自注意力有助于识别输入文本中单词之间的相互依赖关系。输入序列通常不超过 2048 个项,这对于文本应用而言已经足够大了。但是,如果将图像与 Transformer 一起使用,则必须将它们展平,这会创建包含数百万像素的序列(例如 300 x 300 x 3 图像包含 270000 个像素),这并不可行。 为了解决这一限制,可以将尺寸远小于输入图像的特征图作为 Transformer 的输入。

1.2 Transformer 架构

Transformer 的核心是自注意力模块,它以三个二维矩阵(称为查询 (query, Q)、键 (key, K) 和值 (value, V) 矩阵)作为输入,这些矩阵可以具有较大的嵌入大小,矩阵尺寸为 text size x embedding size,其中 text size 表示文本大小,embedding size 表示嵌入大小,因此首先将它们分成较小的部分(多头自注意力图中的步骤 1),然后缩放点积注意力(多头自注意力图中的步骤 2)进行处理。
接下来,通过以下示例了解自注意力的工作原理。假设,序列长度为 3,将三个词嵌入( W 1 W_1 W1 W 2 W_2 W2 W 3 W_3 W3 )作为输入,假设每个嵌入的大小为 512。每个嵌入都被转换为三个附加向量,即与每个输入相对应的查询 (query)、键 (key) 和值 (value) 向量:

计算流程

由于每个向量的大小为 512,因此执行矩阵乘法的计算成本很高。因此,我们将每个向量分成八个部分,每个键、查询和值张量都具有八组 (64 x 3) 向量,其中 64 表示 512 (嵌入大小)/8 (多头注意力数),而 3 表示序列长度:

计算流程

在每个部分中,首先对键和查询矩阵执行矩阵乘法,得到一个 3 x 3 矩阵,然后执行 softmax 激活函数,得到的矩阵用于表示每个单词相对于其他单词的重要性:

计算流程
最后,对以上张量输出与值张量执行矩阵乘法,得到自注意力操作输出:

输出

然后组合在上一步中得到的八个输出,使用 concat 层返回(多头自注意图中的步骤 3),最终得到一个大小为 512 x 3 的张量。由于对 QKV 矩阵进行了拆分,因此该层也称为多头自注意力:

多头自注意力
此架构核心思想如下:

  • 值 ( V s V_s Vs) 是需要在键和查询矩阵的上下文中为给定输入进行学习处理的嵌入
  • 查询 ( Q s Q_s Qs) 和键 ( K s K_s Ks) 的组合会创建正确的掩码,以便只有值矩阵的重要部分被输入到下一层

在计算机视觉中,当搜索诸如马之类的对象时,查询应包含用于搜索尺寸较大且通常为棕色、黑色或白色的对象信息。缩放点积注意力的 softmax 输出反映键矩阵中图像中包含图像颜色(棕色、黑色、白色等)的部分。因此,自注意力层输出的值将具有大致符合所需颜色且在值矩阵中的图像部分。
在网络中多次使用自注意力模块,如下图所示。Transformer 网络包含一个编码网络(下图左侧部分),其输入是源序列。编码部分的输出用于解码部分的键和查询输入,而值输入则会独立于编码部分由神经网络进行学习:

Transformer架构

尽管是一个输入序列,但全连接层没有位置指示,无法确定哪个分词(单词)是第一个,哪个是下一个。位置编码是可学习的嵌入(或硬编码向量),将其添加到每个输入中,将其作为序列中每个输入的位置函数,以便让网络了解哪个单词嵌入在序列中是第一个,哪个是第二个。
PyTorch 中可以使用内置方法 nn.Transformer 很方便的创建 Transformer 网络:

from torch import nn
transformer = nn.Transformer(hidden_dim, nheads, num_encoder_layers, num_decoder_layers)

其中,hidden_dim 是嵌入大小,nheads 是多头自注意力中的头数,num_encoder_layersnum_decoder_layers 分别是网络中编码和解码块的数量。

2. DETR

2.1 DETR 架构

普通 Transformer 网络和 DETR 之间有少数几个关键区别。首先,DETR 输入是图像,而不是序列,DETR 将图像通过 ResNet 主干网络传递,获得大小为 256 的特征向量,然后可以将其视为一个序列。在目标检测任务中,解码器的输入是对象查询嵌入 (object-query embeddings),它们是在训练期间自动学习的,作为解码器层的查询矩阵。类似的,对于每一层,键矩阵和查询矩阵都将为编码器块的最终输出矩阵。Transformer 的最终输出张量形状为 Batch_Size x 100 x Embedding_Size,其中模型训练时的序列长度为 100;也就是说,它学习了 100 个对象查询嵌入,并为每张图像返回 100 个向量,以指示是否存在对象。将大小为 100 x Embedding_Size 的矩阵分别馈送到对象分类模块和对象回归模块,用于独立预测图像中是否存在对象(以及对象类别)以及边界框坐标,两个模块均为简单的 nn.Linear 层。
DETR 的整体架构如下:

DETR架构

2.2 实现 DETR 模型

接下来,使用 PyTorch 实现一个较小规模的 DETR 变体版本。

创建 DETR 模型类:

from collections import OrderedDict
class DETR(nn.Module):def __init__(self,num_classes,hidden_dim=256,nheads=8, num_encoder_layers=6, num_decoder_layers=6):super().__init__()self.backbone = resnet50()

提取 ResNet 中的指定网络层,并丢弃其余部分,选取的网络层名称以列表形式给出:

        layers = OrderedDict()for name,module in self.backbone.named_modules():if name in ['conv1','bn1','relu','maxpool', 'layer1','layer2','layer3','layer4']:layers[name] = moduleself.backbone = nn.Sequential(layers)self.conv = nn.Conv2d(2048, hidden_dim, 1)self.transformer = nn.Transformer(hidden_dim, nheads, num_encoder_layers, num_decoder_layers)self.linear_class = nn.Linear(hidden_dim, num_classes + 1)self.linear_bbox = nn.Linear(hidden_dim, 4)

在以上代码中,定义了以下内容:

  • 按顺序排列的感兴趣的网络层 (self.backbone)
  • 卷积操作 (self.conv)
  • Transformer 模块 (self.transformer)
  • 用于预测目标类别的全连接层 (self.linear_class)
  • 用于预测边界框的全连接层 (self.linear_box)

定义编码器和解码器层的位置嵌入:

        self.query_pos = nn.Parameter(torch.rand(100, hidden_dim))self.row_embed = nn.Parameter(torch.rand(50, hidden_dim // 2))self.col_embed = nn.Parameter(torch.rand(50, hidden_dim // 2))

self.query_pos 是解码器层的位置嵌入输入,而 self.row_embedself.col_embed 则形成编码器层的二维位置嵌入。

定义前向计算方法 forward

    def forward(self, inputs):x = self.backbone(inputs)h = self.conv(x)H, W = h.shape[-2:]pos = torch.cat([self.col_embed[:W].unsqueeze(0).repeat(H, 1, 1),self.row_embed[:H].unsqueeze(1).repeat(1, W, 1),], dim=-1).flatten(0, 1).unsqueeze(1)h = self.transformer(pos+0.1*h.flatten(2).permute(2, 0, 1), self.query_pos.unsqueeze(1)).transpose(0, 1)return {'pred_logits': self.linear_class(h), 'pred_boxes': self.linear_bbox(h).sigmoid()}

加载在 COCO 数据集上训练的预训练模型,并将其用于预测通用类别,也可以在此模型上使用相同的函数进行预测:

detr = DETR(num_classes=91)
state_dict = torch.hub.load_state_dict_from_url(url='detr_demo-da2a99e9.pth',map_location='cpu', check_hash=True)
detr.load_state_dict(state_dict)
detr.eval()

R-CNNYOLO 等模型相比,DETR 可以一次性获取预测,DETR 详细架构如下:

DETR架构
使用主干网络获取图像特征,然后通过编码器将图像特征与位置嵌入连接起来。

__init__ 方法中位置嵌入 self.row_embedself.col_embed 用于对图像中各种对象的位置信息进行编码。编码器将位置嵌入和图像特征连接起来作为输入,在 forward 方法中获得隐藏状态向量 h,然后将其作为解码器的输入。Transformer 的输出进一步传递到两个全连接网络中,一个用于目标对象识别,一个用于边界框回归。
模型训练过程使用 Hungarian 损失,它负责将对象识别为一个集合并惩罚冗余预测,这完全消除了对非最大抑制的需求。
解码器采用编码器隐藏状态向量和对象查询的组合。对象查询的工作方式与位置嵌入/锚框类似,可以生成五个预测结果,其中一个用于预测对象类别,另外四个用于预测对象边界框。

3. 基于 DETR 实现目标检测

在本节中,我们将使用 PyTorch 实现 DETR 网络执行目标检测,识别公共汽车与卡车并在图中绘制边界框,所用数据集与 R-CNN 一节中相同。

3.1 数据加载与模型构建

首先,在 Github 下载 DETR 项目 detr,并下载权重文件 detr-r50-e632da11.pth。

然后,下载并解压数据集后,按照 DETR 所需 COCO 数据集格式调整文件结构:

$ cp open-images-bus-trucks/annotations/mini_open_images_train_coco_format.json open-images-bus-trucks/annotations/instances_train2017.json
$ cp open-images-bus-trucks/annotations/mini_open_images_val_coco_format.json open-images-bus-trucks/annotations/instances_val2017.json
$ ln -s open-images-bus-trucks/images/ open-images-bus-trucks/train2017
$ ln -s open-images-bus-trucks/images/ open-images-bus-trucks/val2017

3.2 模型训练与测试

(1) 使用下载完成的 DETR 模型与 open-images-bus-trucks 文件夹中的图像和标注信息训练模型:

$ cd detr
$ python main.py --coco_path open-images-bus-trucks --epochs 15 --lr=1e-4 --batch_size=2 --num_workers=4 --output_dir="outputs" --resume="detr-r50-e632da11.pth"

(2) 训练模型并保存后,在测试阶段可以直接从文件夹中加载模型:

import os
import torch
from matplotlib import pyplot as plt
from torch import nn, optim
from torch import functional as F
from torchvision import transforms as T
import random
from glob import glob
import shutil
from main import get_args_parser, argparse, build_modelCLASSES = ['', 'BUS','TRUCK']parser = argparse.ArgumentParser('DETR training and evaluation script', parents=[get_args_parser()])
args, _ = parser.parse_known_args()model, _, _ = build_model(args)
model.load_state_dict(torch.load("outputs/checkpoint.pth")['model'])

(2) 对预测结果进行后处理,获取图像和包围对象的边界框:

COLORS = [[0.000, 0.447, 0.741], [0.850, 0.325, 0.098], [0.929, 0.694, 0.125],[0.494, 0.184, 0.556], [0.466, 0.674, 0.188], [0.301, 0.745, 0.933]]transform = T.Compose([T.Resize(800),T.ToTensor(),T.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])# for output bounding box post-processing
def box_cxcywh_to_xyxy(x):x_c, y_c, w, h = x.unbind(1)b = [(x_c - 0.5 * w), (y_c - 0.5 * h),(x_c + 0.5 * w), (y_c + 0.5 * h)]return torch.stack(b, dim=1)def rescale_bboxes(out_bbox, size):img_w, img_h = sizeb = box_cxcywh_to_xyxy(out_bbox)b = b * torch.tensor([img_w, img_h, img_w, img_h], dtype=torch.float32)return bdef detect(im, model, transform):img = transform(im).unsqueeze(0)assert img.shape[-2] <= 1600 and img.shape[-1] <= 1600, 'demo model only supports images up to 1600 pixels on each side'outputs = model(img)# keep only predictions with 0.7+ confidenceprobas = outputs['pred_logits'].softmax(-1)[0, :, :-1]keep = probas.max(-1).values > 0.7# convert boxes from [0; 1] to image scalesbboxes_scaled = rescale_bboxes(outputs['pred_boxes'][0, keep], im.size)return probas[keep], bboxes_scaleddef plot_results(pil_img, prob, boxes):plt.figure(figsize=(16,10))plt.imshow(pil_img)ax = plt.gca()for p, (xmin, ymin, xmax, ymax), c in zip(prob, boxes.tolist(), COLORS * 100):ax.add_patch(plt.Rectangle((xmin, ymin), xmax - xmin, ymax - ymin,fill=False, color=c, linewidth=3))cl = p.argmax()text = f'{CLASSES[cl]}: {p[cl]:0.2f}'ax.text(xmin, ymin, text, fontsize=15,bbox=dict(facecolor='yellow', alpha=0.5))plt.axis('off')plt.show()

(3) 预测测试图像:

for _ in range(20):image = Image.open(random.choice(glob('../open-images-bus-trucks/images/*'))).resize((800,800)).convert('RGB')scores, boxes = detect(image, model, transform)plot_results(image, scores, boxes)

模型预测

从上图可以看出,训练后模型能够预测图像中对象。虽然在此简单示例中检测的准确率可能不是非常高。但是,可以将此方法扩展到大型数据集来提高模型性能。

小结

基于 DETR (Detection Transformer) 的目标检测模型是将 Transformer 网络引入目标检测任务中,与传统的基于区域提议的检测方法有所不同。DETR 模型的核心思想是将目标检测问题转化为集合预测问题,通过将图像中的所有位置视为一个集合,并通过 Transformer 完成对整个集合的编码和解码过程,从而在单个前向传递中直接预测出目标的类别和边界框。

系列链接

PyTorch深度学习实战(1)——神经网络与模型训练过程详解
PyTorch深度学习实战(2)——PyTorch基础
PyTorch深度学习实战(3)——使用PyTorch构建神经网络
PyTorch深度学习实战(4)——常用激活函数和损失函数详解
PyTorch深度学习实战(5)——计算机视觉基础
PyTorch深度学习实战(6)——神经网络性能优化技术
PyTorch深度学习实战(7)——批大小对神经网络训练的影响
PyTorch深度学习实战(8)——批归一化
PyTorch深度学习实战(9)——学习率优化
PyTorch深度学习实战(10)——过拟合及其解决方法
PyTorch深度学习实战(11)——卷积神经网络
PyTorch深度学习实战(12)——数据增强
PyTorch深度学习实战(13)——可视化神经网络中间层输出
PyTorch深度学习实战(14)——类激活图
PyTorch深度学习实战(15)——迁移学习
PyTorch深度学习实战(16)——面部关键点检测
PyTorch深度学习实战(17)——多任务学习
PyTorch深度学习实战(18)——目标检测基础
PyTorch深度学习实战(19)——从零开始实现R-CNN目标检测
PyTorch深度学习实战(20)——从零开始实现Fast R-CNN目标检测
PyTorch深度学习实战(21)——从零开始实现Faster R-CNN目标检测
PyTorch深度学习实战(22)——从零开始实现YOLO目标检测
PyTorch深度学习实战(23)——从零开始实现SSD目标检测
PyTorch深度学习实战(24)——使用U-Net架构进行图像分割
PyTorch深度学习实战(25)——从零开始实现Mask R-CNN实例分割
PyTorch深度学习实战(26)——多对象实例分割
PyTorch深度学习实战(27)——自编码器(Autoencoder)
PyTorch深度学习实战(28)——卷积自编码器(Convolutional Autoencoder)
PyTorch深度学习实战(29)——变分自编码器(Variational Autoencoder, VAE)
PyTorch深度学习实战(30)——对抗攻击(Adversarial Attack)
PyTorch深度学习实战(31)——神经风格迁移
PyTorch深度学习实战(32)——Deepfakes
PyTorch深度学习实战(33)——生成对抗网络(Generative Adversarial Network, GAN)
PyTorch深度学习实战(34)——DCGAN详解与实现
PyTorch深度学习实战(35)——条件生成对抗网络(Conditional Generative Adversarial Network, CGAN)
PyTorch深度学习实战(36)——Pix2Pix详解与实现
PyTorch深度学习实战(37)——CycleGAN详解与实现
PyTorch深度学习实战(38)——StyleGAN详解与实现
PyTorch深度学习实战(39)——小样本学习(Few-shot Learning)
PyTorch深度学习实战(40)——零样本学习(Zero-Shot Learning)
PyTorch深度学习实战(41)——循环神经网络与长短期记忆网络
PyTorch深度学习实战(42)——图像字幕生成
PyTorch深度学习实战(43)——手写文本识别

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

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

相关文章

自动驾驶---Control之LQR控制

1 前言 在前面的系列博客文章中为读者阐述了很多规划相关的知识&#xff08;可参考下面专栏&#xff09;&#xff0c;本篇博客带领读者朋友们了解控制相关的知识&#xff0c;后续仍会撰写规控相关文档。 在控制理论的发展过程中&#xff0c;人们逐渐认识到对于线性动态系统的控…

视频封面:如何用前端实现视频帧截图

在这样一个图像化极其重要的时代&#xff0c;从视频中提取精彩瞬间&#xff0c;即视频帧截图的技术&#xff0c;已成为前端开发中的一个亮点。JavaScript作为网页动态效果和交互的主力军&#xff0c;其在视频处理领域能力逐渐被挖掘和重视&#xff0c;尤其是视频帧截图技术的应…

一键实现文件重命名:巧妙运用随机大写字母命名,复制新文件名,轻松管理文件库!

我们的电脑里总是堆积着各种各样的文件。无论是工作文档、生活照片还是学习资料&#xff0c;这些文件都承载着我们的回忆和辛勤努力。然而&#xff0c;随着时间的推移&#xff0c;文件名的混乱和重复逐渐成为我们管理文件的难题。为了解决这一困扰&#xff0c;我们推出了一款创…

09.爬虫---正则解析爬取数据

09.正则解析爬取数据 1.目标网站2.具体实现3.正则表达式分析4.完整代码并存入表格 1.目标网站 直达目标网站 https://movie.douban.com/chart 2.具体实现 我们来拿取一下上面网页的代码如下: from urllib import requesturl https://movie.douban.com/chart headers {Us…

解决 DBeaver 查询时不刷新数据,需要重新连接才会刷新,有缓存一样

DBeaver 查询时总是第一次有数据&#xff0c;再次执行查询数据不会刷新&#xff0c;像是有缓存一样&#xff0c;需要重新连接再查询才会刷新&#xff0c;知道肯定是哪里设置的不对&#xff0c;但是一直没找到&#xff0c;实在是重连太烦了&#xff0c;多次尝试终于找到了设置。…

【数据结构】从前序与中序遍历,或中序与后序遍历序列,构造二叉树

欢迎浏览高耳机的博客 希望我们彼此都有更好的收获 感谢三连支持&#xff01; 首先&#xff0c;根据先序遍历可以确定根节点E&#xff0c;再在中序遍历中通过E确定左树和右数 &#xff1b; 设立inBegin和inEnd&#xff0c;通过这两个参数的游走&#xff0c;来进行子树的创建&a…

ApiJson简单使用

前言 最近在正式迭代中插入了一个大屏演示项目&#xff0c;因为后端开发人员任务都安排满了&#xff0c;而演示项目逻辑比较简单&#xff0c;大多是直接查表就能搞定&#xff0c;所以只能想办法让前端直接和数据库交互&#xff0c;增加开发速度。在找工具时发现了ApiJson。尝试…

详解redis单线程设计思路

写在文章开头 我们都知道redis是一个基于单线程实现高效网络IO和键值对读写操作的内存数据库,本文将从源码的角度剖析一下redis高效的单线程设计。 Hi,我是 sharkChili ,是个不断在硬核技术上作死的 java coder ,是 CSDN的博客专家 ,也是开源项目 Java Guide 的维护者之一…

一键生成迷宫-Word插件-大珩助手新功能

Word大珩助手是一款功能丰富的Office Word插件&#xff0c;旨在提高用户在处理文档时的效率。它具有多种实用的功能&#xff0c;能够帮助用户轻松修改、优化和管理Word文件&#xff0c;从而打造出专业而精美的文档。 【新功能】迷宫生成器 1、可自定义迷宫大小&#xff1b; …

topK 问题

topK 问题 topK二、实验内容三、数据结构设计四、算法设计五、运行结果六、程序源码 topK &#xff08;1&#xff09;实验题目 topK 问题 &#xff08;2&#xff09;问题描述 从大批量数据序列中寻找最大的前 k 个数据&#xff0c;比如从 10 万个数据中&#xff0c;寻找最大的…

论文阅读《SELECTIVE DOMAIN-INVARIANT FEATURE FOR GENERALIZABLE DEEPFAKEDETECTION》

作者&#xff1a;Yingxin Lai、 Guoqing Yang1、Yifan He2、Zhiming Luo、Shaozi Li 期刊&#xff1a;ICASSP-2024 目的&#xff1a;解决泛化性的问题&#xff0c;提出了3个模块 论文整体的架构图&#xff1a;&#xff08;挑选域特征不变&#xff0c;减少对图像内容或者风格…

Java面试八股之怎么降低锁竞争

怎么降低锁竞争 减少锁的持有时间&#xff1a; 尽量缩短线程持有锁的时间&#xff0c;只在必要时才获取锁&#xff0c;一旦操作完成立即释放锁。可以通过将同步代码块的范围缩小到最小必要程度来实现&#xff0c;避免在锁保护的代码块中执行耗时操作或等待操作&#xff0c;比如…

HTML+CSS+JS 选项卡导航栏

效果演示 实现了一个导航栏切换内容的效果。页面上方有一个导航栏,每个导航项都有一个圆形背景,点击导航项时,圆形背景会放大并显示对应的内容。每个内容区域都包含一个大号字母,数字会在内容区域显示时淡入。点击其他导航项时,当前内容区域会淡出并隐藏,同时新的内容区域…

Docker 基础使用(2) 镜像与容器

文章目录 镜像的含义镜像的构成镜像的作用镜像的指令容器的含义容器的状态容器的指令 Docker 基础使用&#xff08;0&#xff09;基础认识 Docker 基础使用 (1) 使用流程概览 Docker 基础使用&#xff08;2&#xff09; 镜像与容器 Docker 基础使用&#xff08;3&#xff09; 存…

【热点】老黄粉碎摩尔定律被,量产Blackwell解决ChatGPT耗电难题

6月3日&#xff0c;老黄又高调向全世界秀了一把&#xff1a;已经量产的Blackwell&#xff0c;8年内将把1.8万亿参数GPT-4的训练能耗狂砍到1/350&#xff1b; 英伟达惊人的产品迭代&#xff0c;直接原地冲破摩尔定律&#xff1b;Blackwell的后三代路线图&#xff0c;也一口气被…

【动手学深度学习】多层感知机模型选择、欠拟合和过拟合研究详情

目录 &#x1f30a;1. 研究目的 &#x1f30a;2. 研究准备 &#x1f30a;3. 研究内容 &#x1f30d;3.1 多层感知机模型选择、⽋拟合和过拟合 &#x1f30d;3.2 基础练习 &#x1f30a;4. 研究体会 &#x1f30a;1. 研究目的 多层感知机模型选择&#xff1a;比较不同多层…

使用Python绘制南丁格尔图(玫瑰图)

使用Python绘制南丁格尔图&#xff08;玫瑰图&#xff09; 南丁格尔图效果代码 南丁格尔图 南丁格尔图&#xff08;Nightingale Rose Chart&#xff09;&#xff0c;也被称为玫瑰图或极区图&#xff0c;是一种特殊的圆形统计图&#xff0c;用于显示多个类别的数据。它是由弗洛…

基于聚类和回归分析方法探究蓝莓产量影响因素与预测模型研究

&#x1f31f;欢迎来到 我的博客 —— 探索技术的无限可能&#xff01; &#x1f31f;博客的简介&#xff08;文章目录&#xff09; 目录 背景数据说明数据来源思考 正文数据预处理数据读取数据预览数据处理 相关性分析聚类分析数据处理确定聚类数建立k均值聚类模型 多元线性回…

Codeforces Round 950 (Div. 3) 个人题解 (A~F1)

Codeforces Round 950 (Div. 3)个人题解(A~F1) 题解火车头 #define _CRT_SECURE_NO_WARNINGS 1#include <iostream> #include <vector> #include <algorithm> #include <set> #include <unordered_map> #include <cstring> #include <…

小程序集arcgis地图显示自定义坐标的功能实现记录!(学习笔记)

最近再做一个新能源回收项目&#xff0c;项目中有个根据回收点坐标数据显示区域内回收点位置&#xff0c;点击图标直接导航到该位置&#xff0c;及分布的需求&#xff0c;研究了一下&#xff0c;实现效果如下&#xff0c;实现起来很简单&#xff0c;代码及效果 回收点位置及分…