深度學習-線性神經網絡

文章目錄

  • 線性回歸基本概念
      • 隨機梯度下降
      • 矢量化加速
      • 正態分布和平方損失
      • 極大似然估計
  • 線性回歸實現
      • 從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
英文地址,請注明出處:http://en.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. …