【深度学习】 UNet详解
UNet 是一种经典的卷积神经网络(Convolutional Neural Network, CNN)架构,专为生物医学图像分割任务设计。该模型于 2015 年由 Olaf Ronneberger 等人在论文《U-Net: Convolutional Networks for Biomedical Image Segmentation》中首次提出,因其卓越的性能和简单的结构,迅速成为图像分割领域的重要模型
1. 环境搭建
1.1 安装 Python 和相关工具
-
安装 Python 3.8 及以上版本
如果尚未安装 Python,可以从 Python官网 下载并安装。确保安装时勾选“Add Python to PATH”选项。 -
安装虚拟环境管理工具
虚拟环境是管理 Python 项目依赖的好方法。可以使用venv
或conda
来创建虚拟环境。我们这里使用venv
,步骤如下:# 创建虚拟环境 python -m venv unet_env# 激活虚拟环境 source unet_env/bin/activate # Linux/Mac unet_env\Scripts\activate # Windows
1.2 安装依赖库
-
安装 PyTorch
根据你的硬件选择正确的 PyTorch 版本。如果你的电脑支持 CUDA(GPU 加速),可以使用带 CUDA 的版本,否则使用 CPU 版本:# 安装支持 CUDA 11.8 版本的 PyTorch pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118# 如果不支持 CUDA,则使用以下命令: pip install torch torchvision torchaudio
-
安装其他依赖
你还需要一些其他的辅助库:pip install numpy opencv-python matplotlib tqdm scikit-learn pillow
2. 下载或实现 UNet 模型
2.1 UNet 模型结构详解
UNet 是经典的图像分割网络,其主要特点是由编码器(下采样部分)和解码器(上采样部分)组成。通过跳跃连接,编码器的每一层都将特征图传递到解码器对应层,以保持细节信息。
以下是 UNet 的详细实现,包含编码器、解码器、跳跃连接以及卷积操作:
import torch
import torch.nn as nn
import torch.nn.functional as Fclass UNet(nn.Module):def __init__(self, in_channels, out_channels):super(UNet, self).__init__()# 编码器部分self.encoder1 = self.conv_block(in_channels, 64)self.encoder2 = self.conv_block(64, 128)self.encoder3 = self.conv_block(128, 256)self.encoder4 = self.conv_block(256, 512)# 底部瓶颈部分self.bottleneck = self.conv_block(512, 1024)# 解码器部分self.upconv4 = self.upconv(1024, 512)self.decoder4 = self.conv_block(1024, 512)self.upconv3 = self.upconv(512, 256)self.decoder3 = self.conv_block(512, 256)self.upconv2 = self.upconv(256, 128)self.decoder2 = self.conv_block(256, 128)self.upconv1 = self.upconv(128, 64)self.decoder1 = self.conv_block(128, 64)# 输出层self.output = nn.Conv2d(64, out_channels, kernel_size=1)def conv_block(self, in_channels, out_channels):"""标准的卷积模块,包含两个卷积层和ReLU激活函数"""return nn.Sequential(nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1),nn.ReLU(inplace=True),nn.Conv2d(out_channels, out_channels, kernel_size=3, padding=1),nn.ReLU(inplace=True))def upconv(self, in_channels, out_channels):"""上采样操作,采用转置卷积(反卷积)"""return nn.ConvTranspose2d(in_channels, out_channels, kernel_size=2, stride=2)def forward(self, x):"""前向传播"""# 编码器:下采样enc1 = self.encoder1(x)enc2 = self.encoder2(F.max_pool2d(enc1, 2))enc3 = self.encoder3(F.max_pool2d(enc2, 2))enc4 = self.encoder4(F.max_pool2d(enc3, 2))# 底部瓶颈bottleneck = self.bottleneck(F.max_pool2d(enc4, 2))# 解码器:上采样 + 跳跃连接dec4 = self.upconv4(bottleneck)dec4 = torch.cat((dec4, enc4), dim=1) # 跳跃连接dec4 = self.decoder4(dec4)dec3 = self.upconv3(dec4)dec3 = torch.cat((dec3, enc3), dim=1)dec3 = self.decoder3(dec3)dec2 = self.upconv2(dec3)dec2 = torch.cat((dec2, enc2), dim=1)dec2 = self.decoder2(dec2)dec1 = self.upconv1(dec2)dec1 = torch.cat((dec1, enc1), dim=1)dec1 = self.decoder1(dec1)return self.output(dec1)
3. 数据处理
3.1 数据集准备
为了训练 UNet,你需要准备一个图像分割数据集。数据集通常由原始图像(RGB 图像)和每个图像对应的标注图像(Mask)组成。
假设我们有一个目录结构:
dataset/
├── train/
│ ├── images/
│ └── masks/
├── val/
│ ├── images/
│ └── masks/
每个 images
文件夹包含训练图像,而 masks
文件夹包含对应的标注图像。
3.2 数据加载器
在 PyTorch 中,我们可以通过 Dataset
类来自定义数据加载器。以下是一个简单的 SegmentationDataset
类:
import os
import cv2
import torch
from torch.utils.data import Datasetclass SegmentationDataset(Dataset):def __init__(self, image_dir, mask_dir, transform=None):self.image_dir = image_dirself.mask_dir = mask_dirself.transform = transformself.images = os.listdir(image_dir)def __len__(self):return len(self.images)def __getitem__(self, idx):img_path = os.path.join(self.image_dir, self.images[idx])mask_path = os.path.join(self.mask_dir, self.images[idx])# 读取图像和标签image = cv2.imread(img_path)mask = cv2.imread(mask_path, cv2.IMREAD_GRAYSCALE)# 应用任何数据增强(如有)if self.transform:augmented = self.transform(image=image, mask=mask)image = augmented['image']mask = augmented['mask']# 转换为 Tensor,通道数放到最前面return torch.tensor(image, dtype=torch.float32).permute(2, 0, 1), torch.tensor(mask, dtype=torch.long)
4. 训练模型
4.1 定义训练过程
我们将训练一个 UNet 模型,使用交叉熵损失函数和 Adam 优化器。训练时,输入的图像和标签将通过 DataLoader 加载。
from torch.utils.data import DataLoader
from torch.optim import Adam
from torch.nn import CrossEntropyLoss# 超参数
LEARNING_RATE = 1e-4
BATCH_SIZE = 8
EPOCHS = 20
DEVICE = "cuda" if torch.cuda.is_available() else "cpu"# 数据加载
train_dataset = SegmentationDataset("dataset/train/images", "dataset/train/masks")
train_loader = DataLoader(train_dataset, batch_size=BATCH_SIZE, shuffle=True)# 初始化模型与优化器
model = UNet(in_channels=3, out_channels=2).to(DEVICE) # 假设是二分类
optimizer = Adam(model.parameters(), lr=LEARNING_RATE)
criterion = CrossEntropyLoss()# 训练过程
for epoch in range(EPOCHS):model.train()for images, masks in train_loader:images, masks = images.to(DEVICE), masks.to(DEVICE)optimizer.zero_grad()# 前向传播outputs = model(images)# 计算损失loss = criterion(outputs, masks)# 反向传播loss.backward()# 更新参数optimizer.step()print(f"Epoch [{epoch+1}/{EPOCHS}], Loss: {loss.item():.4f}")
5. 模型推理
5.1 保存与加载模型
# 保存模型
torch.save(model.state_dict(), "unet_model.pth")# 加载模型
model.load_state_dict(torch.load("unet_model.pth"))
model.eval()
5.2 单张图片推理
def predict(model, image_path):image = cv2.imread(image_path)image = torch.tensor(image, dtype=torch.float32).permute(2, 0, 1).unsqueeze(0)with torch.no_grad():output = model(image)return output.argmax(dim=1).squeeze(0).numpy()
6. 模型优化与改进
为了提高 UNet 的性能,我们可以从以下几个方面进行优化:
6.1 数据增强
在训练过程中引入数据增强技术可以提高模型的泛化能力。使用 Albumentations
库可以实现多种增强方式,例如旋转、翻转、裁剪等:
import albumentations as A
from albumentations.pytorch import ToTensorV2transform = A.Compose([A.Resize(256, 256), # 调整尺寸A.HorizontalFlip(p=0.5), # 随机水平翻转A.VerticalFlip(p=0.5), # 随机垂直翻转A.RandomRotate90(p=0.5), # 随机旋转90度A.Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)), # 标准化ToTensorV2() # 转为 Tensor
])# 在数据集初始化时传入 transform
train_dataset = SegmentationDataset("dataset/train/images", "dataset/train/masks", transform=transform)
6.2 学习率调度器
动态调整学习率可以提高收敛速度。可以使用 PyTorch 提供的学习率调度器,例如 StepLR
或 ReduceLROnPlateau
:
from torch.optim.lr_scheduler import ReduceLROnPlateauscheduler = ReduceLROnPlateau(optimizer, mode='min', factor=0.5, patience=3)for epoch in range(EPOCHS):model.train()epoch_loss = 0for images, masks in train_loader:images, masks = images.to(DEVICE), masks.to(DEVICE)optimizer.zero_grad()outputs = model(images)loss = criterion(outputs, masks)loss.backward()optimizer.step()epoch_loss += loss.item()# 更新学习率scheduler.step(epoch_loss / len(train_loader))print(f"Epoch [{epoch+1}/{EPOCHS}], Loss: {epoch_loss / len(train_loader):.4f}")
6.3 混合精度训练
使用混合精度训练可以加速训练并减少显存使用,特别是在 GPU 上。PyTorch 提供了 torch.cuda.amp
模块来实现:
from torch.cuda.amp import GradScaler, autocastscaler = GradScaler()for epoch in range(EPOCHS):model.train()for images, masks in train_loader:images, masks = images.to(DEVICE), masks.to(DEVICE)optimizer.zero_grad()# 自动混合精度with autocast():outputs = model(images)loss = criterion(outputs, masks)# 反向传播与优化scaler.scale(loss).backward()scaler.step(optimizer)scaler.update()
6.4 Dice Loss 或 IoU Loss
交叉熵损失适合分类任务,但在分割任务中,Dice Loss 或 IoU Loss 能更好地处理类别不平衡问题:
class DiceLoss(nn.Module):def __init__(self):super(DiceLoss, self).__init__()def forward(self, preds, targets, smooth=1):preds = torch.sigmoid(preds) # 将输出限制在 [0, 1] 之间preds = preds.view(-1)targets = targets.view(-1)intersection = (preds * targets).sum()dice = (2. * intersection + smooth) / (preds.sum() + targets.sum() + smooth)return 1 - dice
然后在训练中替换损失函数:
criterion = DiceLoss()
6.5 模型改进:加入注意力机制
可以在 UNet 的跳跃连接中加入注意力机制(如 Squeeze-and-Excitation 或 Attention Gates),以提升模型对目标区域的关注能力。
以下是一个基于 SE 模块的示例:
class SEBlock(nn.Module):def __init__(self, in_channels, reduction=16):super(SEBlock, self).__init__()self.global_pool = nn.AdaptiveAvgPool2d(1)self.fc = nn.Sequential(nn.Linear(in_channels, in_channels // reduction),nn.ReLU(inplace=True),nn.Linear(in_channels // reduction, in_channels),nn.Sigmoid())def forward(self, x):batch, channels, _, _ = x.size()y = self.global_pool(x).view(batch, channels)y = self.fc(y).view(batch, channels, 1, 1)return x * y
将 SEBlock 插入 UNet 的编码器和解码器中。
7. 模型评估
为了评估模型性能,通常需要计算一些分割任务的指标,例如:
- 像素精度 (Pixel Accuracy)
- IoU (Intersection over Union)
- Dice 系数
以下是计算 IoU 和 Dice 系数的代码:
def compute_metrics(preds, labels):preds = preds > 0.5 # 阈值化intersection = (preds & labels).sum()union = (preds | labels).sum()iou = intersection / uniondice = (2 * intersection) / (preds.sum() + labels.sum())return iou, dice
在验证集上运行:
model.eval()
with torch.no_grad():for images, masks in val_loader:images, masks = images.to(DEVICE), masks.to(DEVICE)outputs = model(images)preds = torch.sigmoid(outputs) > 0.5 # 二值化预测iou, dice = compute_metrics(preds.cpu(), masks.cpu())print(f"IoU: {iou:.4f}, Dice: {dice:.4f}")
8. 部署与推理加速
8.1 导出 ONNX
将模型导出为 ONNX 格式以便在推理加速框架中使用:
dummy_input = torch.randn(1, 3, 256, 256).to(DEVICE)
torch.onnx.export(model, dummy_input, "unet_model.onnx", opset_version=11)
8.2 使用 TensorRT 加速推理
可以使用 NVIDIA TensorRT 对 ONNX 模型进行优化并加速推理。具体操作请参考 TensorRT 文档。
相关文章:
【深度学习】 UNet详解
UNet 是一种经典的卷积神经网络(Convolutional Neural Network, CNN)架构,专为生物医学图像分割任务设计。该模型于 2015 年由 Olaf Ronneberger 等人在论文《U-Net: Convolutional Networks for Biomedical Image Segmentation》中首次提出&…...
“深入浅出”系列之算法篇:(2)openCV、openMV、openGL
OpenCV是一个的跨平台计算机视觉库,可以运行在Linux囚、Windows 和Mac OS操作系统上。它轻量级而且高效,由一系列 C函数和少量C类构成,同时也提供了Python 接口,实现了图像处理和计算机视觉方面的很多通用算法。 OpenMV是一个开源,低成本&am…...
低代码系统-产品架构案例介绍、得帆云(八)
产品名称 得帆云DeCode低代码平台-私有化 得帆云DeMDM主数据管理平台 得帆云DeCode低代码平台-公有云 得帆云DePortal企业门户 得帆云DeFusion融合集成平台 得帆云DeHoop数据中台 名词 概念 云原生 指自己搭建的运维平台,区别于阿里云、腾讯云 Dehoop 指…...
web3py+flask+ganache的智能合约教育平台
最近在学习web3的接口文档,使用web3pyflaskganache写了一个简易的智能合约教育平台,语言用的是python,ganche直接使用的本地区块链网络,用web3py进行交互。 代码逻辑不难,可以私信或者到我的闲鱼号夏沫mds获取我的代码…...
(长期更新)《零基础入门 ArcGIS(ArcMap) 》实验六----流域综合处理(超超超详细!!!)
流域综合处理 流域综合治理是根据流域自然和社会经济状况及区域国民经济发展的要求,以流域水流失治理为中心,以提高生态经济效益和社会经济持续发展为目标,以基本农田优化结构和高效利用及植被建设为重点,建立具有水土保持兼高效生态经济功能的半山区流域综合治理模式。数字高程…...
基于 WPF 平台使用纯 C# 实现动态处理 json 字符串
一、引言 在当今的软件开发领域,数据的交换与存储变得愈发频繁,JSON(JavaScript Object Notation)作为一种轻量级的数据交换格式,以其简洁、易读、便于解析和生成的特点,被广泛应用于各种应用程序中。在 W…...
DRF开发避坑指南01
在当今快速发展的Web开发领域,Django REST Framework(DRF)以其强大的功能和灵活性成为了众多开发者的首选。然而,错误的使用方法不仅会导致项目进度延误,还可能影响性能和安全性。本文将从我个人本身遇到的相关坑来给大…...
WordPress免费证书插件
为了在您的网站上启用HTTPS,您可以使用本插件快速获取Let’s Encrypt免费证书。 主要功能: 支持快速申请Let’s Encrypt免费证书支持通配符证书申请,每个证书最多可以绑定100个域名支持自动续期证书支持重颁发证书,证书过期或失…...
MongoDB平替数据库对比
背景 项目一直是与实时在线监测相关,特点数据量大,读写操作大,所以选用的是MongoDB。但按趋势来讲,需要有一款国产数据库可替代,实现信创要求。选型对比如下 1. IoTDB 这款是由清华大学主导的开源时序数据库&#x…...
ANSYS学习笔记(十)网格质量的诊断和提高
网格质量的好坏不能单纯只看meshing给出的网格质量结果,要根据实际的计算物理场景来判断,需要求解的地方物理量大梯度的位置网格越密越好。 网格质量:在有限网格数量限制下,离散误差小的网格是好网格,是高质量网格。网…...
能量提升法三:赞美
前情回顾: 《能量提升法二:感恩》 片段:“感恩,就像是在跟世界说:谢谢你,我收到了,我很喜欢,请多来点” 把它归还人海,就当作每一个人,都有可能是曾经帮助…...
C++中函数返回值当引用
文章目录 一、概述二、返回值当引用的基本语法三、返回局部变量的引用四、返回引用的常见用途五、返回右值引用六、总结 一、概述 在 C 中,函数返回值当引用(即返回引用)是一个常见的编程技巧。它可以让你返回一个函数内部的局部变量或对象的…...
27. C语言 强制类型转换详解
本章目录: 前言强制类型转换(Type Casting)强制类型转换的语法示例1:将整数转换为浮点数输出结果: 代码解析: 整数提升(Integer Promotion)示例2:整数提升输出结果: 代码…...
Linux 命令之技巧(Tips for Linux Commands)
Linux 命令之技巧 简介 Linux 是一种免费使用和自由传播的类Unix操作系统,其内核由林纳斯本纳第克特托瓦兹(Linus Benedict Torvalds)于1991年10月5日首次发布。Linux继承了Unix以网络为核心的设计思想,是一个性能稳定的多用户…...
freeswitch在centos上编译过程
操作系统:centos9-last usr/local/freeswitch/bin/freeswitch -version FreeSWITCH version: 1.10.13-devgit~20250125T131725Z~3f1e4bf90a~64bit (git 3f1e4bf 2025-01-25 13:17:25Z 64bit)vi /etc/ssh/sshd_config ip a nmtui reboot ip a curl -o /etc/pki/rpm-…...
快速入门Flink
Flink是新一代实时计算平台,采用原生的流处理系统,保证了低延迟性,在API和容错上也是做的相当完善,本文将从架构、组件栈、安装、入门程序等进行基础知识的分析,帮助大家快速对Flink有一个了解。 一.简介 1.是什么 Ap…...
c++ list
1.构造函数 构造函数 // list<T> lst; // list(beg, end); // 区间构造 // list(n, elem); // 元素构造 // list(const list &lst); // 拷贝构造#include <iostream> #include <fstream> #include <string> #include <list> using name…...
Vue 3 + TypeScript 实现父子组件协同工作案例解析
引言 在现代的前端开发中,Vue.js 作为一款流行的渐进式 JavaScript 框架,为我们构建交互式用户界面提供了强大的支持。Vue 3 的推出带来了许多新特性,尤其是组合式 API 的引入,让代码的组织和复用更加灵活。同时,TypeS…...
深度剖析C++17中的std::optional:处理可能缺失值的利器
文章目录 一、基本概念与设计理念二、构建与初始化(一)默认构造(二)值初始化(三)使用std::make_optional(四)使用std::nullopt 三、访问值(一)value()&#x…...
【ArcGIS微课1000例】0141:提取多波段影像中的单个波段
文章目录 一、波段提取函数二、加载单波段导出问题描述:如下图所示,img格式的时序NDVI数据有24个波段。现在需要提取某一个波段,该怎样操作? 一、波段提取函数 首先加载多波段数据。点击【窗口】→【影像分析】。 选择需要处理的多波段影像,点击下方的【添加函数】。 在多…...
一分钟搭建promehteus+grafana+alertmanager监控平台
为什么要自己搭建一个监控平台 平时进行后端开发,特别是微服务的后端可开发,一定少不了对接监控平台,但是平时进行一些小功能的测试又没有必要每次都手动安装那么多软件进行一个小功能的测试,这里我使用docker-compose搭建了一个…...
Transfoemr的解码器(Decoder)与分词技术
在自然语言处理(NLP)领域,解码器(Decoder)和分词技术是两个至关重要的概念。解码器是序列生成任务的核心组件,而分词则是将文本数据转换为可处理形式的基础步骤。 一、解码器(Decoder&…...
LeetCode100之在排序数组中查找元素的第一个和最后一个位置(34)--Java
1.问题描述 给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。 如果数组中不存在目标值 target,返回 [-1, -1]。 你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题 示例1 输入…...
数字人+展厅应用方案:开启全新沉浸式游览体验
随着人们生活质量的不断提升,对于美好体验的追求日益增长。在展厅展馆领域,传统的展示方式已难以满足大众日益多样化的需求。而通过将数字人与展厅进行深度结合,可以打造数字化、智能化新型展厅,不仅能提升展示效果,还…...
echo ‘export PATH=/usr/local/bin:$PATH‘ >> ~/.bashrc这个和直接添加到/etc/profile有什么区别
echo export PATH/usr/local/bin:$PATH >> ~/.bashrc 和直接添加到 /etc/profile 都是用于修改 PATH 环境变量,但它们适用的范围和效果有所不同: 1. 修改 ~/.bashrc 文件 作用范围:~/.bashrc 是针对当前用户的配置文件,它…...
kafka消费者详细介绍(超级详细)
文章目录 一、Kafka 消费者与消费者组1.1 Kafka 消费者(Consumer)概述1.1.1 消费者工作流程1.1.2 消费者的关键配置 1.2 Kafka 消费者组(Consumer Group)概述1.2.1 消费者组的工作原理1.2.2 消费者组的优点1.2.3 消费者组的再均衡…...
《剪映5.9官方安装包》免费自动生成字幕
(避免失效建议存自己网盘后下载)剪映5.9官方Win.Mac 链接:https://pan.xunlei.com/s/VOHc-Fg2XRlD50MueEaOOeW1A1?pwdawtt# 官方唯一的免费版,Win和Mac都有,此版本官方已下架,觉得有用可转存收藏…...
CAS是什么?ABA会带来什么影响?怎么解决ABA问题?
前言 在高并发开发中,CAS(比较并交换)是一种常用的无锁操作,因其高效性而被广泛应用。然而,实际工作中常会遇到ABA问题,导致数据更新异常或逻辑错误。理解CAS的原理及ABA问题的解决方法,有助于…...
智能调度体系与自动驾驶技术优化运输配送效率的研究——兼论开源AI智能名片2+1链动模式S2B2C商城小程序的应用潜力
摘要:随着全球化和数字化进程的加速,消费者需求日益呈现出碎片化和个性化的趋势,这对物流运输行业提出了前所未有的挑战。传统的物流调度体系与调度方式已难以满足当前复杂多变的物流需求,因此,物流企业必须积极引入大…...
方豆子(递归)
方豆子 思路:很典的一道递归题,但当时没想到怎么递归/(ㄒoㄒ)/~~。赛后看了大佬的讲解知道要将这个图形看成由四个小正方形组成的大正方形,递归参数可以设置成(r1,c1,r2,c2,good)表示正方形的左上角坐标和右下角坐标以及当前这个正…...
Go语言入门指南(二): 数据类型
文章创作不易,麻烦大家点赞关注转发一键三连。 在上一篇文章,我们已经完成了开发环境的搭建,成功创建了第一个“Hello, World”程序,并且对变量的声明和初始化有了初步的认识。在这篇文章中,我们将主要介绍Go语言的数据…...
Django ORM解决Oracle表多主键的问题
现状 以Django 3.2为例 Django ORM 设计为默认使用单一主键(通常是自增的 id 字段),这一选择主要基于以下核心原因: 简化ORM设计与操作 统一访问方式外键关联简化 避免歧义冲突 主键语义明确防止隐式依赖 性能与数据库兼容 索引…...
学习数据结构(2)空间复杂度+顺序表
1.空间复杂度 (1)概念 空间复杂度也是一个数学表达式,表示一个算法在运行过程中根据算法的需要额外临时开辟的空间。 空间复杂度不是指程序占用了多少bytes的空间,因为常规情况每个对象大小差异不会很大,所以空间复杂…...
实验一---典型环节及其阶跃响应---自动控制原理实验课
一 实验目的 1.掌握典型环节阶跃响应分析的基本原理和一般方法。 2. 掌握MATLAB编程分析阶跃响应方法。 二 实验仪器 1. 计算机 2. MATLAB软件 三 实验内容及步骤 利用MATLAB中Simulink模块构建下述典型一阶系统的模拟电路并测量其在阶跃响应。 1.比例环节的模拟电路 提…...
从零推导线性回归:最小二乘法与梯度下降的数学原理
欢迎来到我的主页:【Echo-Nie】 本篇文章收录于专栏【机器学习】 本文所有内容相关代码都可在以下仓库中找到: Github-MachineLearning 1 线性回归 1.1 什么是线性回归 线性回归是一种用来预测和分析数据之间关系的工具。它的核心思想是找到一条直…...
OpenSIPS-从安装部署开始认识一个组件
前期讲到了Kamailio,它是一个不错的开源SIP(Session Initiation Protocol)服务器,主要用于构建高效的VoIP(Voice over IP)平台以及即时通讯服务。但是在同根同源(OpenSER)的分支上&a…...
数据结构(树)
每一个节点包含:父节点地址 值 左子节点地址 右子节点地址 如果一个节点不含有:父节点地址或左子节点地址 右子节点地址就记为null 二叉树 度:每一个节点的子节点数量 二叉树中,任意节点的度<2 树的结构: 二叉查…...
[Dialog屏幕开发] 设置搜索帮助
阅读该篇文章之前,可先阅读下述资料 [Dialog屏幕开发] 屏幕绘制(使用向导创建Tabstrip Control标签条控件)https://blog.csdn.net/Hudas/article/details/145372195?spm1001.2014.3001.5501https://blog.csdn.net/Hudas/article/details/145372195?spm1001.2014.…...
C语言从入门到进阶
视频:https://www.bilibili.com/video/BV1Vm4y1r7jY?spm_id_from333.788.player.switch&vd_sourcec988f28ad9af37435316731758625407&p23 //枚举常量 enum Sex{MALE,FEMALE,SECRET };printf("%d\n", MALE);//0 printf("%d\n", FEMALE…...
Node.js下载安装及环境配置教程 (详细版)
Node.js:是一个基于 Chrome V8 引擎的 JavaScript 运行时,用于构建可扩展的网络应用程序。Node.js 使用事件驱动、非阻塞 I/O 模型,使其非常适合构建实时应用程序。 Node.js 提供了一种轻量、高效、可扩展的方式来构建网络应用程序࿰…...
Mac Electron 应用签名(signature)和公证(notarization)
在MacOS 10.14.5之后,如果应用没有在苹果官方平台进行公证notarization(我们可以理解为安装包需要审核,来判断是否存在病毒),那么就不能被安装。当然现在很多人的解决方案都是使用sudo spctl --master-disable,取消验证模式&#…...
redis安装 windows版本
下载 github下载5.x版本redis 安装以及启动 解压文件,目标如下 进入cmd至安装路径 执行如下命令启动redis redis-server.exe redis.windows.conf 进入redis,另外启动cmd在当前目录执行进入redis 服务 redis-cli 测试命令 至此安装成功,但是这只是…...
关联传播和 Python 和 Scikit-learn 实现
文章目录 一、说明二、什么是 Affinity Propagation。2.1 先说Affinity 传播的工作原理2.2 更多细节2.3 传播两种类型的消息2.4 计算责任和可用性的分数2.4.1 责任2.4.2 可用性分解2.4.3 更新分数:集群是如何形成的2.4.4 估计集群本身的数量。 三、亲和力传播的一些…...
若依基本使用及改造记录
若依框架想必大家都了解得不少,不可否认这是一款及其简便易用的框架。 在某种情况下(比如私活)使用起来可谓是快得一匹。 在这里小兵结合自身实际使用情况,记录一下我对若依框架的使用和改造情况。 一、源码下载 前往码云进行…...
c语言网 1127 尼科彻斯定理
原题 题目描述 验证尼科彻斯定理,即:任何一个整数m的立方都可以写成m个连续奇数之和。 输入格式 任一正整数 输出格式 该数的立方分解为一串连续奇数的和 样例输入 13 样例输出 13*13*132197157159161163165167169171173175177179181 #include<ios…...
能说说MyBatis的工作原理吗?
大家好,我是锋哥。今天分享关于【Redis为什么这么快?】面试题。希望对大家有帮助; 能说说MyBatis的工作原理吗? MyBatis 是一款流行的持久层框架,它通过简化数据库操作,帮助开发者更高效地与数据库进行交互。MyBatis…...
卡特兰数学习
1,概念 卡特兰数(英语:Catalan number),又称卡塔兰数,明安图数。是组合数学中一种常出现于各种计数问题中的数列。它在不同的计数问题中频繁出现。 2,公式 卡特兰数的递推公式为:f(…...
【算法】多源 BFS
多源 BFS 1.矩阵距离2.刺杀大使 单源最短路问题 vs 多源最短路问题 当问题中只存在一个起点时,这时的最短路问题就是单源最短路问题。当问题中存在多个起点而不是单一起点时,这时的最短路问题就是多源最短路问题。 多源 BFS:多源最短路问题…...
解锁数字经济新动能:探寻 Web3 核心价值
随着科技的快速发展,我们正迈入一个全新的数字时代,Web3作为这一时代的核心构成之一,正在为全球数字经济带来革命性的变革。本文将探讨Web3的核心价值,并如何推动数字经济的新动能。 Web3是什么? Web3,通常…...
CAN总线数据采集与分析
CAN总线数据采集与分析 目录 CAN总线数据采集与分析1. 引言2. 数据采集2.1 数据采集简介2.2 数据采集实现 3. 数据分析3.1 数据分析简介3.2 数据分析实现 4. 数据可视化4.1 数据可视化简介4.2 数据可视化实现 5. 案例说明5.1 案例1:数据采集实现5.2 案例2࿱…...