Pytorch学习笔记(十一)Learning PyTorch - What is torch.nn really
这篇博客瞄准的是 pytorch 官方教程中 Learning PyTorch
章节的 What is torch.nn really?
部分。主要是教你如何一步一步将最原始的代码进行重构至pytorch标准的代码,如果你已经熟悉了如何使用原始代码以及pytorch标准形式构建模型,可以跳过这一篇。
- 官网链接:https://pytorch.org/tutorials/beginner/nn_tutorial.html
完整网盘链接: https://pan.baidu.com/s/1L9PVZ-KRDGVER-AJnXOvlQ?pwd=aa2m 提取码: aa2m
What is torch.nn really?
PyTorch 提供了模块和类 torch.nn
、torch.optim
、Dataset
和 DataLoader
,以创建和训练神经网络。为了充分利用它们的强大功能并针对问题对其进行自定义,需要真正了解它们的作用。首先在 MNIST 数据集上训练基本神经网络;最初将仅使用最基本的 PyTorch Tensor功能。然后逐步从 torch.nn
、torch.optim
、Dataset
或 DataLoader
中添加一个特征,准确展示每个部分的作用以及它如何工作以使代码更简洁或更灵活。
MNIST data setup
- 官网链接: https://pytorch.org/tutorials/beginner/nn_tutorial.html#mnist-data-setup
这里使用经典的 MNIST 数据集,该数据集由手绘数字(0 到 9 之间)的黑白图像组成。使用 pathlib 来处理路径,并使用请求下载数据集。
准备本地环境
from pathlib import Path
import requestsDATA_PATH = Path("data")
PATH = DATA_PATH / "mnist"PATH.mkdir(parents=True, exist_ok=True)
下载MNIST数据
URL = "https://github.com/pytorch/tutorials/raw/main/_static/"
FILENAME = "mnist.pkl.gz"if not (PATH / FILENAME).exists():content = requests.get(URL + FILENAME).content(PATH / FILENAME).open("wb").write(content)
加载数据并编码
import pickle
import gzipwith gzip.open((PATH/FILENAME).as_posix(), "rb") as f:((x_train, y_train), (x_valid, y_valid), _) = pickle.load(f, encoding='latin-1')
抽看其中一张图像
from matplotlib import pyplot
import numpy as nppyplot.imshow(x_train[0].reshape((28,28)), cmap='gray')
pyplot.show()
print(x_train.shape)
将数据转换为tensor格式
import torchx_train, y_train, x_valid, y_valid = map(torch.tensor, (x_train, y_train, x_valid, y_valid)
)n, c = x_train.shape
print(x_train, y_train)
print(x_train.shape)
print(y_train.min(), y_train.max())
Neural net from scratch (without torch.nn)
首先,只使用 PyTorch Tensor操作创建一个模型。PyTorch 提供了创建随机或零填充Tensor的方法,使用这些方法为简单的线性模型创建权重和偏差,告诉 PyTorch 它们需要梯度,PyTorch 会记录对Tensor执行的所有操作,以便它可以在反向传播期间自动计算梯度。对于权重,在初始化后设置了 require_grad
,因为我们不希望该步骤包含在梯度中。
定义权重与偏置值
import mathweights = torch.randn(784, 10) / math.sqrt(784)
weights.requires_grad_()
bias = torch.zeros(10, requires_grad=True)
由于 PyTorch 能够自动计算梯度,可以使用任何标准 Python 函数作为模型,只需编写一个简单的矩阵乘法和广播加法即可创建一个简单的线性模型。还需要编写一个 log_softmax
激活函数。但尽管 PyTorch 提供了许多预先编写的损失函数、激活函数等,但仍然可以使用普通的 Python 编写自己的函数。PyTorch 甚至会自动为您的函数创建快速加速器或矢量化 CPU 代码。
自定义激活函数
def log_softmax(x):return x - x.exp().sum(-1).log().unsqueeze(-1)def model(xb):return log_softmax(xb @ weights + bias)
执行一次前向传播,前向传播计算得到的preds Tensor不仅包含value,还包含梯度函数。
batch_size = 64
xb = x_train[0:batch_size]
preds = model(xb)
print(preds[0], preds.shape)
定义损失函数
def nll(input, target):return -input[range(target.shape[0]), target].mean()loss_func = nll
计算一次损失
yb = y_train[0:batch_size]
print(loss_func(preds, yb))
定义用于计算模型正确率函数
def accuracy(out, yb):preds = torch.argmax(out, dim=1)return (preds == yb).float().mean()
计算正确率
accuracy(preds, yb)
执行训练循环
lr = 0.5
epochs = 2for epoch in range(epochs):for i in range((n-1)// batch_size + 1):# 抽取数据start_i = i * batch_sizeend_i = start_i + batch_sizexb = x_train[start_i:end_i]yb = y_train[start_i:end_i]# 执行推理pred = model(xb)loss = loss_func(pred, yb)# 反向传播loss.backward()with torch.no_grad():weights -= weights.grad * lrbias -= bias.grad * lrweights.grad.zero_()bias.grad.zero_()print(loss_func(model(xb), yb), accuracy(model(xb), yb))
Using torch.nn.functional
现在将重构代码使其与之前的功能相同,开始利用 PyTorch 的 nn
类使其更简洁、更灵活。
第一步将手写的激活和损失函数替换为来自 torch.nn. functional
的函数来缩短代码,此模块包含 torch.nn
库中的所有函数。除了各种损失和激活函数外,还可以在这里找到一些用于创建神经网络的便捷函数,例如pooling函数。 Pytorch 还提供了一个将负对数似然损失和对数 softmax 激活两者结合起来的单一函数 F.cross_entropy
。
import torch.nn.functional as Floss_func = F.cross_entropydef model(xb):return xb @ weights + biasprint(loss_func(model(xb), yb), accuracy(model(xb), yb))
Refactor using nn.Module
接下来使用 nn.Module
和 nn.Parameter
,以实现更清晰、更简洁的训练循环。创建一个类来保存权重、偏差和前向传播函数的方法。nn.Module
有许多将要使用的属性和方法(例如 .parameters()
和 .zero_grad()
)。
定义模型
from torch import nnclass Mnist_Logistic(nn.Module):def __init__(self):super().__init__()self.weights = nn.Parameter(torch.randn(784, 10) / math.sqrt(784))self.bias = nn.Parameter(torch.zeros(10))def forward(self, xb):return xb @ self.weights + self.biasmodel = Mnist_Logistic()
print(loss_func(model(xb), yb))
执行拟合
def fit():for epoch in range(epochs):for i in range((n-1)//batch_size + 1):start_i = i * batch_sizeend_i = start_i + batch_sizexb = x_train[start_i:end_i]yb = y_train[start_i:end_i]pred = model(xb)loss = loss_func(pred, yb)loss.backward()with torch.no_grad():for p in model.parameters():p -= p.grad * lrmodel.zero_grad()fit()
loss_func(model(xb), yb)
Refactor using nn.Linear
继续重构代码,不再手动定义和初始化 self.weights
和 self.bias
,也不再计算 xb @ self.weights + self.bias
,而是使用 Pytorch 类 nn.Linear
作为线性层。Pytorch 有许多类型的预定义层,可以大大简化代码,而且通常还可以加快速度。
定义模型
class Mnist_Logistic(nn.Module):def __init__(self):super().__init__()self.lin = nn.Linear(784, 10)def forward(self, xb):return self.lin(xb)
执行推理与拟合
model = Mnist_Logistic()
loss_func(model(xb), yb)fit()
loss_func(model(xb), yb)
Refactor using torch.optim
Pytorch 还有一个包含各种优化算法的包,torch.optim
。使用优化器中的 step
方法来实现自动参数更新。
定义模型与优化器
from torch import optimdef get_model():model = Mnist_Logistic()return model, optim.SGD(model.parameters(), lr=lr)model, optimizer = get_model()
print(loss_func(model(xb), yb))
执行拟合
for epoch in range(epochs):for i in range((n-1) // batch_size + 1):start_i = i * batch_sizeend_i = start_i + batch_sizexb = x_train[start_i:end_i]yb = y_train[start_i:end_i]pred = model(xb)loss = loss_func(pred, yb)loss.backward()optimizer.step()optimizer.zero_grad()print(loss_func(model(xb), yb))
Refactor using Dataset
PyTorch 有一个抽象的 Dataset
类。Dataset
可以是任何具有 __len__
和 __getitem__
函数作为索引方式的对象。这部分介绍如何创建自定义 FacialLandmarkDataset
类作为 Dataset
的子类。
PyTorch 的 TensorDataset
是一个包装Tensor的 Dataset
。通过定义长度和索引方式,提供了一种沿Tensor的第一维进行迭代、索引和切片的方法。这在训练时更容易在同一行中访问独立变量和因变量。
用Dataset
包装数据
from torch.utils.data import TensorDatasettrain_ds = TensorDataset(x_train, y_train)
执行拟合
model, optimizer = get_model()for epoch in range(epochs):for i in range((n-1) // batch_size + 1):xb, yb = train_ds[i*batch_size: i*batch_size+batch_size]pred = model(xb)loss = loss_func(pred, yb)loss.backward()optimizer.step()optimizer.zero_grad()print(loss_func(model(xb), yb))
Refactor using DataLoader
PyTorch 的 DataLoader
负责管理batch,可以从任何数据集创建 DataLoader
。DataLoader
使迭代变得更容易,无需使用 train_ds[i*bs : i*bs+bs]
,DataLoader
会自动提供每个小bacth。
定义Loader
from torch.utils.data import DataLoadertrain_ds = TensorDataset(x_train, y_train)
train_dl = DataLoader(train_ds, batch_size=batch_size)
执行拟合
model, optimizer = get_model()for epoch in range(epochs):for xb, yb in train_dl:pred = model(xb)loss = loss_func(pred, yb)loss.backward()optimizer.step()optimizer.zero_grad()print(loss_func(model(xb), yb))
Add validation
在实际的训练过程中终应该有一个验证集,以便确定是否过度拟合。打乱训练数据对于防止batch之间的相关性和过度拟合非常重要。另一方面,无论是否打乱验证集,验证损失都将相同。由于打乱需要额外的时间,因此打乱验证数据是没有意义的。
将使用比训练集大两倍的验证集batch size,因为验证集不需要反向传播,因此占用的内存更少(它不需要存储梯度)。
准备训练集、验证集的loader
train_ds = TensorDataset(x_train, y_train)
train_dl = DataLoader(train_ds, batch_size=batch_size)valid_ds = TensorDataset(x_valid, y_valid)
valid_dl = DataLoader(valid_ds, batch_size=batch_size*2)
执行拟合
model, optimizer = get_model()for epoch in range(epochs):model.train()for xb, yb in train_dl:pred = model(xb)loss = loss_func(pred, yb)loss.backward()optimizer.step()optimizer.zero_grad()model.eval()with torch.no_grad():valid_loss = sum(loss_func(model(xb), yb) for xb,yb in valid_dl)print(epoch, valid_loss / len(valid_dl))
Create fit() and get_data()
继续重构为训练集传递一个优化器,并使用它来执行反向传播。
定义一个batch的loss计算函数
def loss_batch(model, loss_func, xb, yb, opt=None):loss = loss_func(model(xb), yb)if opt is not None:loss.backward()opt.step()opt.zero_grad()return loss.item(), len(xb)
定义拟合函数
import numpy as npdef fit(epochs, model, loss_func, opt, train_dl, valid_dl):for epoch in range(epochs):# 模型训练模式model.train()for xb,yb in train_dl:loss_batch(model, loss_func, xb, yb, opt)# 模型验证模式model.eval()with torch.no_grad():losses, nums = zip(*[loss_batch(model, loss_func, xb, yb) for xb,yb in valid_dl])valid_loss = np.sum(np.multiply(losses, nums)) / np.sum(nums)print(epoch, valid_loss)def get_data(train_ds, valid_ds, bs):return (DataLoader(train_ds, batch_size=bs, shuffle=True),DataLoader(valid_ds, batch_size=bs * 2),)
执行拟合
train_dl, valid_dl = get_data(train_ds, valid_ds, batch_size)
model, optimizer = get_model()
fit(epochs, model, loss_func, optimizer, train_dl, valid_dl)
Switch to CNN
现在用三个卷积层构建神经网络,使用 PyTorch 的预定义 Conv2d
类作为卷积层。定义一个具有 3 个卷积层的 CNN,每个卷积后跟一个 ReLU。最后,执行平均池化。
定义模型
class Mnist_CNN(torch.nn.Module):def __init__(self):super().__init__()self.conv1 = nn.Conv2d(1, 16, kernel_size=3, stride=2, padding=1)self.conv2 = nn.Conv2d(16, 16, kernel_size=3, stride=2, padding=1)self.conv3 = nn.Conv2d(16, 10, kernel_size=3, stride=2, padding=1)def forward(self, xb):xb = xb.view(-1, 1, 28, 28)xb = F.relu(self.conv1(xb))xb = F.relu(self.conv2(xb))xb = F.relu(self.conv3(xb))xb = F.avg_pool2d(xb, 4)return xb.view(-1, xb.size(1))
执行拟合
model = Mnist_CNN()
opt = optim.SGD(model.parameters(), lr=lr, momentum=0.9)fit(epochs, model, loss_func, opt, train_dl, valid_dl)
Using nn.Sequential
torch.nn
还有另一个方便的类,可以使用它来简化代码:Sequential
。Sequential
对象以顺序方式运行其中包含的每个模块。使用Lambda
将创建一个view
层,然后用 Sequential
定义网络时使用它。
定义view层
class Lambda(nn.Module):def __init__(self, func):super().__init__()self.func = funcdef forward(self, x):return self.func(x)def preprocess(x):return x.view(-1, 1, 28, 28)
定义模型 & 优化器
model = torch.nn.Sequential(Lambda(preprocess),nn.Conv2d(1, 16, kernel_size=3, stride=2, padding=1), nn.ReLU(),nn.Conv2d(16, 16, kernel_size=3, stride=2, padding=1),nn.ReLU(),nn.Conv2d(16, 10, kernel_size=3, stride=2, padding=1),nn.ReLU(),nn.AvgPool2d(4),Lambda(lambda x: x.view(x.size(0), -1))
)
opt = optim.SGD(model.parameters(), lr=lr, momentum=0.9)
执行拟合
fit(epochs, model, loss_func, opt, train_dl, valid_dl)
Wrapping DataLoader
上面的 CNN 相当简洁,但它只适用于 MNIST,因为:
- 假设输入是一个 28*28 长的向量;
- 假设最终的 CNN 网格大小为 4*4(因为这是我们使用的平均池化内核大小)
这里要做的是让模型适用于任何 2d 单通道图像。通过将数据预处理移到生成器中来删除初始 Lambda 层:
def preprocess(x,y):return x.view(-1, 1, 28,28), yclass WrappedDataLoader:def __init__(self, dl, func) -> None:self.dl = dlself.func = funcdef __len__(self):return len(self.dl)def __iter__(self):for b in self.dl:yield (self.func(*b))
对dataloader进行修改
train_dl, valid_dl = get_data(train_ds, valid_ds, batch_size)train_dl = WrappedDataLoader(train_dl, preprocess)
valid_dl = WrappedDataLoader(valid_dl, preprocess)
定义模型
model = nn.Sequential(nn.Conv2d(1, 16, kernel_size=3, stride=2, padding=1),nn.ReLU(),nn.Conv2d(16, 16, kernel_size=3, stride=2, padding=1),nn.ReLU(),nn.Conv2d(16, 10, kernel_size=3, stride=2, padding=1),nn.ReLU(),nn.AdaptiveAvgPool2d(1),Lambda(lambda x: x.view(x.size(0), -1)),
)opt = optim.SGD(model.parameters(), lr=lr, momentum=0.9)
执行拟合
fit(epochs, model, loss_func, opt, train_dl, valid_dl)
Using your Accelerator
检查当前设备是否支持计算加速
device = torch.accelerator.current_accelerator().type if torch.accelerator.is_available() else 'cpu'
print(f"device {device}")
在预处理阶段将数据移动到加速设备上
def preprocess(x,y):return x.view(-1,1,28,28).to(device), y.to(device)train_dl, valid_dl = get_data(train_ds, valid_ds, batch_size)
train_dl = WrappedDataLoader(train_dl, preprocess)
valid_dl = WrappedDataLoader(valid_dl, preprocess)
将模型移动到加速设备上
model.to(device)
opt = optim.SGD(model.parameters(), lr=lr, momentum=0.9)
执行拟合
fit(epochs, model, loss_func, opt, train_dl, valid_dl)
Closing thoughts
总结一下这篇教程中的内容:
torch.nn
:Module
:创建一个被调用函数,可以包含状态(例如神经网络层权重)。并且可以将其所有梯度归零,循环遍历它们以更新权重等;Parameter
:Tensor的包装器,它告诉模块它具有在反向传播期间需要更新的权重,只有设置了require_grad
属性的Tensor才会更新;functional
:包含激活函数、损失函数等组件的子模块,以及卷积层和线性层等非状态版本的layer;
torch.optim
:包含优化器,在反向传播期间更新参数的权重;Dataset
:具有__len__
和__getitem__
的对象的抽象接口,包括 Pytorch 提供的类,例如 TensorDataset;DataLoader
:获取任何数据集并创建一个返回批量数据的迭代器;
相关文章:
Pytorch学习笔记(十一)Learning PyTorch - What is torch.nn really
这篇博客瞄准的是 pytorch 官方教程中 Learning PyTorch 章节的 What is torch.nn really? 部分。主要是教你如何一步一步将最原始的代码进行重构至pytorch标准的代码,如果你已经熟悉了如何使用原始代码以及pytorch标准形式构建模型,可以跳过这一篇。 …...
OpenGL ES 2.0与OpenGL ES 3.1的区别
如果硬件支持且需要更高质量的图形效果,推荐3.1;如果兼容性和开发简便更重要,且效果需求不高,2.0更合适。不过现代车载系统可能越来越多支持3.x版本,所以可能倾向于使用3.1,但具体情况还需调查目标平台的硬…...
【Unity3D脚本与系统设计6】鼠标触摸超时待机实现
实现步骤 在Unity中实现一个功能,当鼠标或触摸超过一定时间没有操作时,自动返回待机界面。 检测输入 首先,我需要检测用户的输入,无论是鼠标还是触摸。Unity的Input系统可以检测到鼠标和触摸事件,比如Input.GetAxis…...
SpringMVC 入门教程
一、SpringMVC 简介 SpringMVC 是基于 MVC 设计模式的轻量级 Web 框架,核心功能包括: 请求分发:通过 DispatcherServlet 统一处理请求。注解驱动:使用 Controller、RequestMapping 简化开发。视图解析:支持 JSP、Thy…...
矿山自动化监测解决方案
1.行业现状 为贯彻落实《中共中央国务院关于推进安全生产领域改革发展的意见》《“十四五”矿山安全生产规划》(应急〔2022〕64号)、《国务院安委会办公室关于加强矿山安全生产工作的紧急通知》(安委办〔2021〕3号)等有关工作部署…...
el-table + el-pagination 前端实现分页操作
el-table el-pagination 前端实现分页操作 后端返回全部列表数据,前端进行分页操作 html代码 <div><el-table :data"tableData" border><el-table-column label"序号" type"index" width"50" /><el…...
NIO ByteBuffer 总结
目录 基本概念创建 ByteBuffer核心属性关键方法切换模式读写操作压缩数据 基本概念 java.nio.ByteBuffer 是 Java NIO 中一个核心类, 用于高效处理二进制数据的读写操作。应用于通道(Channel)的I/O操作。作用: 数据缓冲…...
华为hcia——Datacom实验指南——配置IPv4静态路由,默认路由和浮动静态路由
什么是IPv4 IPv4静态路由,是手动配置的,不会随着网络拓扑的变化而变化,所配置的路由信息也不会在网络中传播,所以它主要运用在小型网络或者作为动态路由的补充。 IPv4的配置 配置的命令很简单 IP route-static (目…...
Git入门——常用指令汇总
以下是一份精心整理的 Git常用指令速查表,基本覆盖日常开发使用场景,建议收藏备用👇 🔧 环境配置 指令作用git config --global user.name "你的名字"设置全局用户名git config --global user.email "你的邮箱&qu…...
深入解析 MyBatis-Plus 批量操作:原理、实现与性能优化
引言 在高并发、大数据量场景下,批量数据库操作是提升系统性能的核心手段之一。本文以 MyBatis-Plus 为例,深入剖析 批量更新 和 自定义批量插入 的实现原理,并结合实战代码与性能测试,揭示其在高性能场景下的应用价值。 批量更新:动态 SQL 的极致运用 原理与 SQL 生成…...
2025年成都市双流区农业科技试验示范基地建设方案申报条件材料和补贴程序、时间安排
成都市双流区2025年农业科技试验示范基地建设方案申报条件材料和补贴程序、时间安排如下,需要申报的可指导! 一、成都市双流区农业科技试验示范基地申报 (一)基地建设数量。2025年建设农业科技试验示范基地2个。 (二…...
8路CXP相机采集系统介绍
8xCXP相机采集系统介绍 目录 1 系统概述 4 2 硬件架构 5 2.1 FPGA处理单元 5 2.2 CXP接口层 6 2.3 CXP相机说明与使用要求 7 2.4 SSI控制器板 8 3 FPGA方案 9 3.1 FPGA实现 9 3.2 Block Design说明 10 4 软件方案 14 4.1 嵌入式层 14 4.2 上位机软件(C…...
vue2前端日志数据存储,推荐(IndexedDB)
前言:首先,我得回忆一下IndexedDB的基本概念和用法,确保自己理解正确。IndexedDB是一个浏览器内置的数据库,允许存储大量结构化数据,支持事务和索引查询,适合需要离线存储的应用场景。 接下来,用…...
onedav一为导航批量自动化导入网址(完整教程)
OneNav作为一个功能强大的导航工具,支持后台管理、加密链接、浏览器书签批量导入等功能,能够帮助用户轻松打造专属的导航页面。今天,我将为大家详细介绍如何实现OneNav导航站的批量自动化导入网址。 1、建立要批量导入的表格 格局需要创建表格,表格的要求是一定要有需要,…...
Ubuntu Linux安装PyQt5并配置Qt Designer
一 安装 PyQt5 借助 apt 包管理器来安装 PyQt5 及其相关的开发工具: sudo apt install python3-pyqt5 pyqt5-dev-tools 假如报错, You might want to run apt --fix-broken install to correct these. 直接执行: sudo apt --fix-…...
无人机螺旋桨平衡标准
螺旋桨平衡是确保无人机(UAV)平稳运行、可靠性和使用寿命的关键过程。螺旋桨的不平衡会导致振动、噪音,并加速关键部件的磨损,从而对飞行性能产生负面影响。 ISO 21940-11:2016标准为旋翼平衡提供了一个广泛引用的框架,定义了可接受的不平衡…...
基于MCP协议的多模态模型优化在医疗3D打印精密人工关节制造中的研究
一、引言 1.1 研究背景与意义 在全球人口老龄化趋势愈发明显的当下,诸如骨关节炎、类风湿性关节炎这类关节疾病的发病率不断攀升,进而使得人工关节置换手术的需求呈现出激增态势。人工关节置换手术作为治疗终末期关节疾病的有效手段,能够显著缓解患者疼痛,提升关节功能与生…...
ESLint报错:Could not find config file.
如果你的ESLint的版本大于 8,同时使用 .eslinrc.js 和 .eslintignore 作为配置文件,且目前用的是 VSCODE ,就有可能遇到报错: Could not find config file. 这个是因为 VSCode 中 ESLint 插件的配置 eslint.useFlatConfig 的问题…...
npm install 卡在创建项目:sill idealTree buildDeps
参考: https://blog.csdn.net/PengXing_Huang/article/details/136460133 或者再执行 npm install -g cnpm --registryhttps://registry.npm.taobao.org 或者换梯子...
drizzleDumper:基于内存搜索的Android脱壳工具
一、工具介绍 drizzleDumper 是一款基于内存搜索的 Android 脱壳工具,主要用于从加固的 Android 应用程序中提取原始的 DEX 文件。它通过分析应用程序运行时的内存,定位并提取被加固的 DEX 文件,从而帮助开发者、安全研究人员进行逆向工程和…...
信号处理中的窗
窗函数(Window Function)是一种在信号处理中常用的工具,用于对信号进行截断和加权处理。它在频谱分析、滤波器设计以及信号处理的许多其他领域中都发挥着重要作用。 窗函数的基本概念 窗函数本质上是一个有限长度的序列,通常用于…...
FFmpeg学习:AVPacket结构体
1.AVPacket结构体 FFmpeg中用于封装一帧的编码数据的结构体(比如H264视频帧或者AAC音频帧),主要用于编解码过程中数据的载体,使用av_read_frame()读取获得,或者使用avcodec_send_packet()进行解码,与AVFra…...
34.[前端开发-JavaScript基础]Day11-王者轮播图-书籍购物车-BOM对象-JSON
1 认识BOM操作 认识BOM 2 全局对象window window对象 window对象的作用 window常见的属性 window常见的方法 3 事件对象event window常见的事件 4 location、history location对象常见的属性 Location对象常见的方法 URLSearchParams history对象常见属性和方法 5 navigato…...
FLEXlm如何通过web调用
FLEXlm 是一种流行的软件许可管理工具,广泛用于各种软件产品的授权管理。它支持多种协议,包括传统的服务器-客户端模式和一些基于网络的解决方案。如果你想通过 Web 接口调用 FLEXlm 许可证服务器,你可以通过以下几种方式实现: 使…...
深度解析Spring Boot可执行JAR的构建与启动机制
一、Spring Boot应用打包架构演进 1.1 传统JAR包与Fat JAR对比 传统Java应用的JAR包在依赖管理上存在明显短板,依赖项需要单独配置classpath。Spring Boot创新的Fat JAR(又称Uber JAR)解决方案通过spring-boot-maven-plugin插件实现了"…...
Zookeeper运维指南:服务端与客户端常用命令详解
#作者:任少近 文章目录 1 Zookeeper服务端常用命令2 Zookeeper客户端常用命令2.1Ls命令2.2创建节点create2.3Get命令2.4删除命令2.5修改命令 1 Zookeeper服务端常用命令 启动ZK服务: bin/zkServer.sh start # ./zkServer.sh startZooKeeper JMX enabled by defau…...
K8S学习之基础五十一:k8s部署jenkins
k8s部署jenkins 创建nfs共享目录, mkdir -p /data/v2 echo /data/v2 *(rw,no_root_squash) > /etc/exports exportfs -arv创建pv、pvc vi pv.yaml apiVersion: v1 kind: PersistentVolume metadata:name: jenkins-k8s-pv spec:capacity:storage: 1GiaccessMod…...
界面控件DevExpress WinForms v25.1 - 人工智能(AI)方面全新升级
DevExpress WinForms拥有180组件和UI库,能为Windows Forms平台创建具有影响力的业务解决方案。DevExpress WinForms能完美构建流畅、美观且易于使用的应用程序,无论是Office风格的界面,还是分析处理大批量的业务数据,它都能轻松胜…...
基于动态光影融合的缺陷实时检测和材质量化方法,并且整合EventPS、VMNer和EvDiG
要完成基于动态光影融合的缺陷实时检测和材质量化方法,并且整合EventPS、VMNer和EvDiG,是一个复杂且综合性的任务。以下是一个大致的实现步骤和代码示例,不过要完整完成论文和所有实验还需要大量的细化和调整。 整体思路 数据加载与预处理&…...
关于我对接了deepseek之后部署到本地将数据存储到mysql的过程
写在前面 今天写一下使用nodejs作为服务端,vue作为客户端,mysql的数据库,对接deepseek的全过程,要实现一个很简单的效果就是,可以自由的询问,然后可以将询问的过程存储到mysql的数据库中。 文档对接 deeps…...
Android 中两个 APK 之间切换的几中方法
在 Android 中,两个 APK(应用程序)之间的切换通常是通过 Intent 来实现的。以下是一些常见的方法和注意事项,帮助你实现两个 APK 之间的切换。 一、启动目标 APK 的主 Activity 1、setPackage 方法 使用 Intent 的 setPackage …...
【LeetCode 热题 100】解答汇总
一、哈希表 1. 两数之和 | python【简单】 49. 字母异位词分组 | python【中等】 128. 最长连续序列 | python【中等】 二、双指针 283. 移动零 | python【简单】 盛最多水的容器 三数之和 接雨水 三、滑动窗口 3. 无重复字符的最长子串 | python 【中等】 49. 字母异…...
【RAG综述系列】之 RAG 相关背景和基本原理
系列文章: 【RAG综述系列】之 RAG 相关背景和基本原理 【RAG综述系列】之 RAG 特点与挑战以及方法与评估 【RAG综述系列】之 RAG 先进方法与综合评估 【RAG综述系列】之 RAG 应用和未来方向 正文: 检索增强生成(Retrieval-Augmented Gen…...
Unity 开发休闲手游:M_Studio 实战指南,源码课件全解析
Unity 开发休闲手游:M_Studio 实战指南,源码课件全解析 在手游开发领域,Unity 引擎凭借其强大的跨平台能力和丰富的资源,成为众多开发者的首选。今天,我们深入探讨如何利用 Unity 开发休闲手机游戏,以 M_S…...
HTML5 新的 Input 类型学习笔记
HTML5 引入了多种新的表单输入类型,这些新特性不仅增强了输入控制,还提供了更强大的验证功能,使表单设计更加灵活和便捷。以下是 HTML5 新的 Input 类型的详细学习笔记。 一、color 类型 功能:用于选取颜色。 使用场景ÿ…...
【第23节】windows网络编程模型(WSAEventSelect模型)
目录 引言 一、WSAEventSelect模型概述 二、 WSAEventSelect模型的实现流程 2.1 创建一个事件对象,注册网络事件 2.2 等待网络事件发生 2.3 获取网络事件 2.4 手动设置信号量和释放资源 三、 WSAEventSelect模型伪代码示例 四、完整实践示例代码 引言 在网…...
C# 中实现 跨线程写入
方案核心思路 写入请求队列:使用 ConcurrentQueue 接收来自任意线程的写入请求。 专用写入线程:由独立线程处理队列中的写入操作,确保顺序执行。 双信号机制:通过 ManualResetEventSlim 控制读取线程的暂停与恢复。 线程安全确…...
联合体(Union)的使用与应用场景
引言 在 C/C++ 编程中,联合体(Union)是一个非常独特的数据结构。与结构体(struct)不同,联合体允许不同的数据类型共享同一块内存空间,从而节省内存。在许多需要高效内存管理的场景下,联合体的使用能够显著提高程序的性能与资源利用率。本文将从联合体的基本概念入手,…...
Spark2 之 Expression/Functions
ExpressionConverter src/main/scala/org/apache/gluten/expression/ExpressionConverter.scala TopNTransformer src/main/scala/org/apache/gluten/execution/TopNTransformer.scala...
【Mysql】SQL 优化全解析
文章目录 一、理解执行计划1.1 执行计划的作用1.2 查看执行计划 二、查询优化2.1 避免全表扫描2.2 使用覆盖索引2.3 合理使用 JOIN 三、索引优化3.1 索引设计原则3.2 索引维护 在数据驱动的当今时代,MySQL 作为应用广泛的开源关系型数据库&…...
谈谈对spring IOC的理解,原理和实现
一、IoC 核心概念 1. 控制反转(Inversion of Control) 传统编程中对象自行管理依赖(主动创建),而IoC将控制权转移给容器,由容器负责对象的创建、装配和管理,实现依赖关系的反向控制。 2. 依赖…...
Element UI实现表格全选、半选
制作如图所示的表格全选、半选: 父组件 <template><div id"app"><SelectHost :hostArray"hostArray" /></div> </template><script> import SelectHost from ./components/SelectHost.vue export default…...
Dify实现自然语言生成SQL并执行
目录 一、需求分析 二、解决思路 问题1:文字描述生成SQL语句 问题2:执行生成的SQL语句 完整解决方案 三、最终效果展示 四、具体实现 1.Agent提示词 2.知识库数据 3.sql执行器工作流创建 3.1 节点1 3.2 节点2 3.3 节点3 3.4 最终配置界面预…...
【leetcode hot 100 347】前 K 个高频元素
解法一:用map的value记录key出现的次数,用PriorityQueue构造最小堆。 class Solution {public int[] topKFrequent(int[] nums, int k) {// 把元素放在map中Map<Integer,Integer> map new HashMap<>();for(int num:nums){if(map.containsK…...
golang不使用锁的情况下,对slice执行并发写操作,是否会有并发问题呢?
背景 并发问题最简单的解决方案加个锁,但是,加锁就会有资源争用,提高并发能力其中的一个优化方向就是减少锁的使用。 我在之前的这篇文章《开启多个协程,并行对struct中的每个元素操作,是否会引起并发问题?》中讨论过多协程场景下struct的并发问题。 Go语言中的slice在…...
一文了解Gradle 依赖管理(五)- 依赖管理缓存依赖
文章目录 1. 版本目录 (Version Catalogs)1. 版本目录的概念与优势2. 主要优势3. 基本配置4. 使用版本目录5.使用外部版本目录文件6.实际项目中的版本目录最佳实践 2. 依赖锁定(Dependency Locking)1. 依赖锁定的概念与重要性2. 主要优势3. 如何启用依赖…...
如何在 Postman 中发送 PUT 请求?
在 Postman 中发送 PUT 请求的步骤相对简单,包括新建接口、选择 PUT 方法、填写 URL 和参数等几个主要步骤。 Postman 发送 put 请求教程...
Ubuntu20.04.6系统根目录扩容
文章目录 方法一:**1. 检查磁盘和分区情况****2. 扩展 vda3 分区****3. 扩展 LVM 物理卷****4. 扩展 LVM 逻辑卷****5. 扩展文件系统** 方法二:1. 查看当前磁盘分区情况2. 创建新分区3. 重新加载分区表4. 扩展物理卷(PV)5. 扩展逻辑卷&#x…...
《AI赋能SQL Server,数据处理“狂飙”之路》
在数字化浪潮汹涌的当下,企业的数据量犹如滚雪球般飞速增长。据统计,过去几年全球数据量的年增长率高达30%以上 ,海量数据如同双刃剑,既蕴含着无限商机,也给数据处理带来巨大挑战。SQL Server作为一款强大的关系型数据…...
c++ 日志框架G3log介绍及在嵌入式Linux上的移植(交叉编译)
在开发高性能的C应用程序时,一个高效的日志框架是不可或缺的。G3log是一个开源的日志库,以其高性能和易于使用著称,特别适用于嵌入式Linux环境。本文将详细介绍G3log的主要特性和如何在嵌入式Linux平台上进行交叉编译。 G3log介绍 G3log 是一…...