從代碼學習深度學習 - 單發多框檢測(SSD)PyTorch版

文章目錄

  • 前言
  • 工具函數
    • 數據處理工具 (`utils_for_data.py`)
    • 訓練工具 (`utils_for_train.py`)
    • 檢測相關工具 (`utils_for_detection.py`)
    • 可視化工具 (`utils_for_huitu.py`)
  • 模型
    • 類別預測層
    • 邊界框預測層
    • 連接多尺度預測
    • 高和寬減半塊
    • 基礎網絡塊
    • 完整的模型
  • 訓練模型
    • 讀取數據集和初始化
    • 定義損失函數和評價函數
    • 訓練模型
  • 預測目標
    • 圖像預處理
    • 執行預測和后處理
    • 可視化結果
  • 總結


前言

大家好!歡迎來到“從代碼學習深度學習”系列博客。目標檢測是計算機視覺領域的核心任務之一,旨在識別圖像或視頻中特定類別的對象實例,并確定它們的位置和范圍。近年來,深度學習技術極大地推動了目標檢測的發展,涌現出許多優秀的算法,如 R-CNN 系列、YOLO 系列以及我們今天要重點介紹的單發多框檢測(Single Shot MultiBox Detector, SSD)。

SSD 是一種流行的單階段目標檢測器,以其在速度和精度之間的良好平衡而聞名。與兩階段檢測器(如 Faster R-CNN)先生成區域提議再進行分類和回歸不同,SSD 直接在不同尺度的特征圖上預測邊界框和類別,從而實現了更快的檢測速度。

本篇博客旨在通過一個具體的 PyTorch 實現(基于香蕉檢測數據集),帶領大家深入理解 SSD 的核心原理和代碼實現細節。我們將逐步剖析模型結構、損失函數、訓練過程以及預測可視化等關鍵環節,真正做到“從代碼中學習”。

完整代碼:下載鏈接

在深入 SSD 模型之前,我們先引入一些在整個項目中會用到的工具函數,它們主要負責數據處理、模型訓練輔助以及結果可視化。

工具函數

在實現和訓練 SSD 模型以及可視化結果的過程中,我們會用到一些輔助函數。這些函數分散在不同的工具文件中。

數據處理工具 (utils_for_data.py)

這部分代碼負責讀取和加載香蕉檢測數據集。read_data_bananas 函數讀取圖像和對應的 CSV 標簽文件,并將它們轉換成 PyTorch 張量。BananasDataset 類繼承了 torch.utils.data.Dataset,方便我們構建數據加載器。load_data_bananas 函數則利用 BananasDataset 創建了訓練和驗證數據的數據加載器(DataLoader)。

# --- START OF FILE utils_for_data.py ---import os
import pandas as pd
import torch
import torchvisiondef read_data_bananas(is_train=True):"""讀取香蕉檢測數據集中的圖像和標簽參數:is_train (bool): 是否讀取訓練集數據,True表示讀取訓練集,False表示讀取驗證集返回:tuple: (images, targets)- images: 圖像列表,每個元素是一個形狀為[C, H, W]的張量- targets: 標注信息張量,形狀為[N, 1, 5],每行包含[類別, 左上角x, 左上角y, 右下角x, 右下角y]"""# 設置數據目錄路徑data_dir = 'banana-detection'# 根據is_train確定使用訓練集還是驗證集路徑subset_name = 'bananas_train' if is_train else 'bananas_val'# 構建標簽CSV文件的完整路徑# csv_fname: 字符串,表示CSV文件的完整路徑csv_fname = os.path.join(data_dir, subset_name, 'label.csv')# 讀取CSV文件到pandas DataFrame# csv_data: DataFrame,包含圖像名稱和對應的標注信息csv_data = pd.read_csv(csv_fname)# 將img_name列設置為索引,便于后續訪問# csv_data: DataFrame,索引為圖像名稱,列為標注信息csv_data = csv_data.set_index('img_name')# 初始化存儲圖像和標注的列表# images: 列表,用于存儲讀取的圖像張量# targets: 列表,用于存儲對應的標注信息images, targets = [], []# 遍歷DataFrame中的每一行,讀取圖像和對應的標注信息for img_name, target in csv_data.iterrows():# 讀取圖像并添加到images列表中# img_name: 字符串,圖像文件名# 讀取的圖像: 張量,形狀為[C, H, W],C是通道數,H是高度,W是寬度images.append(torchvision.io.read_image(os.path.join(data_dir, subset_name, 'images', f'{img_name}')))# 添加標注信息到targets列表中# target: Series,包含類別和邊界框坐標信息# list(target): 列表,形狀為[5],包含[類別, 左上角x, 左上角y, 右下角x, 右下角y]targets.append(list(target))# 將targets列表轉換為張量,并添加一個維度,然后將值歸一化到0-1范圍# torch.tensor(targets): 張量,形狀為[N, 5],N是樣本數量# torch.tensor(targets).unsqueeze(1): 張量,形狀為[N, 1, 5]# 最終返回的targets: 張量,形狀為[N, 1, 5],值范圍在0-1之間targets_tensor = torch.tensor(targets).unsqueeze(1) / 256return images, targets_tensorclass BananasDataset(torch.utils.data.Dataset):"""一個用于加載香蕉檢測數據集的自定義數據集類繼承自torch.utils.data.Dataset基類,實現了必要的__init__、__getitem__和__len__方法用于提供數據加載器(DataLoader)訪問數據集的接口"""def __init__(self, is_train):"""初始化香蕉檢測數據集參數:is_train (bool): 是否加載訓練集數據,True表示加載訓練集,False表示加載驗證集屬性:self.features: 列表,包含所有圖像張量,每個張量形狀為[C, H, W]self.labels: 張量,形狀為[N, 1, 5],其中N是樣本數量,1是類別數量每個樣本包含[類別, 左上角x, 左上角y, 右下角x, 右下角y]"""# 調用read_data_bananas函數讀取數據集# self.features: 列表,包含N個形狀為[C, H, W]的圖像張量# self.labels: 張量,形狀為[N, 1, 5]self.features, self.labels = read_data_bananas(is_train)# 打印讀取的數據集信息dataset_type = '訓練樣本' if is_train else '驗證樣本'print(f'讀取了 {len(self.features)}{dataset_type}')def __getitem__(self, idx):"""獲取指定索引的樣本參數:idx (int): 樣本索引返回:tuple: (feature, label)- feature: 張量,形狀為[C, H, W],圖像數據,已轉換為float類型- label: 張量,形狀為[1, 5],對應的標注信息"""# 返回索引為idx的特征和標簽對# self.features[idx]: 張量,形狀為[C, H, W]# self.features[idx].float(): 將圖像張量轉換為float類型,形狀不變,仍為[C, H, W]# self.labels[idx]: 張量,形狀為[1, 5],包含一個目標的類別和邊界框信息return (self.features[idx].float(), self.labels[idx])def __len__(self):"""獲取數據集中樣本的數量返回:int: 數據集中的樣本數量"""# 返回數據集中的樣本數量# len(self.features): int,表示數據集中圖像的總數return len(self.features)def load_data_bananas(batch_size):"""加載香蕉檢測數據集,并創建數據加載器參數:batch_size (int): 批量大小,指定每次加載的樣本數量返回:tuple: (train_iter, val_iter)- train_iter: 訓練數據加載器,每次返回batch_size個訓練樣本每個批次包含:- 特征張量,形狀為[batch_size, C, H, W]- 標簽張量,形狀為[batch_size, 1, 5]- val_iter: 驗證數據加載器,每次返回batch_size個驗證樣本批次格式與train_iter相同"""# 創建訓練集數據加載器# BananasDataset(is_train=True): 實例化訓練集數據集對象# batch_size: 每個批次的樣本數量# shuffle=True: 打亂數據順序,增強模型的泛化能力# train_iter的每個批次包含:# - 特征張量,形狀為[batch_size, C, H, W],C是通道數,H是高度,W是寬度# - 標簽張量,形狀為[batch_size, 1, 5],每行包含[類別, 左上角x, 左上角y, 右下角x, 右下角y]train_iter = torch.utils.data.DataLoader(BananasDataset(is_train=True),batch_size=batch_size,shuffle=True)# 創建驗證集數據加載器# BananasDataset(is_train=False): 實例化驗證集數據集對象# batch_size: 每個批次的樣本數量# shuffle默認為False: 不打亂驗證數據的順序,保持一致性# val_iter的每個批次包含:# - 特征張量,形狀為[batch_size, C, H, W]# - 標簽張量,形狀為[batch_size, 1, 5]val_iter = torch.utils.data.DataLoader(BananasDataset(is_train=False),batch_size=batch_size)return train_iter, val_iter
# --- END OF FILE utils_for_data.py ---

訓練工具 (utils_for_train.py)

這部分包含通用的訓練輔助類。Timer 類用于記錄和計算代碼塊的執行時間。Accumulator 類則方便我們在訓練過程中累加損失、準確率等多個指標。try_gpu 函數嘗試獲取可用的 GPU 設備,否則回退到 CPU。

# --- START OF FILE utils_for_train.py ---import torch
import math   # 導入math包,用于計算指數
from torch import nn
import time
import numpy as np # 導入numpy 用于cumsum計算class Timer:"""記錄多次運行時間"""def __init__(self):"""Defined in :numref:`subsec_linear_model`"""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()class Accumulator:"""在 n 個變量上累加"""def __init__(self, n):"""初始化 Accumulator 類輸入:n: 需要累加的變量數量  # 輸入參數:變量數量輸出:無返回值  # 方法無顯式返回值"""self.data = [0.0] * n  # 初始化一個長度為 n 的浮點數列表,初始值為 0.0def add(self, *args):"""向累加器中添加多個值輸入:*args: 可變數量的數值,用于累加  # 輸入參數:可變參數,表示要累加的值輸出:無返回值  # 方法無顯式返回值"""self.data = [a + float(b) for a, b in zip(self.data, args)]  # 將輸入值累加到對應位置的數據上def reset(self):"""重置累加器中的所有值為 0輸入:無  # 方法無輸入參數輸出:無返回值  # 方法無顯式返回值"""self.data = [0.0] * len(self.data)  # 重置數據列表,所有值設為 0.0def __getitem__(self, idx):"""獲取指定索引處的值輸入:idx: 索引值  # 輸入參數:要訪問的數據索引輸出:float: 指定索引處的值  # 返回指定位置的累加值"""return self.data[idx]  # 返回指定索引處的數據值def try_gpu(i=0):"""如果存在,則返回gpu(i),否則返回cpu()Args:i (int, optional): GPU設備的編號,默認為0,表示嘗試使用第0號GPUReturns:torch.device: 返回可用的設備對象,如果指定編號的GPU可用則返回GPU,否則返回CPU"""# 檢查系統中可用的GPU數量是否大于等于i+1if torch.cuda.device_count() >= i + 1:# 如果條件滿足,返回指定編號i的GPU設備return torch.device(f'cuda:{i}')# 如果沒有足夠的GPU設備,返回CPU設備return torch.device('cpu')# --- END OF FILE utils_for_train.py ---

檢測相關工具 (utils_for_detection.py)

這是 SSD 實現的核心工具集。包含了以下關鍵功能:

  • 邊界框表示轉換: box_corner_to_centerbox_center_to_corner 用于在 (左上角, 右下角) 和 (中心點, 寬高) 兩種坐標表示法之間轉換。
  • 錨框生成: multibox_prior 根據輸入的特征圖、尺寸比例 (sizes) 和寬高比 (ratios) 生成大量的錨框。
  • IoU 計算: box_iou 計算兩組邊界框之間的交并比 (Intersection over Union),這是目標檢測中的基本度量。
  • 錨框分配: assign_anchor_to_bbox 將真實邊界框 (ground truth) 分配給最匹配的錨框。
  • 偏移量計算: offset_boxes 計算預測邊界框相對于錨框的偏移量(中心點坐標和寬高),這是回歸任務的目標。offset_inverse 則根據錨框和預測的偏移量反算出預測的邊界框坐標。
  • 目標生成: multibox_target 是關鍵函數,它整合了錨框分配和偏移量計算,為每個錨框生成對應的類別標簽和邊界框回歸目標。
  • 非極大值抑制 (NMS): nms 用于在預測階段去除高度重疊的冗余檢測框,保留置信度最高的框。
  • 多框檢測: multibox_detection 結合類別概率預測、邊界框偏移量預測、錨框以及 NMS,生成最終的檢測結果。
  • 可視化輔助: bbox_to_rect 將邊界框轉換為 Matplotlib 繪圖格式,show_bboxes 則用于在圖像上繪制邊界框和標簽。
# --- START OF FILE utils_for_detection.py ---import torch
import matplotlib.pyplot as plt
torch.set_printoptions(2)  # 精簡輸出精度def box_corner_to_center(boxes):"""將邊界框從(左上角,右下角)表示法轉換為(中心點,寬度,高度)表示法該函數接收以(x1, y1, x2, y2)格式表示的邊界框張量,其中:- (x1, y1):表示邊界框左上角的坐標- (x2, y2):表示邊界框右下角的坐標然后將其轉換為(cx, cy, w, h)格式,其中:- (cx, cy):表示邊界框中心點的坐標- w:表示邊界框的寬度- h:表示邊界框的高度參數:boxes (torch.Tensor): 形狀為(N, 4)的張量,包含N個邊界框的左上角和右下角坐標返回:torch.Tensor: 形狀為(N, 4)的張量,包含N個邊界框的中心點坐標、寬度和高度"""# 分別提取所有邊界框的左上角和右下角坐標x1, y1, x2, y2 = boxes[:, 0], boxes[:, 1], boxes[:, 2], boxes[:, 3]# 計算中心點坐標cx = (x1 + x2) / 2  # 中心點x坐標 = (左邊界x + 右邊界x) / 2cy = (y1 + y2) / 2  # 中心點y坐標 = (上邊界y + 下邊界y) / 2# 計算寬度和高度w = x2 - x1  # 寬度 = 右邊界x - 左邊界xh = y2 - y1  # 高度 = 下邊界y - 上邊界y# 將計算得到的中心點坐標、寬度和高度堆疊成新的張量boxes = torch.stack((cx, cy, w, h), axis=-1)return boxesdef box_center_to_corner(boxes):"""將邊界框從(中心點,寬度,高度)表示法轉換為(左上角,右下角)表示法該函數接收以(cx, cy, w, h)格式表示的邊界框張量,其中:- (cx, cy):表示邊界框中心點的坐標- w:表示邊界框的寬度- h:表示邊界框的高度然后將其轉換為(x1, y1, x2, y2)格式,其中:- (x1, y1):表示邊界框左上角的坐標- (x2, y2):表示邊界框右下角的坐標參數:boxes (torch.Tensor): 形狀為(N, 4)的張量,包含N個邊界框的中心點坐標、寬度和高度返回:torch.Tensor: 形狀為(N, 4)的張量,包含N個邊界框的左上角和右下角坐標"""# 分別提取所有邊界框的中心點坐標、寬度和高度cx, cy, w, h = boxes[:, 0], boxes[:, 1], boxes[:, 2], boxes[:, 3]# 計算左上角坐標x1 = cx - 0.5 * w  # 左邊界x = 中心點x - 寬度/2y1 = cy - 0.5 * h  # 上邊界y = 中心點y - 高度/2# 計算右下角坐標x2 = cx + 0.5 * w  # 右邊界x = 中心點x + 寬度/2y2 = cy + 0.5 * h  # 下邊界y = 中心點y + 高度/2# 將計算得到的左上角和右下角坐標堆疊成新的張量boxes = torch.stack((x1, y1, x2, y2), axis=-1)return boxesdef multibox_prior(data, sizes, ratios):"""生成以每個像素為中心具有不同形狀的錨框參數:data:輸入圖像張量,維度為(批量大小, 通道數, 高度, 寬度)sizes:錨框縮放比列表,元素個數為num_sizes,每個元素∈(0,1]ratios:錨框寬高比列表,元素個數為num_ratios,每個元素>0返回:輸出張量,維度為(1, 像素總數*每像素錨框數, 4),表示所有錨框的坐標"""# 獲取輸入數據的高度和寬度# in_height, in_width: 標量in_height, in_width = data.shape[-2:]# 獲取設備信息以及尺寸和比例的數量# device: 字符串; num_sizes, num_ratios: 標量device, num_sizes, num_ratios = data.device, len(sizes), len(ratios)# 計算每個像素點產生的錨框數量 = 尺寸數 + 寬高比數 - 1# boxes_per_pixel: 標量boxes_per_pixel = (num_sizes + num_ratios - 1)# 將尺寸和比例轉換為張量# size_tensor: 維度為(num_sizes,)# ratio_tensor: 維度為(num_ratios,)size_tensor = torch.tensor(sizes, device=device)ratio_tensor = torch.tensor(ratios, device=device)# 為了將錨點移動到像素的中心,需要設置偏移量# 因為一個像素的高為1且寬為1,我們選擇偏移中心0.5# offset_h, offset_w: 標量offset_h, offset_w = 0.5, 0.5# 計算高度和寬度方向上的步長(歸一化)# steps_h, steps_w: 標量steps_h = 1.0 / in_height  # 在y軸上縮放步長steps_w = 1.0 / in_width   # 在x軸上縮放步長# 生成錨框的所有中心點# center_h: 維度為(in_height,)# center_w: 維度為(in_width,)center_h = (torch.arange(in_height, device=device) + offset_h) * steps_hcenter_w = (torch.arange(in_width, device=device) + offset_w) * steps_w# 使用meshgrid生成網格坐標# shift_y, shift_x: 維度均為(in_height, in_width)shift_y, shift_x = torch.meshgrid(center_h, center_w, indexing='ij')# 將坐標展平為一維# shift_y, shift_x: 展平后維度均為(in_height*in_width,)shift_y, shift_x = shift_y.reshape(-1), shift_x.reshape(-1)# 生成"boxes_per_pixel"個高和寬,# 之后用于創建錨框的四角坐標(xmin,ymin,xmax,ymax)# 計算錨框寬度:先計算尺寸與第一個比例的組合,再計算第一個尺寸與其余比例的組合# w: 維度為(num_sizes + num_ratios - 1,)w = torch.cat((size_tensor * torch.sqrt(ratio_tensor[0]),sizes[0] * torch.sqrt(ratio_tensor[1:])))\* in_height / in_width  # 處理矩形輸入,調整寬度# 計算錨框高度:對應于寬度的計算方式# h: 維度為(num_sizes + num_ratios - 1,)h = torch.cat((size_tensor / torch.sqrt(ratio_tensor[0]),sizes[0] / torch.sqrt(ratio_tensor[1:]</

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

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

相關文章

基于STM32的溫濕度光照強度仿真設計(Proteus仿真+程序設計+設計報告+講解視頻)

這里寫目錄標題 **1.****主要功能****2.仿真設計****3.程序設計****4.設計報告****5.下載鏈接** 基于STM32的溫濕度光照強度仿真設計(Proteus仿真程序設計設計報告講解視頻&#xff09; 仿真圖Proteus 8.9 程序編譯器&#xff1a;keil 5 編程語言&#xff1a;C語言 設計編號…

SSH 服務部署指南

本指南涵蓋 OpenSSH 服務端的安裝、配置密碼/公鑰/多因素認證&#xff0c;以及連接測試方法。 適用系統&#xff1a;Ubuntu/Debian、CentOS/RHEL 等主流 Linux 發行版。 1. 安裝 SSH 服務端 Ubuntu/Debian # 更新軟件包索引 sudo apt update# 安裝 OpenSSH 服務端 sudo apt i…

《Python星球日記》 第46天:決策樹與隨機森林

名人說:路漫漫其修遠兮,吾將上下而求索。—— 屈原《離騷》 創作者:Code_流蘇(CSDN)(一個喜歡古詩詞和編程的Coder??) 專欄:《Python星球日記》,限時特價訂閱中ing 目錄 一、前言二、決策樹算法原理1. 決策樹簡介2. 決策樹的分裂準則(1) 信息熵與信息增益(2) 基尼不純…

Vue2:引入公共JS,通過this調用

tools.js // 圖片加上前綴 baseurl 是請求域名 img 是圖片路徑export function getimgurl(img) {return ${this.$baseurl}${img}}main.js import baseUrl from "/api/baseUrl.js" Vue.prototype.$baseurl baseUrlimport {getimgurl} from /api/tool.js; Vue.protot…

【Hot 100】 146. LRU 緩存

目錄 引言LRU 緩存官方解題LRU實現&#x1f4cc; 實現步驟分解步驟 1&#xff1a;定義雙向鏈表節點步驟 2&#xff1a;創建偽頭尾節點&#xff08;關鍵設計&#xff09;步驟 3&#xff1a;實現鏈表基礎操作操作 1&#xff1a;添加節點到頭部操作 2&#xff1a;移除任意節點 步驟…

【Linux】swap交換分區管理

目錄 一、Swap 交換分區的功能 二、swap 交換分區的典型大小的設置 2.1 查看交換分區的大小 2.1.1 free 2.1.2 cat /proc/swaps 或 swapon -s 2.1.3 top 三、使用交換分區的整體流程 3.1 案例一 3.2 案例二 一、Swap 交換分區的功能 計算機運行一個程序首先會將外存&am…

【計算機網絡】用戶從輸入網址到網頁顯示,期間發生了什么?

1.URL解析 瀏覽器分解URL&#xff1a;https://www.example.com/page 協議&#xff1a;https域名&#xff1a;www.example.com路徑&#xff1a;/page 2.DNS查詢&#xff1a; 瀏覽器向DNS服務器發送查詢請求&#xff0c;將域名解析為對應的IP地址。 3.CDN檢查(如果有)&#…

架空輸電線巡檢機器人軌跡優化設計

架空輸電線巡檢機器人軌跡優化 摘要 本論文針對架空輸電線巡檢機器人的軌跡優化問題展開研究,綜合考慮輸電線復雜環境、機器人運動特性及巡檢任務需求,結合路徑規劃算法、智能優化算法與機器人動力學約束,構建了多目標軌跡優化模型。通過改進遺傳算法與模擬退火算法,有效…

根據窗口大小自動調整頁面縮放比例,并保持居中顯示

vue 項目 直接上代碼 圖片u1.png 是個背景圖片 圖片u2.png 是個遮罩 <template><div id"app"><div class"viewBox"><divclass"screen":style"{ transform: translate(-50%,-50%…

初學Python爬蟲

文章目錄 前言一、 爬蟲的初識1.1 什么是爬蟲1.2 爬蟲的核心1.3 爬蟲的用途1.4 爬蟲分類1.5 爬蟲帶來的風險1.6. 反爬手段1.7 爬蟲網絡請求1.8 爬蟲基本流程 二、urllib庫初識2.1 http和https協議2.2 編碼解碼的使用2.3 urllib的基本使用2.4 一個類型六個方法2.5 下載網頁數據2…

oracle 數據庫sql 語句處理過程

14.1SQL語句處理過程 在進行SQL語句處理優化前&#xff0c;需要先熟悉和了解SQL語句的處理過程。 每種類型的語句在執行時都需要如下階段&#xff1a; 第1步: 創建游標。 第2步: 分析語句。 第5步: 綁定變量。 第7步: t運行語句。 第9步: 關閉游標。 如果使用了并行功能&#x…

pm2 list查詢服務時如何通過name或者namespace進行區分

在 PM2 中&#xff0c;如果 pm2 list 顯示的所有服務名稱&#xff08;name&#xff09;相同&#xff0c;就無法直觀地區分不同的進程。這時可以通過 --namespace&#xff08;命名空間&#xff09; 或 自定義 name 來區分服務。以下是解決方案&#xff1a; 方法 1&#xff1a;啟…

[python] 函數基礎

二 函數參數 2.1 必備參數(位置參數) 含義: 傳遞和定義參數的順序及個數必須一致 格式: def func(a,b) def func_1(id,passwd):print("id ",id)print("passwd ",passwd) func_1(10086,123456) 2.2 默認參數 函數: 為函數的參數提供一個默認值,如果調…

超大規模SoC后仿真流程與優化

在超大規模SoC設計中,是否需要進行全芯片后仿真(Full-Chip Post-layout Simulation)取決于多個因素,包括設計復雜度、項目風險、資源限制以及驗證目標。以下是針對這一問題的系統性分析: 1. 全芯片后仿真的必要性 需要全芯片后仿真的場景 系統級交互驗證: 跨模塊信號交互…

深入理解 Docker 網絡原理:構建高效、靈活的容器網絡

在現代軟件開發中&#xff0c;Docker 已經成為了容器化技術的代名詞&#xff0c;廣泛應用于開發、測試和生產環境。Docker 使得開發者能夠將應用及其依賴打包成一個輕量級的容器&#xff0c;并通過 Docker 容器化技術來實現高效的部署與管理。 然而&#xff0c;在日常使用 Dock…

leetcode 242. Valid Anagram

題目描述 因為s和t僅僅包含小寫字母&#xff0c;所以可以開一個26個元素的數組用來做哈希表。不過如果是unicode字符&#xff0c;那就用編程語言自帶的哈希表。 class Solution { public:bool isAnagram(string s, string t) {int n s.size();if(s.size() ! t.size())return …

4、反應釜壓力監控系統 - /自動化與控制組件/reaction-vessel-monitor

76個工業組件庫示例匯總 反應釜壓力監控組件 這是一個用于反應釜壓力監控的自定義組件&#xff0c;專為化工廠反應釜壓力監控設計。采用蘋果工業風格界面&#xff0c;簡潔優雅&#xff0c;功能實用&#xff0c;易于使用。 功能特點 實時壓力可視化&#xff1a;直觀展示反應…

系統思考助力富維東陽

剛剛完成了長春一家汽車零配件公司關于系統思考的項目&#xff01; 在開班儀式上&#xff0c;公司總經理深刻闡述了項目的背后意義&#xff0c;強調了系統思考與公司戰略的緊密聯系。這不僅是一次培訓&#xff0c;更是一次關于“如何全方位看待問題”的深度對話。 在這個過程中…

Linux下的c/c++開發之操作Sqlite3數據庫

libsqlite3-dev 介紹&#xff08;Linux 下的 SQLite3 C/C 開發包&#xff09; libsqlite3-dev 是一個開發包&#xff0c;在 Linux 環境下為使用 SQLite3 C API 進行開發的 C/C 程序員提供頭文件&#xff08;如 sqlite3.h&#xff09;和靜態庫/動態庫的鏈接信息&#xff08;如 …

【Prompt工程—文生圖】案例大全

目錄 一、人物繪圖 二、卡通頭像 三、風景圖 四、logo設計圖 五、動物形象圖 六、室內設計圖 七、動漫風格 八、二次元圖 九、日常場景圖 十、古風神化圖 十一、游戲場景圖 十二、電影大片質感 本文主要介紹了12種不同類型的文生圖技巧&#xff0c;通過加入不同的圖像…