早期 CNN 的經典模型—卷積神經網絡(LeNet)

目錄

LeNet 的設計背景與目標

?LeNet 的網絡結構(經典 LeNet-5)

局部感受野詳解

一、局部感受野和全連接網絡的區別

1.?傳統全連接網絡的問題

2.?局部感受野的解決方案

二、局部感受野的優勢

1. 參數大幅減少

2. 提取局部特征

3. 平移不變性

參數共享(權值共享)詳解

一、定義與核心思想

二、為什么需要參數共享?

1.?減少參數數量

2.?平移不變性

3.?強制特征學習的普適性

三、參數共享與局部感受野的協同作用

?池化詳解

一、池化的核心作用

二、常見的池化方式

1.?最大池化(Max Pooling)

2.?平均池化(Average Pooling)

3.?其他變體

三、池化的工作流程

四、池化與卷積的區別

五、池化的參數設置

?為什么每個 epoch 都需要新的累加器?

代碼執行流程驗證

?完整代碼

實驗結果


LeNet 的設計背景與目標

在 LeNet 出現之前,圖像識別主要依賴全連接神經網絡,但存在兩個關鍵問題:

?
  1. 參數爆炸:全連接網絡將圖像展平為向量,若輸入為 32×32 的圖像,僅第一層就需要約 1000 個神經元(參數近百萬),計算成本極高。
  2. 缺乏平移不變性:圖像中目標的微小位移會導致全連接網絡的輸入向量大幅變化,識別魯棒性差。

LeNet 通過局部感受野、參數共享和池化三大核心思想解決了這些問題,專為圖像識別設計。

?LeNet 的網絡結構(經典 LeNet-5)

LeNet-5 的結構簡潔且層次分明,可分為卷積層塊(特征提取)和全連接層塊(分類決策)兩部分。整體結構如下:

層類型名稱核心參數輸入維度輸出維度作用
輸入層-手寫數字圖像(灰度圖)32×32×132×32×1原始像素輸入
卷積層C16 個 5×5 卷積核,步幅 = 1,無填充(padding=0)32×32×128×28×6提取局部特征(如邊緣、拐角),輸出 6 個特征圖
平均池化層S22×2 窗口,步幅 = 2,無填充28×28×614×14×6降低維度(寬高減半),增強平移不變性
卷積層C316 個 5×5 卷積核,步幅 = 1,無填充14×14×610×10×16提取更復雜的組合特征(如紋理、局部形狀)
平均池化層S42×2 窗口,步幅 = 2,無填充10×10×165×5×16進一步降維,寬高再減半
卷積層(特殊)C5120 個 5×5 卷積核,步幅 = 1,無填充(等價于全連接,因輸入 5×5 剛好被卷積核覆蓋)5×5×161×1×120提取高層抽象特征,輸出 120 個特征
全連接層F684 個神經元12084整合特征,為分類做準備
輸出層F710 個神經元(對應數字 0-9),使用 softmax 激活8410輸出

局部感受野詳解

一、局部感受野和全連接網絡的區別

1.?傳統全連接網絡的問題

在處理圖像時,若使用全連接網絡:

  • 輸入層神經元與圖像像素一一對應(如 32×32 圖像需 1024 個神經元)。
  • 隱藏層每個神經元連接所有輸入神經元,導致參數極多(如 1000 個隱藏神經元需 1024×1000≈100 萬參數)。
  • 這種 “全局連接” 忽略了圖像的局部相關性(相鄰像素關聯緊密,遠距離像素關聯弱)。
2.?局部感受野的解決方案

在 CNN 中,卷積層的每個神經元僅連接輸入圖像的局部區域,而非全部像素:

  • 局部區域大小:由卷積核(濾波器)的尺寸決定。例如,5×5 的卷積核對應 5×5 的局部感受野。
  • 滑動窗口機制:卷積核在輸入圖像上滑動,每個位置生成一個輸出值,形成特征圖。

示例(輸入圖像 32×32,卷積核 5×5):

  • 第一個卷積神經元僅連接輸入圖像左上角 5×5 的區域(感受野)。
  • 第二個神經元連接向右滑動 1 步后的 5×5 區域(假設步幅 = 1)。
  • 依此類推,直到覆蓋整個圖像。

二、局部感受野的優勢

1. 參數大幅減少
  • 每個卷積核的參數固定(如 5×5 卷積核僅 25 個參數),無論輸入圖像多大。
  • 相比全連接網絡,參數減少幾個數量級,緩解過擬合,降低計算成本。
2. 提取局部特征
  • 卷積核能自動學習圖像的局部特征(如邊緣、紋理、角點)。
  • 多層 CNN 通過堆疊卷積層,可從低級特征(邊緣)逐步構建高級特征(物體部件、整體)。
3. 平移不變性
  • 無論特征出現在圖像的哪個位置,卷積核都能檢測到(因參數共享,見下文)。
  • 例如,識別數字 “7” 時,無論 “7” 出現在圖像左上角還是右下角,同一卷積核都能響應。

參數共享(權值共享)詳解

參數共享(Parameter Sharing)?是卷積神經網絡(CNN)的核心機制之一,它與局部感受野共同構成了 CNN 的效率基石。通過參數共享,CNN 能夠在大幅減少模型參數的同時,保持強大的特征提取能力。

一、定義與核心思想

參數共享是指在神經網絡中,一組參數(權重)被應用于多個不同的輸入位置。在 CNN 中,這一思想體現在以下方面:

  1. 卷積核的參數共享
    每個卷積核(濾波器)的參數在整個輸入圖像上保持不變。例如,一個 5×5 的卷積核在掃描輸入圖像的所有位置時,使用的是同一組權重。

  2. 跨通道的獨立性
    不同卷積核的參數是獨立的,但同一卷積核在不同位置的參數共享。例如,32 個卷積核會生成 32 個特征圖,每個特征圖使用各自獨立的參數。

二、為什么需要參數共享?
1.?減少參數數量

傳統全連接網絡處理圖像時,參數數量與圖像尺寸的平方成正比(如 32×32 圖像需約 100 萬參數)。而 CNN 通過參數共享,將參數數量降低到與圖像尺寸無關:

?
  • 一個 5×5 的卷積核僅需 25 個參數(加偏置 26 個)。
  • 若有 32 個卷積核,總參數僅 32×26=832 個,遠少于全連接網絡。
2.?平移不變性

參數共享使 CNN 對圖像中的平移變換具有魯棒性:

  • 無論特征出現在圖像的哪個位置,同一卷積核都能檢測到它。
  • 例如,一個識別 “貓耳朵” 的卷積核,在圖像左上角和右下角都能發揮作用。
3.?強制特征學習的普適性

通過參數共享,網絡被迫學習在圖像所有位置都有效的特征,而非特定位置的特征,從而增強泛化能力。

三、參數共享與局部感受野的協同作用

參數共享與局部感受野是 CNN 的兩大核心思想,二者相互配合:

  1. 局部感受野:每個神經元僅連接輸入的局部區域,提取局部特征。
  2. 參數共享:同一卷積核在所有局部區域使用相同參數,檢測相同特征。

示例

  • 一個垂直邊緣檢測器(卷積核)通過參數共享,在圖像的所有位置檢測垂直邊緣。
  • 若沒有參數共享,網絡需為每個位置學習獨立的邊緣檢測器,參數數量爆炸式增長。

?池化詳解

在卷積神經網絡(CNN)中,池化(Pooling)?是一種重要的下采樣操作,主要用于減少特征圖的空間維度(高度和寬度),同時保留關鍵特征。它通常緊跟在卷積層之后,是 CNN 中控制模型復雜度、提升計算效率和增強平移不變性的核心手段之一。

一、池化的核心作用

  1. 降低維度:通過對特征圖進行聚合操作,減少輸出特征圖的尺寸(例如將 2×2 區域壓縮為 1 個值),從而降低后續層的計算量和參數數量,避免過擬合。
  2. 增強平移不變性:對局部區域的特征進行聚合(如取最大值或平均值),使得模型對輸入數據的微小位移不敏感(例如圖像中物體的輕微移動不影響特征提取結果)。
  3. 保留關鍵特征:通過選擇局部區域的顯著特征(如最大值)或統計特征(如平均值),過濾冗余信息,突出重要模式。

二、常見的池化方式

池化操作通過一個固定大小的 “池化窗口” 在特征圖上滑動(類似卷積窗口),對窗口內的元素進行聚合計算。常見的池化方式有:

1.?最大池化(Max Pooling)
  • 操作:取池化窗口內所有元素的最大值作為輸出。
  • 特點:保留局部區域內的最顯著特征(如邊緣、紋理的強度),對噪聲更魯棒,是實際應用中最常用的池化方式。
  • 示例:對窗口[[1, 3], [2, 4]]進行最大池化,結果為4
2.?平均池化(Average Pooling)
  • 操作:取池化窗口內所有元素的平均值作為輸出。
  • 特點:保留局部區域的整體強度信息,對特征的平滑性更好,但可能會弱化顯著特征。
  • 示例:對窗口[[1, 3], [2, 4]]進行平均池化,結果為(1+3+2+4)/4 = 2.5
3.?其他變體
  • 最小池化:取窗口內最小值(較少用,適用于檢測暗區域特征)。
  • L2 池化:取窗口內元素平方和的平方根,兼顧數值大小和穩定性。

三、池化的工作流程

2×2 最大池化為例,步驟如下:

  1. 設定池化窗口大小(如 2×2)和滑動步長(通常與窗口大小相同,如步長 = 2)。
  2. 窗口從特征圖左上角開始,依次在水平和垂直方向滑動。
  3. 對每個窗口內的元素執行池化操作(如取最大值),生成輸出特征圖的一個元素。
  4. 重復滑動,直到覆蓋整個特征圖。

示例
輸入特征圖為 3×3 矩陣:

?
[[0, 1, 2],[3, 4, 5],[6, 7, 8]]
?

使用 2×2 最大池化(步長 = 2),輸出為 2×2 矩陣:

?
[[4, 5],  # 窗口(0-1行, 0-1列)最大值=4;窗口(0-1行, 1-2列)最大值=5[7, 8]]  # 窗口(1-2行, 0-1列)最大值=7;窗口(1-2行, 1-2列)最大值=8

四、池化與卷積的區別

維度卷積操作池化操作
核心目的提取局部特征(如邊緣、紋理)降低維度,保留關鍵特征
是否有參數有卷積核參數(需要學習)無參數(僅執行固定聚合規則)
操作對象輸入與卷積核的加權求和窗口內元素的聚合(max/avg 等)
輸出維度變化可通過 padding 和 stride 控制通常尺寸減小(下采樣)

五、池化的參數設置

與卷積類似,池化操作也需要指定:

  • 池化窗口大小(kernel_size):如 2×2、3×3(常用奇數,便于對稱滑動)。
  • 步長(stride):窗口滑動的步幅,默認與窗口大小相同(如 2×2 窗口對應步長 = 2)。
  • 填充(padding):在特征圖邊緣補 0,用于保持輸出尺寸(較少用,因池化通常目的是降維)。

例如,在 PyTorch 中定義一個 3×3 最大池化層:

?
import torch.nn as nn
pool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)  # 窗口3×3,步長2,邊緣補1層0

?為什么每個 epoch 都需要新的累加器?

累加器(d2l.Accumulator)的作用是統計當前 epoch 內的訓練指標(訓練損失總和、正確預測數、總樣本數)。每個 epoch 是一個獨立的訓練周期,需要單獨統計該周期的指標,因此必須在每個 epoch 開始時重置累加器。

具體來說:

  1. metric?的三個累加項

    • metric[0]:當前 epoch 所有樣本的損失總和(l * X.shape[0])。
    • metric[1]:當前 epoch 所有樣本中正確預測的數量(d2l.accuracy(y_hat, y))。
    • metric[2]:當前 epoch 處理的總樣本數(X.shape[0],即批次大小)。
  2. 每個 epoch 獨立統計

    • 第 1 個 epoch 結束后,metric?中存儲的是第 1 個 epoch 的指標,用于計算該 epoch 的平均損失和準確率。
    • 第 2 個 epoch 開始時,必須創建新的?metric,否則會與第 1 個 epoch 的指標混淆,導致計算錯誤。

代碼執行流程驗證

假設?num_epochs=2(訓練 2 個 epoch),流程如下:

?
# 第1個epoch開始
epoch=0:metric = d2l.Accumulator(3)  # 新累加器,初始值[0,0,0]遍歷所有批次:metric.add(當前批次損失, 當前批次正確數, 當前批次樣本數)計算第1個epoch的指標:train_l = metric[0]/metric[2]  # 第1個epoch的平均損失train_acc = metric[1]/metric[2]  # 第1個epoch的準確率# 第2個epoch開始
epoch=1:metric = d2l.Accumulator(3)  # 新累加器,重置為[0,0,0]遍歷所有批次:metric.add(當前批次損失, 當前批次正確數, 當前批次樣本數)計算第2個epoch的指標:train_l = metric[0]/metric[2]  # 第2個epoch的平均損失(獨立于第1個epoch)

?

如果不重置累加器,第 2 個 epoch 的指標會疊加到第 1 個 epoch 上,導致結果錯誤。

?完整代碼

"""
文件名: 6.6  卷積神經網絡(LeNet)
作者: 墨塵
日期: 2025/7/13
項目名: dl_env
備注: 
"""
import torch
from torch import nn
from d2l import torch as d2l
# 手動顯示圖像(關鍵)
import matplotlib.pyplot as plt
import matplotlib.text as text  # 新增:用于修改文本繪制# -------------------------- 核心解決方案:替換減號 --------------------------
# 定義替換函數:將Unicode減號U+2212替換為普通減號-
def replace_minus(s):if isinstance(s, str):return s.replace('\u2212', '-')return s# 安全重寫Text類的set_text方法,避免super()錯誤
original_set_text = text.Text.set_text  # 保存原始方法
def new_set_text(self, s):s = replace_minus(s)  # 替換減號return original_set_text(self, s)  # 調用原始方法
text.Text.set_text = new_set_text  # 應用新方法
# -------------------------------------------------------------------------# -------------------------- 字體配置(關鍵修改)--------------------------
# 解決中文顯示和 Unicode 減號(U+2212)顯示問題
plt.rcParams["font.family"] = ["SimHei"]
plt.rcParams["text.usetex"] = True  # 使用Latex渲染
plt.rcParams["axes.unicode_minus"] = True  # 正確顯示負號
plt.rcParams["mathtext.fontset"] = "cm"    # 確保數學符號(如減號)正常顯示
d2l.plt.rcParams.update(plt.rcParams)      # 讓 d2l 繪圖工具繼承字體配置
# -------------------------------------------------------------------------"""激活函數的核心作用是引入非線性,因此:
隱藏層必須使用激活函數,否則深層網絡失去意義;
輸出層根據任務選擇是否使用,取決于是否需要對輸出進行范圍約束或概率化。"""# 評估模型在數據集上的準確率(使用GPU)
def evaluate_accuracy_gpu(net, data_iter, device=None): #@save"""使用GPU計算模型在數據集上的精度"""if isinstance(net, nn.Module):net.eval()  # 設置為評估模式(關閉Dropout、BatchNorm等)if not device:device = next(iter(net.parameters())).device  # 獲取模型參數所在的設備# 累加器:用于統計正確預測數和總樣本數metric = d2l.Accumulator(2)  # 創建一個包含2個累加項的累加器with torch.no_grad():  # 關閉梯度計算,節省內存和計算資源for X, y in data_iter:# 將數據移至GPUif isinstance(X, list):X = [x.to(device) for x in X]  # 處理特殊輸入(如BERT)else:X = X.to(device)y = y.to(device)# 計算預測正確的樣本數,并累加到metric中metric.add(d2l.accuracy(net(X), y), y.numel())  # y.numel()返回y中元素的總數return metric[0] / metric[1]  # 返回準確率# 訓練模型(使用GPU)自定義GPU訓練模型
def train_ch6(net, train_iter, test_iter, num_epochs, lr, device):"""用GPU訓練模型(在第六章定義)"""# 權重初始化函數:對線性層和卷積層使用Xavier均勻初始化def init_weights(m):if type(m) == nn.Linear or type(m) == nn.Conv2d:nn.init.xavier_uniform_(m.weight)net.apply(init_weights)  # 應用權重初始化print('training on', device)net.to(device)  # 將模型移至GPU# 定義優化器和損失函數optimizer = torch.optim.SGD(net.parameters(), lr=lr)  # 使用隨機梯度下降loss = nn.CrossEntropyLoss()  # 交叉熵損失函數(用于多分類)# 創建動畫繪制器,用于可視化訓練過程animator = d2l.Animator(xlabel='epoch', xlim=[1, num_epochs],legend=['train loss', 'train acc', 'test acc'])timer, num_batches = d2l.Timer(), len(train_iter)  # 計時器和批次數量# 訓練主循環for epoch in range(num_epochs):# 訓練損失之和,訓練準確率之和,樣本數metric = d2l.Accumulator(3)  # 創建包含3個累加項的累加器net.train()  # 設置為訓練模式# 遍歷每個批次的數據for i, (X, y) in enumerate(train_iter):timer.start()  # 開始計時# 梯度清零,前向傳播,計算損失,反向傳播,更新參數optimizer.zero_grad()X, y = X.to(device), y.to(device)  # 將數據移至GPUy_hat = net(X)  # 前向傳播l = loss(y_hat, y)  # 計算損失l.backward()  # 反向傳播optimizer.step()  # 更新參數# 統計訓練損失和準確率with torch.no_grad():metric.add(l * X.shape[0], d2l.accuracy(y_hat, y), X.shape[0])timer.stop()  # 停止計時# 計算當前批次的訓練損失和準確率train_l = metric[0] / metric[2]train_acc = metric[1] / metric[2]# 每5個批次或最后一個批次時,更新動畫if (i + 1) % (num_batches // 5) == 0 or i == num_batches - 1:animator.add(epoch + (i + 1) / num_batches,(train_l, train_acc, None))# 每個epoch結束后,在測試集上評估模型test_acc = evaluate_accuracy_gpu(net, test_iter)animator.add(epoch + 1, (None, None, test_acc))# 打印最終結果print(f'loss {train_l:.3f}, train acc {train_acc:.3f}, test acc {test_acc:.3f}')print(f'{metric[2] * num_epochs / timer.sum():.1f} examples/sec on {str(device)}')if __name__ == '__main__':# ------------------------------# 步驟1: 定義LeNet-5網絡# ------------------------------# 定義LeNet-5網絡(針對MNIST數據集優化版本)net = nn.Sequential(# ===== 第一卷積塊:提取低級特征 =====nn.Conv2d(1, 6, kernel_size=5, padding=2),  # 輸入1通道,輸出6通道,保持尺寸28x28nn.Sigmoid(),  # 引入非線性nn.AvgPool2d(kernel_size=2, stride=2),  # 池化,尺寸減半至14x14# ===== 第二卷積塊:提取中級特征 =====nn.Conv2d(6, 16, kernel_size=5),  # 輸入6通道,輸出16通道,尺寸減小至10x10nn.Sigmoid(),  # 引入非線性nn.AvgPool2d(kernel_size=2, stride=2),  # 池化,尺寸減半至5x5# ===== 展平層:將多維特征圖轉為一維向量 =====nn.Flatten(),  # 展平為400維向量# ===== 全連接層塊:分類器 =====nn.Linear(16 * 5 * 5, 120),  # 400→120nn.Sigmoid(),  # 引入非線性nn.Linear(120, 84),  # 120→84nn.Sigmoid(),  # 引入非線性nn.Linear(84, 10)  # 84→10(輸出10類,對應0-9數字))# -----------------------------------------------# 步驟2: 檢查LeNet-5網絡的可用性# ------------------------------------------------# 創建一個隨機輸入張量,模擬MNIST數據X = torch.rand(size=(1, 1, 28, 28), dtype=torch.float32)# 逐層打印輸出形狀,驗證網絡結構for layer in net:X = layer(X)print(layer.__class__.__name__, 'output shape: \t', X.shape)# -----------------------------------------------# 步驟3: 初始化數據集# ------------------------------------------------# 加載Fashion-MNIST數據集(28x28灰度圖像,10個類別)batch_size = 256train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size=batch_size)# -----------------------------------------------# 步驟4: 訓練# ------------------------------------------------lr, num_epochs = 0.9, 10  # 學習率和訓練輪數# 使用GPU訓練模型(如果可用)train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())# 顯示圖像plt.show(block=True)  # block=True 確保窗口阻塞,直到手動關閉

實驗結果

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/88797.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/88797.shtml
英文地址,請注明出處:http://en.pswp.cn/web/88797.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

RabbitMQ 高級特性之延遲隊列

1. 簡介 在某些場景下,當生產者發送消息后,可能不需要讓消費者立即接收到,而是讓消息延遲一段時間后再發送給消費者。 2. 實現方式 2.1 TTL 死信隊列 給消息設置過期時間后,若消息在這段時間內沒有被消費,就會將消…

uniapp app安卓下載文件 圖片 doc xls 數據流文件 app安卓本地路徑下載保存

//下載圖片 downloadToLocal() {plus.android.requestPermissions([android.permission.WRITE_EXTERNAL_STORAGE],(success) > {uni.saveImageToPhotosAlbum({filePath: /static/x.png,//本地地址success: () > {this.$refs.uToast.show({message: "模版下載成功&am…

Context Engineering:從Prompt Engineering到上下文工程的演進

最近在做Deepresearch以及刷到一個不錯的文章:context-engineering-guide ,這篇文章揭示了提示工程以及上下文過程在智能體應用開源流程中,包括Deepresearch,MCP在內的一些概念,起到了非常重要的作用! Cont…

jenkins部署vue前端項目

文章目錄前言一、安裝nginx二、jenkins構建項目總結前言 前面已經使用jenkins部署了后端springboot項目,現在開始學習jenkins部署前端Vue項目。 一、安裝nginx 訪問nginx官網,https://nginx.org/en/download.html下載tar包 上傳到服務器目錄中 然后到…

設計總監年中復盤:用Adobe XD內容識別布局,告別“手動調距”

時至年中,這不僅是檢視上半年項目成果的節點,更是優化團隊工作流、為下半年挑戰儲備動能的關鍵時期。在海外設計界工作的十余年間,我發現,一個高效的設計團隊與一個疲于奔命的團隊之間,最大的差別往往就在于是否建立了…

Unity 在Rider中通過Lingma插件使用MCP

環境: Unity 2022.3.12f1 JetBrains Rider 2025.1.4 Lingma 2.5.14 Python 3.13.4 下載包 首先在unity package manager 加入unity-mcp包 https://github.com/justinpbarnett/unity-mcp.git 然后下載uv包(要先先下載python),網上很多…

pycharm+SSH 深度學習項目 遠程后臺運行命令

pycharmSSH 深度學習項目 遠程后臺運行命令碎碎念,都是實驗室里那說關機就關機,說重啟就重啟的臺式機逼得。。學吧記錄 運行:nohup /root/miniconda3/bin/python -u "run.py" > /root/log/nohup.log 2>&1 &實時查看日…

【Linux | 網絡】應用層(HTTP)

目錄一、認識URL二、urlencode和urldecode三、HTTP協議格式(使用Fiddler抓包)3.1 安裝并使用Fiddler抓包3.2 HTTP協議格式3.2.1 HTTP請求3.2.1.1 資源URL路徑3.2.1.2 請求方法(Method)3.2.1.3 Location頭字段(重定向相…

編程實踐:單例模式(懶漢模式+餓漢模式)

說明:本專欄文章有兩種解鎖方案 1:付費訂閱,暢享所有文章 2:免費獲取,點擊下方鏈接,關注,自動獲取免費鏈接 https://free-img.400040.xyz/4/2025/04/29/6810a50b7ac8b.jpg 主題:C++ 單例模式 什么是單例模式

破局電機制造四大痛點:MES與AI視覺的協同智造實踐

萬界星空科技電機行業MES系統解決方案是針對電機制造過程中多工序協同難、質量追溯復雜、設備管理要求高等痛點設計的數字化管理系統。一、電機行業的核心痛點1. 多工序協同困難 電機制造涉及繞線、裝配、測試等多道工序,工藝銜接復雜,傳統人工調度效率…

HTML 初體驗

HTML(超文本標記語言)全稱:HyperText Markup Language。超文本是什么?答:超文本就是網頁中的鏈接。標記是什么?答:標記也叫標簽,是帶尖括號的文本。需求1:將“我愛中國”…

網絡層TCP機制

1.確認應答機制由于發送信息的距離可能較遠,可能出現后發的信息先到的情況,怎么辦?TCP將每個字節的數據都進行了編號,即為序列號如何分辨一個數據包是普通數據還是應答數據呢2.超時重傳由于丟包是一個隨機的事件,因此在上述tcp傳輸的過程中,丟包就存在兩種情況但是在發送方的角…

【一起來學AI大模型】微調技術:LoRA(Low-Rank Adaptation) 的實戰應用

LoRA(Low-Rank Adaptation) 的實戰應用,使用 Hugging Face 的 peft (Parameter-Efficient Fine-Tuning) 庫對大型語言模型進行高效微調。LoRA 因其顯著降低資源消耗(顯存和計算)同時保持接近全量微調性能的特點&#x…

RedisJSON 內存占用剖析與調優

一、基礎內存模型指針包裝 所有 JSON 值(標量、對象、數組、字符串等)至少占用 8 字節,用于存儲一個帶類型標記的指針。標量與空容器 null、true、false、小整數(靜態緩存)、空字符串、空數組、空對象 均不分配額外內存…

【LeetCode 熱題 100】23. 合并 K 個升序鏈表——(解法一)逐一合并

Problem: 23. 合并 K 個升序鏈表 題目:給你一個鏈表數組,每個鏈表都已經按升序排列。 請你將所有鏈表合并到一個升序鏈表中,返回合并后的鏈表。 文章目錄整體思路完整代碼時空復雜度時間復雜度:O(K * N)空間復雜度:O(1…

垃圾收集器-Serial Old

第一章 引言1.1 JVM 中垃圾收集的簡要概述JVM(Java Virtual Machine)作為 Java 程序的運行時環境,負責將字節碼加載至內存并執行,同時也承擔著內存管理的重任。垃圾收集(Garbage Collection,簡稱 GC&#x…

Docker(02) Docker-Compose、Dockerfile鏡像構建、Portainer

Docker-Compose 1、Docker Desktop 在Windows上安裝Docker服務,可以使用Docker Desktop這個應用程序。 下載并安裝這樣的一個安裝包 安裝好后:執行命令 docker --version 從Docker Hub提取hello-world映像并運行一個容器: docker run h…

大數據時代UI前端的用戶體驗設計新思維:以數據為驅動的情感化設計

hello寶子們...我們是艾斯視覺擅長ui設計和前端數字孿生、大數據、三維建模、三維動畫10年經驗!希望我的分享能幫助到您!如需幫助可以評論關注私信我們一起探討!致敬感謝感恩!一、引言:從 “經驗設計” 到 “數據共情” 的體驗革命傳統 UI 設計常陷入 “設計師主觀經…

TypeScript 學習手冊

1.TypeScript 概念 TypeScript(簡稱 TS,靜態類型)是微軟公司開發的一種基于 JavaScript (簡稱 JS,動態類型)語言的編程語言。TypeScript 可以看成是 JavaScript 的超集(superset)&a…

掌握現代CSS:變量、變形函數與動態計算

CSS近年來發展迅速,引入了許多強大的功能,如變量、高級變形函數和動態計算能力。本文將深入探討如何在CSS中設置并使用變量,以及如何有效利用translate3d、translateY和translateX等變形方法。我們還將解析var()和calc()函數的關鍵作用。一、…