第J1周:ResNet-50算法實戰與解析

🍨 本文為🔗365天深度學習訓練營 中的學習記錄博客
🍖 原作者:K同學啊

我的環境
語言環境:Python3.8·
編譯器:Jupyter Lab
深度學習環境:Pytorchtorch1.12.1+cu113
torchvision
0.13.1+cu113

一、準備工作

在這里插入圖片描述

二、導入數據

在這里插入圖片描述

三、劃分數據集

在這里插入圖片描述
在這里插入圖片描述

四、搭建網絡

import torch
import torch.nn as nn
import torchsummary as summary
import torchvision.models as modelsdef identity_block(input_tensor, kernel_size, filters, stage, block):"""構建殘差網絡的恒等映射塊Args:input_tensor: 輸入張量kernel_size: 卷積核大小filters: [f1, f2, f3] 形式的過濾器數量列表stage: 階段編號block: 塊編號"""filters1, filters2, filters3 = filtersname_base = f'{stage}{block}_identity_block_'# 第一個 1x1 卷積層x = nn.Conv2d(input_tensor.size(1), filters1, 1, bias=False)(input_tensor)x = nn.BatchNorm2d(filters1)(x)x = nn.ReLU(inplace=True)(x)# 3x3 卷積層x = nn.Conv2d(filters1, filters2, kernel_size, padding=kernel_size//2, bias=False)(x)x = nn.BatchNorm2d(filters2)(x)x = nn.ReLU(inplace=True)(x)# 第二個 1x1 卷積層x = nn.Conv2d(filters2, filters3, 1, bias=False)(x)x = nn.BatchNorm2d(filters3)(x)# 添加跳躍連接x = x + input_tensorx = nn.ReLU(inplace=True)(x)return xdef conv_block(input_tensor, kernel_size, filters, stage, block, strides=(2,2)):"""構建殘差網絡的卷積塊Args:input_tensor: 輸入張量kernel_size: 卷積核大小filters: [f1, f2, f3] 形式的過濾器數量列表stage: 階段編號block: 塊編號strides: 步長元組"""filters1, filters2, filters3 = filtersname_base = f'{stage}{block}_conv_block_'# 主路徑x = nn.Conv2d(input_tensor.size(1), filters1, 1, stride=strides, bias=False)(input_tensor)x = nn.BatchNorm2d(filters1)(x)x = nn.ReLU(inplace=True)(x)x = nn.Conv2d(filters1, filters2, kernel_size, padding=kernel_size//2, bias=False)(x)x = nn.BatchNorm2d(filters2)(x)x = nn.ReLU(inplace=True)(x)x = nn.Conv2d(filters2, filters3, 1, bias=False)(x)x = nn.BatchNorm2d(filters3)(x)# shortcut 路徑shortcut = nn.Conv2d(input_tensor.size(1), filters3, 1, stride=strides, bias=False)(input_tensor)shortcut = nn.BatchNorm2d(filters3)(shortcut)# 添加跳躍連接x = x + shortcutx = nn.ReLU(inplace=True)(x)return xdef ResNet50(input_shape=[224,224,3], num_classes=1000):"""構建 ResNet50 模型Args:input_shape: 輸入圖像的形狀 [H, W, C]num_classes: 分類類別數"""# 輸入層inputs = torch.randn(1, input_shape[2], input_shape[0], input_shape[1])# 初始卷積塊 - 修改 ZeroPadding2d 為 pad 操作x = nn.functional.pad(inputs, (3, 3, 3, 3))  # 替換 ZeroPadding2dx = nn.Conv2d(input_shape[2], 64, 7, stride=2, bias=False)(x)x = nn.BatchNorm2d(64)(x)x = nn.ReLU(inplace=True)(x)x = nn.MaxPool2d(3, stride=2, padding=1)(x)# Stage 2x = conv_block(x, 3, [64, 64, 256], stage=2, block='a', strides=(1,1))x = identity_block(x, 3, [64, 64, 256], stage=2, block='b')x = identity_block(x, 3, [64, 64, 256], stage=2, block='c')# Stage 3x = conv_block(x, 3, [128, 128, 512], stage=3, block='a')x = identity_block(x, 3, [128, 128, 512], stage=3, block='b')x = identity_block(x, 3, [128, 128, 512], stage=3, block='c')x = identity_block(x, 3, [128, 128, 512], stage=3, block='d')# Stage 4x = conv_block(x, 3, [256, 256, 1024], stage=4, block='a')for block in ['b', 'c', 'd', 'e', 'f']:x = identity_block(x, 3, [256, 256, 1024], stage=4, block=block)# Stage 5x = conv_block(x, 3, [512, 512, 2048], stage=5, block='a')x = identity_block(x, 3, [512, 512, 2048], stage=5, block='b')x = identity_block(x, 3, [512, 512, 2048], stage=5, block='c')# 分類層x = nn.AdaptiveAvgPool2d((1, 1))(x)x = torch.flatten(x, 1)x = nn.Linear(2048, num_classes)(x)# 修改模型創建和前向傳播的方式class ResNet(nn.Module):def __init__(self):super(ResNet, self).__init__()# 在這里定義所有層def forward(self, x):# 定義前向傳播return xmodel = ResNet()# 移除 load_weights,改用 PyTorch 的加載方式model.load_state_dict(torch.load("resnet50_pretrained.pth"))return modelmodel = models.resnet50().to(device)
model
ResNet((conv1): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True)(maxpool): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)(layer1): Sequential((0): Bottleneck((conv1): Conv2d(64, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn3): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True)(downsample): Sequential((0): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)))(1): Bottleneck((conv1): Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn3): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True))(2): Bottleneck((conv1): Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn3): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True)))(layer2): Sequential((0): Bottleneck((conv1): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)(bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True)(downsample): Sequential((0): Conv2d(256, 512, kernel_size=(1, 1), stride=(2, 2), bias=False)(1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)))(1): Bottleneck((conv1): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True))(2): Bottleneck((conv1): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True))(3): Bottleneck((conv1): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True)))(layer3): Sequential((0): Bottleneck((conv1): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True)(downsample): Sequential((0): Conv2d(512, 1024, kernel_size=(1, 1), stride=(2, 2), bias=False)(1): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)))(1): Bottleneck((conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True))(2): Bottleneck((conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True))(3): Bottleneck((conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True))(4): Bottleneck((conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True))(5): Bottleneck((conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True)))(layer4): Sequential((0): Bottleneck((conv1): Conv2d(1024, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)(bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv3): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn3): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True)(downsample): Sequential((0): Conv2d(1024, 2048, kernel_size=(1, 1), stride=(2, 2), bias=False)(1): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)))(1): Bottleneck((conv1): Conv2d(2048, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv3): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn3): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True))(2): Bottleneck((conv1): Conv2d(2048, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv3): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn3): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True)))(avgpool): AdaptiveAvgPool2d(output_size=(1, 1))(fc): Linear(in_features=2048, out_features=1000, bias=True)
)

五、編寫訓練函數和測試函數

在這里插入圖片描述
在這里插入圖片描述

六、設置超參數

在這里插入圖片描述

七、訓練

在這里插入圖片描述

在這里插入圖片描述

八、可視化

在這里插入圖片描述

在這里插入圖片描述

八、總結

ResNet是由微軟研究院提出的,應該是在2015年的ImageNet競賽中取得了很好的成績。殘差塊是它的核心概念,對吧?殘差塊通過跳躍連接(shortcut connections)將輸入直接傳遞到后面的層,這樣可以讓網絡更容易訓練深層結構。那ResNet-50中的50層具體是怎么組成的呢?

ResNet有不同的版本,比如ResNet-18、34、50、101、152,數字代表層數。50層的應該比更小的版本更深,結構更復雜。那ResNet-50的結構具體是怎樣的?可能由多個殘差塊堆疊而成,每個殘差塊里面有幾個卷積層?

對了,ResNet中的殘差塊有兩種類型,一種是基礎的殘差塊,用于較淺的網絡如ResNet-34,另一種是瓶頸結構(bottleneck),可能用于更深的網絡如ResNet-50。瓶頸結構應該是指通過1x1的卷積層先減少通道數,再做3x3的卷積,然后再用1x1恢復通道數,這樣可以減少計算量,同時保持網絡深度。

所以ResNet-50可能由多個這樣的瓶頸塊組成。那每個階段的塊數應該是怎樣的?比如,可能有四個階段(stage),每個階段包含不同數量的殘差塊。比如第一個階段可能處理較大的特征圖,之后每個階段通過步長為2的卷積進行下采樣,特征圖尺寸減半,通道數增加。

比如,初始的層可能是一個7x7的卷積層,接著是池化層,然后是四個階段的殘差塊。每個階段的塊數目可能是3,4,6,3,這樣加起來總層數可能達到50層?需要計算一下每個塊貢獻的層數。瓶頸塊每個塊包含三個卷積層:1x1,3x3,1x1。所以每個塊有3層,四個階段的塊數如果是3,4,6,3,總塊數是3+4+6+3=16個塊,每個塊3層,就是16 * 3=48層,加上前面的7x7卷積層和池化層,還有最后的全連接層,可能總數接近50層?所以ResNet-50的結構大致如此。

另外,跳躍連接的結構可能有不同的處理方式,當輸入和輸出的通道數或尺寸不一致時,可能用1x1的卷積來調整通道數或進行下采樣。例如,在進入每個階段的第一個殘差塊時,可能需要調整shortcut連接的通道數,這時會使用一個1x1卷積,步長為2來減小尺寸并調整通道數。

那ResNet-50的創新點主要是殘差學習和瓶頸結構,這樣可以讓網絡更深而不出現梯度消失的問題。傳統深層網絡訓練時,隨著層數增加,準確率會飽和甚至下降,而殘差網絡通過引入跳躍連接,使得網絡更容易學習恒等映射,從而讓訓練更深的網絡變得可行。

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

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

相關文章

養生:健康生活的極簡攻略

在追求高效生活的當下,養生也能化繁為簡。通過飲食、運動、睡眠與心態的精準調節,就能輕松為健康續航。 飲食上,遵循 “均衡、節制” 原則。早餐用一杯熱豆漿搭配水煮蛋和半個蘋果,喚醒腸胃活力;午餐以糙米飯為主食&am…

遷移 Visual Studio Code 設置和擴展到 VSCodium

本文同步發布在個人博客 遷移 Visual Studio Code 設置和擴展到 VSCodium - 萑澈的寒舍https://hs.cnies.org/archives/vscodium-migrateVisual Studio Code(以下簡稱 VS Code)無疑是當下最常用的代碼編輯器。盡管微軟的 VS Code 源代碼采用 MIT 協議開…

力扣654題:最大二叉樹(遞歸)

小學生一枚,自學信奧中,沒參加培訓機構,所以命名不規范、代碼不優美是在所難免的,歡迎指正。 標簽: 二叉樹、遞歸 語言: C 題目: 給定一個不重復的整數數組 nums 。最大二叉樹可以用下面的算…

離散制造企業WMS+MES+QMS+條碼管理系統高保真原型全解析

在離散型制造企業的生產過程中,庫存管理混亂、生產進度不透明、質檢流程繁瑣等問題常常成為制約企業發展的瓶頸。為了幫助企業實現全流程數字化管控,我們精心打造了一款基于離散型制造企業(涵蓋單件生產、批量生產、混合生產模式)…

Linux操作系統--進程間通信(system V共享內存)

目錄 1.system V共享內存 2.共享內存數據結構 3.共享內存函數 4.實例代碼: 1.system V共享內存 共享內存區是最快的IPC(進程間通信)形式。一旦這樣的內存映射到共享它的進程地址空間,這些進程間數據傳遞不再涉及到內核,換句話說是進程不再…

【C++】類與對象

目錄 1、類的定義 2、類的訪問限定符及封裝 3、類的實例化 4、類和對象的大小 5、this 指針 6、類的六個默認成員函數 構造函數 析構函數 拷貝構造函數 賦值重載函數 取地址運算符的重載函數 7、運算符重載 8、const 成員函數 9、 static 成員 10、友元 11、…

現代簡約中式通用,民國畫報風,中國風PPT模版8套一組分享

中國風PPT模版分享:中國風PPT模版分享https://pan.quark.cn/s/abbf75507c5f 第1套PPT模版:棕色調中式窗欞封面,水墨山水背景配白梅與燈籠流蘇,適用于教學課件目錄設計,展現濃郁的書卷氣息。 第2套PPT模版:米…

django擴展練習記錄

一、Django 中使用 django-apscheduler 實現定時任務 可以方便地管理周期性任務(如每天清理緩存、定時發送郵件等) 1. 安裝 pip install django-apscheduler -i https://pypi.tuna.tsinghua.edu.cn/simple #0.7.02.添加到應用,python m…

Guided Filtering相關記錄

一、背景介紹 以前折騰保邊濾波時候,刷了一些Guided Filtering相關資料。這里主要是對它們做個算法效果復現和資料簡單整理。 二、Guided Filtering 1、基本原理 原版Guided Filtering的提出,主要是為了改善雙邊濾波做保邊平滑濾波器時候的梯度翻轉偽影…

知識圖譜系列(2):知識圖譜的技術架構與組成要素

1. 引言 知識圖譜作為一種強大的知識表示和組織方式,已經在搜索引擎、推薦系統、智能問答等多個領域展現出巨大的價值。在之前的上一篇文章中,我們介紹了知識圖譜的基礎概念與發展歷程,了解了知識圖譜的定義、核心特征、發展歷史以及在AI發展中的地位與作用。 要深入理解和…

操作系統|| 虛擬內存頁置換算法

題目 寫一個程序來實現 FIFO 和 LRU 頁置換算法。首先,產生一個隨機的頁面引用序列,頁面數從 0~9。將這個序列應用到每個算法并記錄發生的頁錯誤的次數。實現這個算法時要將頁幀的數量設為可變。假設使用請求調頁。可以參考所示的抽象類。 抽象類&…

開發與AI融合的Windsurf編輯器

Windsurf編輯器是開發人員和人工智能真正融合在一起的地方,提供了一種感覺像文字魔術的編碼體驗。 手冊:Windsurf - Getting Started 下載鏈接:Download Windsurf Editor for Windows | Windsurf (formerly Codeium) 下載安裝 從上面的下載…

【Java】網絡編程(Socket)

網絡編程 Socket 我們開發的網絡應用程序位于應用層,TCP和UDP屬于傳輸層協議,在應用層如何使用傳輸層的服務呢?在應用層和傳輸層之間,則使用套接字Socket來進行分離 套接字就像是傳輸層為應用層開的一個小口,應用程…

【教程】Docker方式本地部署Overleaf

轉載請注明出處:小鋒學長生活大爆炸[xfxuezhagn.cn] 如果本文幫助到了你,歡迎[點贊、收藏、關注]哦~ 目錄 背景說明 下載倉庫 初始化配置 修改監聽IP和端口 自定義網站名稱 修改數據存放位置 更換Docker源 更換Docker存儲位置 啟動Overleaf 創…

根據用戶ID獲取所有子節點數據或是上級直屬節點數據

一、根據用戶ID獲取所有子節點,通過存儲過程來實現 CREATE DEFINERcrmeb% PROCEDURE proc_get_user_all_children( IN rootUid INTEGER, -- 要查詢的根用戶ID IN includeSelf BOOLEAN -- 是否包含自身(1包含,0不包含) ) BEGIN -- 聲明變…

計算機組成原理——數據的表示

2.1數據的表示 整理自Beokayy_ 1.進制轉換 十六進制與二進制的轉換 一位十六進制等于四位二進制 四位二進制等于一位十六進制 0x173A4C0001 0111 0011 1010 0100 1100 十六進制與十進制的轉換 十六轉十:每一位數字乘以相應的16的冪再相加 十轉十六&#xff1a…

基于MATLAB-GUI圖形界面的數字圖像處理

基于MATLAB GUI的數字圖像處理系統實現方案,包含常見圖像處理功能。代碼分為兩部分:GUI界面設計和回調函數實現。 %% 第一部分:創建GUI界面 (使用GUIDE) % 1. 打開GUIDE: guide % 2. 創建新GUI,添加以下控件: % - …

從裸機開發到實時操作系統:FreeRTOS詳解與實戰指南

從裸機開發到實時操作系統:FreeRTOS詳解與實戰指南 本文將帶你從零開始,深入理解嵌入式系統中的裸機開發與實時操作系統,以FreeRTOS為例,全面剖析其核心概念、工作原理及應用場景。無論你是嵌入式新手還是希望提升技能的開發者&am…

zabbix7.2最新版本 nginx自定義監控(三) 設置觸發器

安裝zabbix-get服務 在zabbix-server端口安裝zabbix-get服務 [rootlocalhost ~]# dnf install -y zabbix-get Last metadata expiration check: 1:55:49 ago on Wed 14 May 2025 09:24:49 AM CST. Dependencies resolved. Package Architectur…

在 Kotlin 中,什么是解構,如何使用?

在 Kotlin 中,解構是一種語法糖,允許將一個對象分解為多個獨立的變量。 這種特性可以讓代碼更簡潔、易讀,尤其適用于處理數據類、集合(如 Pair、Map)或其他結構化數據。 1 解構的核心概念 解構通過定義 componentN()…