深度学习-线性神经网络

文章目录

  • 线性回归基本概念
      • 随机梯度下降
      • 矢量化加速
      • 正态分布和平方损失
      • 极大似然估计
  • 线性回归实现
      • 从0开始
        • **`torch.no_grad()`的两种用途**
        • **为什么需要 `l.sum().backward()`?**
      • 调用现成库
  • softmax回归
      • 图像数据集
    • 从0开始实现softmax
    • 利用框架API实现

课程学习自李牧老师B站的视频和网站文档

https://zh-v2.d2l.ai/chapter_preliminaries

线性回归基本概念

线性模型可以看作单层神经网络,由多个输入得到一个输出

线性回归可以解决预测多少的问题

适用问题

  1. 数值预测:
    • 预测连续值,如房价(基于面积、位置等)、股票价格(基于历史数据)、温度预测(基于时间和天气因素)。
    • 示例:用房屋面积和卧室数预测房价。
  2. 趋势分析:
    • 分析变量之间的线性趋势,如销售额随广告投入的增长。
    • 示例:研究学习时间对考试成绩的影响。
  3. 因果关系探索:
    • 初步评估输入特征对输出的影响(如广告支出对销售额的贡献)。
    • 示例:分析肥料用量对作物产量的关系。
  4. 数据标准化:
    • 用线性回归拟合基线(如去趋势数据),用于时间序列分析。
    • 示例:移除季节性影响后的销售预测。

image-20250718155636820

image-20250718160334727

image-20250718160436516

下面两组参数分别表示求一个损失均值,期望可以最小化损失的w和b

image-20250718161115060

解析解

image-20250718161740137

随机梯度下降

梯度下降最简单的用法是计算损失函数(数据集中所有样本的损失均值) 关于模型参数的导数(在这里也可以称为梯度)。 但实际中的执行可能会非常慢:因为在每一次更新参数之前,我们必须遍历整个数据集。 因此,我们通常会在每次需要计算更新的时候随机抽取一小批样本, 这种变体叫做小批量随机梯度下降

image-20250718162309911

公式表示梯度的原先的w减去均值乘上学习率

批量大小和学习率(沿着梯度走多长的方向)都是预先指定的

image-20250718193647163

训练过程中不断更新的参数叫超参数,调参是选择超参数的过程

矢量化加速

在训练我们的模型时,我们经常希望能够同时处理整个小批量的样本。 为了实现这一点,需要我们对计算进行矢量化, 从而利用线性代数库,而不是在Python中编写开销高昂的for循环。

什么是矢量化?

  • 矢量化(vectorization)是指用向量或矩阵操作替代循环,特别是在计算中同时处理多个数据点。这是一种利用现代处理器(如 CPU 或 GPU)并行计算能力的技巧。
import numpy as np
import time
import torch
import math
class Timer: """记录多次运行时间"""def __init__(self):self.times = []self.start()def start(self):"""启动计时器"""self.tik = time.time()def stop(self):"""停止计时器并将时间记录在列表中"""self.times.append(time.time() - self.tik)return self.times[-1]def avg(self):"""返回平均时间"""return sum(self.times) / len(self.times)def sum(self):"""返回时间总和"""return sum(self.times)def cumsum(self):"""返回累计时间"""return np.array(self.times).cumsum().tolist()n=10000
a=torch.ones([n])
b=torch.ones([n])c=torch.zeros([n])
time1=Timer()
for i in range(n):c[i]=a[i]+b[i]
print(f"{time1.stop()} sec")time2=Timer()
d=a+b
print(f"{time2.stop()} sec")

image-20250718164906886

正态分布和平方损失

image-20250718165028761

极大似然估计

什么是极大似然估计?

  • 极大似然估计是一种统计方法,用于根据观测数据找到最可能产生这些数据的模型参数。简单说,就是从数据“反推”出最合理的参数值。

image-20250718194524563

线性回归实现

从0开始

因为感觉应该也不会从头开始写函数,所以就只分析一下背后的原理不做实现了

生成数据集没什么好说的,注意,features中的每一行都包含一个二维数据样本, labels中的每一行都包含一维标签值(一个标量)

def synthetic_data(w, b, num_examples):  #@save"""生成y=Xw+b+噪声"""X = torch.normal(0, 1, (num_examples, len(w)))y = torch.matmul(X, w) + by += torch.normal(0, 0.01, y.shape)return X, y.reshape((-1, 1))true_w = torch.tensor([2, -3.4])
true_b = 4.2
features, labels = synthetic_data(true_w, true_b, 1000)

在下面的代码中,我们定义一个data_iter函数, 该函数接收批量大小、特征矩阵和标签向量作为输入,生成大小为batch_size的小批量。 每个小批量包含一组特征和标签。

def data_iter(batch_size, features, labels):num_examples = len(features)indices = list(range(num_examples))# 这些样本是随机读取的,没有特定的顺序random.shuffle(indices)for i in range(0, num_examples, batch_size):batch_indices = torch.tensor(indices[i: min(i + batch_size, num_examples)])yield features[batch_indices], labels[batch_indices]

yield用于实现一个 生成器(Generator),它的核心作用是:

按批次(batch)逐个返回数据和标签,而不是一次性返回所有数据

在我们开始用小批量随机梯度下降优化我们的模型参数之前, 我们需要先有一些参数。 在下面的代码中,我们通过从均值为0、标准差为0.01的正态分布中采样随机数来初始化权重, 并将偏置初始化为0。

w = torch.normal(0, 0.01, size=(2,1), requires_grad=True)
b = torch.zeros(1, requires_grad=True)

初始化参数后每次更新参数时计算梯度,然后从梯度减小的方向更新梯度

定义线性回归模型:

def linreg(X, w, b):  #@save"""线性回归模型"""return torch.matmul(X, w) + b

定义损失函数:

def squared_loss(y_hat, y):  #@save"""均方损失"""return (y_hat - y.reshape(y_hat.shape)) ** 2 / 2

定义优化算法:在每一步中,使用从数据集中随机抽取的一个小批量,然后根据参数计算损失的梯度。 接下来,朝着减少损失的方向更新我们的参数。每 一步更新的大小由学习速率lr决定

def sgd(params, lr, batch_size):  #@save"""小批量随机梯度下降"""with torch.no_grad():for param in params:param -= lr * param.grad / batch_sizeparam.grad.zero_()

params: 模型参数列表(如 [w, b]),每个参数是张量且带有 .grad属性。

with torch.no_grad():

  • 作用:禁用梯度计算上下文,确保参数更新时不会记录梯度(避免干扰后续反向传播)

  • 除以 batch_size:梯度是批次内样本梯度的总和,除以批次大小得到平均梯度(保证不同批次大小下的稳定性)。也叫梯度归一化,因为pytorch默认对批次内样本梯度求和

param.grad.zero_()

  • 清空梯度:将当前参数的梯度置零,避免下一次反向传播时梯度累加

那么到这里,数值初始化,损失计算,优化函数都搞定了,就可以开始训练了

lr = 0.03
num_epochs = 3
net = linreg
loss = squared_lossfor epoch in range(num_epochs):for X, y in data_iter(batch_size, features, labels):l = loss(net(X, w, b), y)  # X和y的小批量损失# 因为l形状是(batch_size,1),而不是一个标量。l中的所有元素被加到一起,# 并以此计算关于[w,b]的梯度l.sum().backward()sgd([w, b], lr, batch_size)  # 使用参数的梯度更新参数with torch.no_grad():train_l = loss(net(features, w, b), labels)print(f'epoch {epoch + 1}, loss {float(train_l.mean()):f}')
torch.no_grad()的两种用途
  1. 参数更新时sgd内):避免更新操作被记录到计算图中。
  2. 评估时:禁用梯度以节省内存和计算资源。
为什么需要 l.sum().backward()
  • PyTorch 的 backward()需要标量输入。如果 l是形状为 (batch_size, 1)的张量,必须先求和或均值转为标量。

  • 梯度计算逻辑

    对每个样本的损失求梯度后,PyTorch 默认对批次内梯度求和(sum),因此后续需手动除以 batch_size(在 sgd中实现)。

调用现成库

接下来try一try调用框架现成的库

同样先生成数据

true_w=torch.tensor([3,-3.4])
true_b=3.2
x,y=synthetic_data(true_w,true_b,1000)

读取数据可以调用现成的数据迭代器来进行,同时可以指定样本batch的大小,以及是否打乱数据

DataLoader其实本质上就是一个迭代器

def load_array(data_arrays,batch_size,is_train=True):dataset=data.TensorDataset(*data_arrays)return data.DataLoader(dataset,batch_size,shuffle=is_train)batch_size=10
data_iter=load_array((x,y),batch_size)
print(next(iter(data_iter)))

对于标准深度学习模型,我们可以使用框架的预定义好的层。这使我们只需关注使用哪些层来构造模型,而不必关注层的实现细节。 我们首先定义一个模型变量net,它是一个Sequential类的实例。 Sequential类将多个层串联在一起。 当给定输入数据时,Sequential实例将数据传入到第一层, 然后将第一层的输出作为第二层的输入,以此类推。

单层神经网络就是全连接层,在PyTorch中,全连接层在Linear类中定义。 值得注意的是,我们将两个参数传递到nn.Linear中。 第一个指定输入特征形状,即2,第二个指定输出特征形状,输出特征形状为单个标量,因此为1。

from torch import nn
net=nn.Sequential(nn.Linear(2,1))

指定每个权重参数应该从均值为0、标准差为0.01的正态分布中随机采样, 偏置参数将初始化为零。

net[0].weight.data.normal_(0,0.01)
net[0].bias.data.fill_(0)

损失函数和优化算法同样有现成的

loss=nn.MSELoss()
trainer=torch.optim.SGD(net.parameters(),lr=0.03)

接下来开始训练,使用模型net计算输出,之前生成的优化算法trainer更新结果

num_epochs=3
for epoch in range(num_epochs):for x,y in data_iter:l=loss(net(x),y)trainer.zero_grad()l.backward()trainer.step()l=loss(net(X),Y)print(f'epoch {epoch + 1}, loss {l:f}')

完整代码

from operator import ne
import numpy as np
import torch
from torch.utils import data
def synthetic_data(w, b, num_examples):  #@save"""生成y=Xw+b+噪声"""X = torch.normal(0, 1, (num_examples, len(w)))y = torch.matmul(X, w) + by += torch.normal(0, 0.01, y.shape)return X, y.reshape((-1, 1))
true_w=torch.tensor([3,-3.4])
true_b=3.2
X,Y=synthetic_data(true_w,true_b,1000)def load_array(data_arrays,batch_size,is_train=True):dataset=data.TensorDataset(*data_arrays)return data.DataLoader(dataset,batch_size,shuffle=is_train)batch_size=10
data_iter=load_array((X,Y),batch_size)from torch import nn
net=nn.Sequential(nn.Linear(2,1))net[0].weight.data.normal_(0,0.01)
net[0].bias.data.fill_(0)loss=nn.MSELoss()
trainer=torch.optim.SGD(net.parameters(),lr=0.01)num_epochs=5
for epoch in range(num_epochs):for x,y in data_iter:l=loss(net(x),y)trainer.zero_grad()l.backward()trainer.step()l=loss(net(X),Y)print(f'epoch {epoch + 1}, loss {l:f}')

softmax回归

用于解决分类的问题,预测图片中物品是哪一类

什么是置信度?

  • 置信度(confidence)表示模型对某个预测结果的“把握程度”,通常是一个介于 0 到 1 之间的值。数值越高,模型越认为预测正确。

image-20250719111004878

对分类进行编码

image-20250719111149659

softmax本质上也是一个根据输入计算得到输出的单层网络

什么是全连接层?

  • 全连接层(Fully Connected Layer, FC Layer)是神经网络中的一种层级结构,每个神经元都与前一层的所有神经元相连,像一张“全网”联系的网络,用于整合和变换特征。

image-20250719140544530

要将输出视为概率,我们必须保证在任何数据上的输出都是非负的且总和为1。 此外,我们需要一个训练的目标函数,来激励模型精准地估计概率。 例如, 在分类器输出0.5的所有样本中,我们希望这些样本是刚好有一半实际上属于预测的类别。 这个属性叫做校准(calibration)。

接下来对预测的概率值做一个处理,使其非负且总和为1

image-20250719141304115

第一个公式描述的是给定x的前提下所有标签的连乘概率,每一次事件都会对结果产生影响,MLE(最大似然估计)就是要最大化这个概率

第二个公式是取对数,将乘法转换为加法,最大值改为求最小值

第三个公式描述的是损失函数

image-20250719141846429

image-20250719142722477

图像数据集

图像数据集使用Fashion-MNIST数据集

  • 像素值范围

    • 在计算机中,一张图像由像素(Pixel)组成,每个像素的颜色通常用数值表示。
    • 对于 8位灰度图像(如FashionMNIST),每个像素的取值范围是 [0, 255]
      • 0表示纯黑色,
      • 255表示纯白色,
      • 中间值表示不同深浅的灰色。
    • 对于彩色图像(如RGB),每个通道(红、绿、蓝)的取值范围也是 [0, 255]
  • 归一化(Normalization)

    • 归一化是指将数据缩放到一个固定的范围(这里是 [0, 1])。
    • transforms.ToTensor()会自动将像素值从 [0, 255]除以 255,转换到 [0, 1]
  • 灰度图像(Grayscale Image)

    • 是一种单通道图像,每个像素只有一个数值表示亮度(没有颜色信息)。
    • 数值范围通常是 [0, 255]
      • 0:纯黑色,
      • 255:纯白色,
      • 中间值:灰色(如 128是中灰色)。
  • FashionMNIST 数据集是灰度图像,每张图片大小为 28x28像素,像素值范围 [0, 255]

  • 通过 ToTensor()转换后:

    • 形状从 (28, 28)变为 (1, 28, 28)(添加了通道维度)。
    • 像素值从 [0, 255]缩放到 [0, 1]

先下载数据

trans=transforms.ToTensor()
mnist_train=torchvision.datasets.FashionMNIST(root='./data',train=True,transform=trans,download=True
)
mnist_test=torchvision.datasets.FashionMNIST(root='./data',train=False,transform=trans,download=True
)

再展示图片

import re
import torch
import torchvision
from torch.utils import data
from torchvision import transforms
import matplotlib.pyplot as plttrans=transforms.ToTensor()
mnist_train=torchvision.datasets.FashionMNIST(root='./data',train=True,transform=trans,download=True
)
mnist_test=torchvision.datasets.FashionMNIST(root='./data',train=False,transform=trans,download=True
)
def get_fashion_mnist_labels(labels):  """返回Fashion-MNIST数据集的文本标签"""text_labels = ['t-shirt', 'trouser', 'pullover', 'dress', 'coat','sandal', 'shirt', 'sneaker', 'bag', 'ankle boot']return [text_labels[int(i)] for i in labels]def show_fashion_mnist(imgs,num_rows,num_cols,title=None,scale=1.5):figsize=(num_cols * scale, num_rows* scale)_, axes = plt.subplots(num_rows, num_cols, figsize=figsize)axes = axes.flatten()for i, (ax,img) in enumerate(zip(axes, imgs)):if torch.is_tensor(img):ax.imshow(img.numpy())else:ax.imshow(img)ax.axes.get_xaxis().set_visible(False)      ax.axes.get_yaxis().set_visible(False)if title:ax.set_title(title[i])plt.show()return axes
X, y = next(iter(data.DataLoader(mnist_train, batch_size=18)))
show_fashion_mnist(X.reshape(18, 28, 28), 2, 9, title=get_fashion_mnist_labels(y))

接下来通过内置数据迭代器来读取小批量数据

batch_size = 256
train_iter = data.DataLoader(mnist_train, batch_size, shuffle=True,num_workers=4)

综合下载数据并返回迭代器

def load_data_fashion_mnist(batch_size, resize=None):  #@save"""下载Fashion-MNIST数据集,然后将其加载到内存中"""trans = [transforms.ToTensor()]if resize:trans.insert(0, transforms.Resize(resize))trans = transforms.Compose(trans)mnist_train = torchvision.datasets.FashionMNIST(root="../data", train=True, transform=trans, download=True)mnist_test = torchvision.datasets.FashionMNIST(root="../data", train=False, transform=trans, download=True)return (data.DataLoader(mnist_train, batch_size, shuffle=True,num_workers=get_dataloader_workers()),data.DataLoader(mnist_test, batch_size, shuffle=False,num_workers=get_dataloader_workers()))

从0开始实现softmax

将28*28的图像展平后得到784的向量,也就是一个w,而我们有十个输出,所以有10个w

所以权重将构成一个784*10的矩阵

num_inputs = 784
num_outputs = 10W = torch.normal(0, 0.01, size=(num_inputs, num_outputs), requires_grad=True)
b = torch.zeros(num_outputs, requires_grad=True)

image-20250719153103166

def softmax(X):X_exp = torch.exp(X)partition = X_exp.sum(1, keepdim=True)return X_exp / partition  # 这里应用了广播机制

定义模型:其实就是将数据转换为w*x+b

def net(X):return softmax(torch.matmul(X.reshape((-1, W.shape[0])), W) + b)

在分类问题中,最常用的损失函数就是交叉熵函数

  • 分类任务需要模型输出 “属于某一类的概率”(如“这张图是猫的概率是90%”)。
  • 交叉熵直接衡量 预测概率分布真实标签分布 的差异,完美匹配这一需求。

image-20250719154107663

具体实现

def cross_entropy(y_hat, y):return - torch.log(y_hat[range(len(y_hat)), y])cross_entropy(y_hat, y)

softmax求精度,就是把预测值跟真实值作比较,最后用正确数/总数,下面描述的其实是怎么得到预测值的一个过程

image-20250719155334064

利用框架API实现

我们还是一样先读取数据

def load_data_fashion_mnist(batch_size, resize=None):  """下载Fashion-MNIST数据集,然后将其加载到内存中"""trans = [transforms.ToTensor()]if resize:trans.insert(0, transforms.Resize(resize))trans = transforms.Compose(trans)mnist_train = torchvision.datasets.FashionMNIST(root="../data", train=True, transform=trans, download=True)mnist_test = torchvision.datasets.FashionMNIST(root="../data", train=False, transform=trans, download=True)return (data.DataLoader(mnist_train, batch_size, shuffle=True,num_workers=get_dataloader_workers()),data.DataLoader(mnist_test, batch_size, shuffle=False,num_workers=get_dataloader_workers()))batch_size = 256
train_iter, test_iter = load_data_fashion_mnist(batch_size)

进行w和b的初始化

net=nn.Sequential(nn.Flatten(),nn.Linear(784, 10))def init_weights(m):if type(m) == nn.Linear:nn.init.normal_(m.weight, mean=0, std=0.01)nn.init.constant_(m.bias, 0)net.apply(init_weights)

image-20250719160240752

模型训练代码

import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import transforms, datasets
import matplotlib.pyplot as plt
import numpy as np# 1. 数据加载函数
def load_data_fashion_mnist(batch_size):"""下载Fashion-MNIST数据集并返回数据加载器"""transform = transforms.ToTensor()train_data = datasets.FashionMNIST(root="./data", train=True, transform=transform, download=True)test_data = datasets.FashionMNIST(root="./data", train=False, transform=transform, download=True)return (DataLoader(train_data, batch_size, shuffle=True, num_workers=0),  # Windows必须设为0DataLoader(test_data, batch_size, shuffle=False, num_workers=0))# 2. 模型定义
def init_weights(m):if type(m) == nn.Linear:nn.init.normal_(m.weight, std=0.01)nn.init.zeros_(m.bias)net = nn.Sequential(nn.Flatten(),nn.Linear(784, 10)
)
net.apply(init_weights)# 3. 训练工具
loss = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(net.parameters(), lr=0.1)def accuracy(y_hat, y):"""计算预测正确的数量"""if len(y_hat.shape) > 1 and y_hat.shape[1] > 1:y_hat = y_hat.argmax(axis=1)cmp = y_hat.type(y.dtype) == yreturn float(cmp.sum())class Accumulator:"""用于累加多个指标"""def __init__(self, n):self.data = [0.0] * ndef add(self, *args):self.data = [a + float(b) for a, b in zip(self.data, args)]def __getitem__(self, idx):return self.data[idx]# 4. 可视化类(适配普通Python脚本)
class Animator:def __init__(self, xlabel='epoch', legend=None, figsize=(8, 4)):self.fig, self.ax = plt.subplots(figsize=figsize)self.xlabel = xlabelself.legend = legendself.lines = Noneplt.show(block=False)  # 非阻塞显示def update(self, x, y_values):"""更新图表数据"""if self.lines is None:# 第一次调用时创建线条self.lines = []for _ in range(len(y_values)):line, = self.ax.plot([], [])self.lines.append(line)if self.legend:self.ax.legend(self.lines, self.legend)self.ax.grid()# 更新每条线的数据for line, y in zip(self.lines, y_values):x_data = list(line.get_xdata())y_data = list(line.get_ydata())x_data.append(x)y_data.append(y)line.set_data(x_data, y_data)# 调整坐标轴范围self.ax.relim()self.ax.autoscale_view()self.ax.set_xlabel(self.xlabel)self.fig.canvas.draw()plt.pause(0.01)  # 短暂暂停让GUI更新# 5. 训练和评估函数
def train_epoch(net, train_iter, loss, optimizer):"""训练一个epoch"""metric = Accumulator(3)  # 训练损失总和,训练准确度总和,样本数for X, y in train_iter:y_hat = net(X)l = loss(y_hat, y)optimizer.zero_grad()l.backward()optimizer.step()metric.add(float(l.sum()), accuracy(y_hat, y), y.numel())return metric[0]/metric[2], metric[1]/metric[2]  # 平均损失,准确率def evaluate_accuracy(net, data_iter):"""评估模型在数据集上的准确率"""net.eval()  # 评估模式metric = Accumulator(2)  # 正确预测数,总预测数with torch.no_grad():for X, y in data_iter:metric.add(accuracy(net(X), y), y.numel())return metric[0] / metric[1]def train(net, train_iter, test_iter, loss, num_epochs, optimizer):"""完整训练过程"""animator = Animator(xlabel='epoch', legend=['train loss', 'train acc', 'test acc'])for epoch in range(num_epochs):train_loss, train_acc = train_epoch(net, train_iter, loss, optimizer)test_acc = evaluate_accuracy(net, test_iter)animator.update(epoch + 1, (train_loss, train_acc, test_acc))plt.show(block=True)  # 训练结束后保持窗口显示# 6. 主程序
if __name__ == '__main__':# 参数设置batch_size = 256num_epochs = 10# 加载数据train_iter, test_iter = load_data_fashion_mnist(batch_size)# 开始训练print("开始训练...")train(net, train_iter, test_iter, loss, num_epochs, optimizer)print("训练完成!")# 保存模型torch.save(net.state_dict(), 'fashion_mnist_model.pth')print("模型已保存到 fashion_mnist_model.pth")

后面写的有点草率,一直学一个东西会疲劳,先调整一下再回来接着学

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

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

相关文章

【王树森推荐系统】推荐系统涨指标的方法04:多样性

涨指标的方法有哪些? 改进召回模型,添加新的召回模型改进粗排和精排模型提升召回,粗排,精排的多样性特殊对待新用户吗,低活用户等特殊人群利用关注,转发,评论这三种交互行为 排序的多样性 精排多…

1. Spring AI概述

一、前言 Spring AI 是由 Spring 团队推出的开源项目,旨在为 Java 开发者提供简洁、一致的 Spring 风格开发体验,用于构建基于生成式人工智能(GenAI)和大型语言模型(LLM)的应用程序。它通过标准化抽象层简…

[每日随题10] DP - 重链剖分 - 状压DP

整体概述 难度:1600 →\rightarrow→ 2200 →\rightarrow→ 2600 P6005 [USACO20JAN] Time is Mooney G 标签:DP 前置知识:链式前向星 难度:绿 1600 题目描述: 输入格式: 输出格式: 样例输…

【Ubuntu22.04】repo安装方法

背景 repo是Google开发的用于基于git管理Android版本库的一个工具,管理多个Git仓库的工具,它可以帮助您在一个代码库中管理多个Git仓库的代码。其在鸿蒙操作系统中大量使用。下面我们就介绍repo在wsl中的安装部署。 安装方法 使用中国科技大学资源 脚本i…

Vue3的definePros和defineEmits

在 Vue 3 中,defineProps 和 defineEmits 是组合式 API 中用于定义组件的 props 和 事件 的方法,提供了一种更简洁和明确的方式来管理组件的输入和输出。它们属于 Composition API 的一部分,在 Vue 2 中通常使用 props 和 $emit 来实现。1. d…

【华为机试】122. 买卖股票的最佳时机 II

文章目录122. 买卖股票的最佳时机 II描述示例 1示例 2示例 3提示解题思路核心观察关键洞察算法实现方法1:贪心算法(推荐)方法2:动态规划方法3:动态规划(空间优化)方法4:波峰波谷法算…

Spring MVC @RequestParam注解全解析

RequestParam 注解详解 RequestParam 是 Spring MVC 中最常用的注解之一,用于从 HTTP 请求中提取查询参数(Query String)或表单数据。它主要处理 application/x-www-form-urlencoded 类型的请求(如 GET 请求或 POST 表单提交&…

从零掌握XML与DTD实体:原理、XXE漏洞攻防

本文仅用于技术研究,禁止用于非法用途。 Author:枷锁 文章目录一、XML基础1. 什么是XML?2. XML语法规则3. 数据类型二、DTD1. 认识DTD2. 声明DTD3. DTD实体4. 如何防御XXE攻击?5. 总结一、XML基础 1. 什么是XML? XML &#xff1…

.NET 8 Release Candidate 1 (RC1)现已发布,包括许多针对ASP.NET Core的重要改进!

.NET 8 Release Candidate 1 (RC1)发布:ASP.NET Core重大改进来袭! 近日,.NET 8 Release Candidate 1 (RC1)正式发布,这是在今年晚些时候计划发布的最终 .NET 8 版本之前的两个候选版本中的第一个。此版本包含了大部分计划中的功…

Jenkins pipeline 部署docker通用模板

Jenkinsfile: Docker的NETWORK_NAME不要使用bridge默认网络,要使用自定义的网络如test默认 bridge 网络:容器间不能用名字互相访问,只能用 IP。自定义网络:容器间可以用名字互相访问,Docker 自动做了 DNS 解析。pipeli…

【每日算法】专题十五_BFS 解决 FloodFill 算法

1. 算法思想 Flood Fill 问题的核心需求 给定一个二维网格(如像素矩阵)、一个起始坐标 (x, y) 和目标颜色 newColor,要求: 将起始点 (x, y) 的颜色替换为 newColor。递归地将所有与起始点相邻(上下左右) …

ESLint 完整功能介绍和完整使用示例演示

以下是ESLint的完整功能介绍和完整使用示例演示: ESLint 完整功能介绍 一、核心功能静态代码分析: 通过解析JavaScript/TypeScript代码为抽象语法树(AST),识别语法错误、潜在问题(如未定义变量、未使用变量…

解决问题七大步骤

发现问题后寻找解决方案的流程可以细化为 7个核心步骤,每个步骤包含具体措施、信息源和关键技巧,形成“从自查到验证、从独立解决到寻求帮助”的完整闭环。以下是完善后的流程: 一、明确问题与初步自查(前提:减少无效搜…

思维链(CoT)技术全景:原理、实现与前沿应用深度解析

一、核心概念与原理 定义与起源 CoT 是一种引导大语言模型(LLM)显式生成中间推理步骤的技术,通过模拟人类逐步解决问题的过程,提升复杂任务(如数学证明、多步逻辑推理)的准确性。该概念由 Google Brain 团…

实验-华为综合

华为综合实验 一 实验拓扑二 实验配置交换机2 vlan batch 10 20 int e0/0/2 port link-type access port default vlan 10 int e0/0/1 port link-type access port default vlan 20 int e0/0/3 port link-type trunk port trunk allow-pass vlan alltelnet交换机3 链路类型配置…

Matlab打开慢、加载慢的解决办法

安装完毕后直接打开会非常慢,而且打开了之后还得加载很久才能运行 解决办法如下: 1.找到路径“D:\Program Files\Polyspace\R2020a\licenses”(我是把matlab安装在D盘了,如果是其他盘修改路径即可),该路径记…

混沌趋势指标原理及交易展示

1. 引言在金融市场交易中,尤其是加密货币合约交易,趋势跟踪是最主流的策略之一。然而,传统趋势指标如均线、MACD等存在明显的滞后性,往往在趋势确立后才发出信号,导致交易者错失最佳入场时机。更糟糕的是,市…

Java面试宝典:Maven

一、Maven的本质与核心价值 项目管理革命 POM驱动:通过pom.xml文件定义项目结构、依赖、构建规则,实现标准化管理()。示例配置: <dependencies> <dependency> <groupId>org.springframework

可靠消息最终一致性分布式事务解决方案

之前文章写过主流的一些 分布式事务的解决方案&#xff0c;但其实工作中很少有一些高并发的业务中去使用这些方案&#xff0c;因为对于高并发的场景来说&#xff0c;引入这些方案的性能损耗太大&#xff0c;且对系统事务侵入性太强影响系统稳定性。 所以在高并发的业务中&…

ISIS基础

拓扑计算方式 模型 支持的网络 支持的地址OSPF SPF TCP/IP IP网络 IPv4地址ISIS SPF OSI CLNP网络 NSAP地址集成ISIS SPF TCP/IP IP网络 NSAP地址&#xff0c;但可以支持IPv4地址12. …