主頁 >  其他 > PANet:基于金字塔注意力網路的影像超解析度重建(Pytorch實作)

PANet:基于金字塔注意力網路的影像超解析度重建(Pytorch實作)

2021-09-26 15:47:40 其他

PANet:基于金字塔注意力網路的影像超解析度重建

[!] 為了提高代碼的可讀性,本文模型的具體實作與原文具有一定區別,因此會造成性能上的差異


文章目錄

  • PANet:基于金字塔注意力網路的影像超解析度重建
  • 1.相關資料
  • 2.簡介
  • 3.模型結構
  • 4.專案實踐
    • 4.1 準備作業
    • 4.2 具體實作
      • 4.2.1 匯入專案所需庫
      • 4.2.2 構建資料集
      • 4.2.3 構建網路模型
        • # 特征金字塔部分
        • # 模型部分
      • 4.2.4 準備訓練配件
        • # 優化器
        • # 損失函式
        • # 評估標準
          • ## PSRN
          • ## SSIM
      • 4.2.5 構建訓練框架
      • 4.2.6 訓練結果


1.相關資料

  • 論文下載地址: 傳送門
  • 原作者代碼地址:傳送門
  • 完整代碼地址:傳送門

2.簡介

  • PANet(Pyramid Attention with Simple Network Backbones)是一種基于影像恢復金字塔注意力模塊的影像修復模型,它能夠從多尺度特征金字塔種提取到長距離與短距離的特征關系,
  • 受降采樣能夠有效減少壓縮偽影等影像噪聲的啟發,作者所提出的金字塔利用不同采樣倍數的特征圖來相互傳遞注意力信號,以更靈活的方式來借用不同特征尺寸之間的“干凈”資訊,
  • 作者只在一個簡單的前饋鏈接網路中加入了一個金字塔注意力模塊,就在絕大多數影像修復任務中達到了SOTA,(這樣看來模塊確實牛逼)

3.模型結構

直接上圖
模型結構

  • 圖上面部分就是傳說中的金字塔注意力模塊,圖下面部分就是PANet的結構(這個結構和SRResNet怪像的,可以參考我的相關文章:SRResNet和SRGAN)
  • 金字塔注意力模塊的結構分為兩個部分:金字塔采樣環節S-A Attention,金字塔采樣環節就是簡單的降采樣處理,根據源代碼來看,作者使用的是雙二次下采樣的方法,
  • S-A Attention的結構參考了NLP中最經典的注意力機制結構,即構建了Q,K,V三種特征圖來捕獲影像在不同尺寸中的資訊,與其他注意力機制不同的是,S-A Attention將注意力機制中的按元素相乘環節改成將Q和K特征圖作為卷積核(即圖中淺藍色特征層出來的兩個特征圖)來與V特征圖進行卷積/反卷積操作,

4.專案實踐

在這里我會一步一步教大家做一個能夠成功運行的PANet,完整的代碼也會很快推出,

4.1 準備作業

  • 筆者使用的作業環境如下所示:

    系統:Windows 10
    CPU:Intel Core i9-10850K
    GPU:GeForce RTX 3090
    
  • 實作代碼所需要準備的庫為:

    Pytorch
    OpenCV
    Numpy
    Torchvision
    
  • 本文使用的是COCO 2017資料集,其中包含了123,403張照片,大家可以根據自己的需要來使用自己的資料集,

4.2 具體實作

為了方便閱讀,部分代碼已標注中文注釋,而且全部放進了一個代碼檔案中

  • 完整版代碼支持重新打開代碼自動恢復到上次訓練的功能,只需要關注筆者即可獲得:傳送門

4.2.1 匯入專案所需庫

import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.utils.data import DataLoader,Dataset,SubsetRandomSampler
import torch.optim as optim
from torchvision import utils as vutils
from torchvision.utils import save_image

import os
import cv2
import random as ra
import numpy as np
import math

4.2.2 構建資料集

class PreprocessDataset(Dataset):
   def __init__(self,path,size = 96):
       super().__init__()
       self.size = size  #高清影像的尺寸,這里默認為96x96

       self.allImgs = list()
       for root,dirs,files in os.walk(path):
           self.allImgs = [os.path.join(root,file) for file in files] #獲取影像的地址

           
   def __len__(self):
       return len(self.allImgs)
   
   def __getitem__(self,index):
       img = self.allImgs[index]
       img = cv2.imread(img)            
       img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
       height,width,_ = img.shape
 
       xStart = ra.randint(0,width-self.size-1)
       yStart = ra.randint(0,height-self.size-1)

       img = img[yStart:self.size + yStart,xStart:self.size + xStart,:]  #隨機裁剪影像
           
       if ra.random() > 0.5:
           img = cv2.flip(img,1)  #有50%幾率反轉影像
       
       hr = torch.tensor(np.transpose(img,(2,0,1)))/255.0
       hr = (hr - 0.5)/0.5  #像素標準化
       lr = F.max_pool2d(hr,2) #使用最大池化來獲得下采樣圖片
       
       return hr,lr
  • 構建完資料集類后,我們可以很方便地構建對應的Dataloader,在這里我只構建了訓練集,并沒有構建測驗集,

    path = '你的資料集檔案路徑'
    
    
    dataset = PreprocessDataset(path,size = 96)
    trainData = DataLoader(dataset,batch_size = 32,num_workers = 4,shuffle = True)
    

4.2.3 構建網路模型

# 特征金字塔部分

  • 這里直接改進了原作者的金字塔注意力模塊代碼,因此代碼風格會與其他部分有一定差異,
    def extract_image_patches(images, ksizes, strides, rates, padding='same'):
        """
        Extract patches from images and put them in the C output dimension.
        :param padding:
        :param images: [batch, channels, in_rows, in_cols]. A 4-D Tensor with shape
        :param ksizes: [ksize_rows, ksize_cols]. The size of the sliding window for
         each dimension of images
        :param strides: [stride_rows, stride_cols]
        :param rates: [dilation_rows, dilation_cols]
        :return: A Tensor
        """
        assert len(images.size()) == 4
        assert padding in ['same', 'valid']
        batch_size, channel, height, width = images.size()
        
        if padding == 'same':
            images = same_padding(images, ksizes, strides, rates)
        elif padding == 'valid':
            pass
        else:
            raise NotImplementedError('Unsupported padding type: {}.\
                    Only "same" or "valid" are supported.'.format(padding))
    
        unfold = torch.nn.Unfold(kernel_size=ksizes,
                                 dilation=rates,
                                 padding=0,
                                 stride=strides)
        patches = unfold(images)
        return patches  # [N, C*k*k, L], L is the total number of such blocks
    
    def reduce_sum(x, axis=None, keepdim=False):
        if not axis:
            axis = range(len(x.shape))
        for i in sorted(axis, reverse=True):
            x = torch.sum(x, dim=i, keepdim=keepdim)
        return x
    
    def same_padding(images, ksizes, strides, rates):
        assert len(images.size()) == 4
        batch_size, channel, rows, cols = images.size()
        out_rows = (rows + strides[0] - 1) // strides[0]
        out_cols = (cols + strides[1] - 1) // strides[1]
        effective_k_row = (ksizes[0] - 1) * rates[0] + 1
        effective_k_col = (ksizes[1] - 1) * rates[1] + 1
        padding_rows = max(0, (out_rows-1)*strides[0]+effective_k_row-rows)
        padding_cols = max(0, (out_cols-1)*strides[1]+effective_k_col-cols)
        # Pad the input
        padding_top = int(padding_rows / 2.)
        padding_left = int(padding_cols / 2.)
        padding_bottom = padding_rows - padding_top
        padding_right = padding_cols - padding_left
        paddings = (padding_left, padding_right, padding_top, padding_bottom)
        images = torch.nn.ZeroPad2d(paddings)(images)
        return images
    
    def default_conv(in_channels, out_channels, kernel_size,stride=1, bias=True):
        return nn.Conv2d(
            in_channels, out_channels, kernel_size,
            padding=(kernel_size//2),stride=stride, bias=bias)
    
    class BasicBlock(nn.Sequential):
        def __init__(
            self, conv, in_channels, out_channels, kernel_size, stride=1, bias=True,
            bn=False, act=nn.PReLU()):
    
            m = [conv(in_channels, out_channels, kernel_size, bias=bias)]
            if bn:
                m.append(nn.BatchNorm2d(out_channels))
            if act is not None:
                m.append(act)
    
            super(BasicBlock, self).__init__(*m)
    
    class PyramidAttention(nn.Module):
        def __init__(self, level=5, res_scale=1, channel=64, reduction=2, ksize=3, stride=1, softmax_scale=10, average=True, conv=default_conv):
            super(PyramidAttention, self).__init__()
            self.ksize = ksize
            self.stride = stride
            self.res_scale = res_scale
            self.softmax_scale = softmax_scale
            self.scale = [1-i/10 for i in range(level)]
            self.average = average
            escape_NaN = torch.FloatTensor([1e-4])
            self.register_buffer('escape_NaN', escape_NaN)
            self.conv_match_L_base = BasicBlock(conv,channel,channel//reduction, 1, bn=False, act=nn.PReLU())
            self.conv_match = BasicBlock(conv,channel, channel//reduction, 1, bn=False, act=nn.PReLU())
            self.conv_assembly = BasicBlock(conv,channel, channel,1,bn=False, act=nn.PReLU())
    
        def forward(self, input):
            res = input
            #theta
            match_base = self.conv_match_L_base(input)
            shape_base = list(res.size())
            input_groups = torch.split(match_base,1,dim=0)
            # patch size for matching 
            kernel = self.ksize
            # raw_w is for reconstruction
            raw_w = []
            # w is for matching
            w = []
            #build feature pyramid
            for i in range(len(self.scale)):    
                ref = input
                if self.scale[i]!=1:
                    ref  = F.interpolate(input, scale_factor=self.scale[i], mode='bicubic',
                    align_corners=True,recompute_scale_factor=True)
                #feature transformation function f
                base = self.conv_assembly(ref)
                shape_input = base.shape
                #sampling
                raw_w_i = extract_image_patches(base, ksizes=[kernel, kernel],
                                          strides=[self.stride,self.stride],
                                          rates=[1, 1],
                                          padding='same') # [N, C*k*k, L]
                raw_w_i = raw_w_i.view(shape_input[0], shape_input[1], kernel, kernel, -1)
                raw_w_i = raw_w_i.permute(0, 4, 1, 2, 3)    # raw_shape: [N, L, C, k, k]
                raw_w_i_groups = torch.split(raw_w_i, 1, dim=0)
                raw_w.append(raw_w_i_groups)
    
                #feature transformation function g
                ref_i = self.conv_match(ref)
                shape_ref = ref_i.shape
                #sampling
                w_i = extract_image_patches(ref_i, ksizes=[self.ksize, self.ksize],
                                      strides=[self.stride, self.stride],
                                      rates=[1, 1],
                                      padding='same')
                w_i = w_i.view(shape_ref[0], shape_ref[1], self.ksize, self.ksize, -1)
                w_i = w_i.permute(0, 4, 1, 2, 3)    # w shape: [N, L, C, k, k]
                w_i_groups = torch.split(w_i, 1, dim=0)
                w.append(w_i_groups)
    
            y = []
            for idx, xi in enumerate(input_groups):
                #group in a filter
                wi = torch.cat([w[i][idx][0] for i in range(len(self.scale))],dim=0)  # [L, C, k, k]
                #normalize
                max_wi = torch.max(torch.sqrt(reduce_sum(torch.pow(wi, 2),
                                                         axis=[1, 2, 3],
                                                         keepdim=True)),
                                   self.escape_NaN)
                wi_normed = wi/ max_wi
                #matching
                xi = same_padding(xi, [self.ksize, self.ksize], [1, 1], [1, 1])  # xi: 1*c*H*W
                yi = F.conv2d(xi, wi_normed, stride=1)   # [1, L, H, W] L = shape_ref[2]*shape_ref[3]
                yi = yi.view(1,wi.shape[0], shape_base[2], shape_base[3])  # (B=1, C=32*32, H=32, W=32)
                # softmax matching score
                yi = F.softmax(yi*self.softmax_scale, dim=1)
                
                if self.average == False:
                    yi = (yi == yi.max(dim=1,keepdim=True)[0]).float()
                
                # deconv for patch pasting
                raw_wi = torch.cat([raw_w[i][idx][0] for i in range(len(self.scale))],dim=0)
                yi = F.conv_transpose2d(yi, raw_wi, stride=self.stride,padding=1)/4.
                y.append(yi)
          
            y = torch.cat(y, dim=0)+res*self.res_scale  # back to the mini-batch
            return y
    

# 模型部分

  • PANet使用的是SRResNet的骨干

    class ResBlock(nn.Module):
        def __init__(self,inChannals):
            super().__init__()
            self.model = nn.Sequential(
                nn.Conv2d(inChannals,inChannals,kernel_size = 1,bias = False),
                nn.BatchNorm2d(inChannals),
                nn.ReLU(inplace = True),
                nn.Conv2d(inChannals,inChannals,kernel_size = 3,stride = 1,
                          padding = 1,bias = False,padding_mode = 'reflect'),
                nn.BatchNorm2d(inChannals)
            )
            
        def forward(self,input):
            return F.relu(input + self.model(input),inplace = True)
    
    class Sequential(nn.Sequential):
        def __init__(self,inChannals,blockNum = 8):
            seq = [ResBlock(inChannals) for _ in range(blockNum)]
            seq.insert(int(blockNum/2),PyramidAttention(channel=inChannals, level=4))
            super().__init__(*seq)
            
    class Model(nn.Module):
        def __init__(self,channals = 64,blockNum = 6):
            super().__init__()
            self.features = nn.Sequential(
                nn.Conv2d(3,channals,kernel_size = 7,padding = 3,stride = 1,
                          padding_mode = 'reflect',bias = False),
                nn.BatchNorm2d(channals),
                nn.ReLU(inplace = True),
                nn.Conv2d(channals,channals,kernel_size = 3,padding = 1,stride = 1,
                         padding_mode = 'reflect',bias = False),
                nn.BatchNorm2d(channals),
                nn.ReLU(inplace = True)
            )
            
            self.sequential = Sequential(channals,blockNum)
            
            self.upSample = nn.Sequential(
                nn.Conv2d(channals,channals * 4,kernel_size = 3,padding = 1,stride = 1,
                         padding_mode = 'reflect'),
                
                nn.PixelShuffle(2),
                nn.Conv2d(channals,channals,kernel_size = 3,padding = 1,stride = 1),
                nn.ReLU(inplace = True),
                nn.Conv2d(channals,3,kernel_size = 1,stride = 1),
                nn.Tanh()
            )
            
        def forward(self,input):
            features = self.features(input)
            output = self.sequential(features)
            output = features + output
            output = self.upSample(output)
    
            return output
    
  • 最后,通過簡單的方式我們便可構建一個模型

    #如果電腦可以使用顯卡,則自動使用顯卡加速
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    #創建網路模型 
    net = Model(channals = 64,blockNum = 24).to(device)
    

4.2.4 準備訓練配件

  • 為了對模型進行訓練和驗證,我們需要以下部件:優化器Optimizer損失函式Criteria評估標注

# 優化器

  • 優化器我們使用了AdamW
    optimizer = optim.AdamW(net.parameters(),lr = 1e-4)
    

# 損失函式

  • 損失函式我們參考了原作者,使用了L1 Loss
    criteria = nn.L1Loss()
    

# 評估標準

  • 我們使用了SSIMPSRN兩種標注,他們的代碼如下所示:
## PSRN
  • 代碼如下:
    def PSRN(img1, img2):
        mse = torch.mean((img1 - img2) ** 2)
        if mse < 1.0e-10:
            return 100
        return 10 * math.log10(255.0**2/mse)
    
## SSIM
  • 代碼如下:
    def gaussian(window_size, sigma):
        gauss = torch.Tensor([exp(-(x - window_size//2)**2/float(2*sigma**2)) for x in range(window_size)])
        return gauss/gauss.sum()
    
    def create_window(window_size, channel):
        _1D_window = gaussian(window_size, 1.5).unsqueeze(1)
        _2D_window = _1D_window.mm(_1D_window.t()).float().unsqueeze(0).unsqueeze(0)
        window = Variable(_2D_window.expand(channel, 1, window_size, window_size).contiguous())
        return window
    
    def _ssim(img1, img2, window, window_size, channel, size_average = True):
        mu1 = F.conv2d(img1, window, padding = window_size//2, groups = channel)
        mu2 = F.conv2d(img2, window, padding = window_size//2, groups = channel)
    
        mu1_sq = mu1.pow(2)
        mu2_sq = mu2.pow(2)
        mu1_mu2 = mu1*mu2
    
        sigma1_sq = F.conv2d(img1*img1, window, padding = window_size//2, groups = channel) - mu1_sq
        sigma2_sq = F.conv2d(img2*img2, window, padding = window_size//2, groups = channel) - mu2_sq
        sigma12 = F.conv2d(img1*img2, window, padding = window_size//2, groups = channel) - mu1_mu2
    
        C1 = 0.01**2
        C2 = 0.03**2
    
        ssim_map = ((2*mu1_mu2 + C1)*(2*sigma12 + C2))/((mu1_sq + mu2_sq + C1)*(sigma1_sq + sigma2_sq + C2))
    
        if size_average:
            return ssim_map.mean()
        else:
            return ssim_map.mean(1).mean(1).mean(1)
    
    
    def ssim(img1, img2, window_size = 11, size_average = True):
        (_, channel, _, _) = img1.size()
        window = create_window(window_size, channel)
        
        if img1.is_cuda:
            window = window.cuda(img1.get_device())
        window = window.type_as(img1)
        
        return _ssim(img1, img2, window, window_size, channel, size_average)
    
    • 好吧,這兩個都是借鑒別人的(老懶狗了

4.2.5 構建訓練框架

  • 訓練框架如下所示:
if __name__ == '__main__':
    path = '你的資料集路徑'
    
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    dataset = PreprocessDataset(path,size = 96)
    trainData = DataLoader(dataset,batch_size = 32,num_workers = 4,shuffle = True)

    net = Model(channals = 64,blockNum = 24).to(device)
    print(net)
    criteria = nn.L1Loss()
    optimizer = optim.AdamW(net.parameters(),lr = 1e-4)
    totalStep = len(trainData)

    # 構建可視化結果的保存路徑
    if not os.path.exists('./img'):
        os.mkdir('./img')

    for epoch in range(startEpoch,10000):
        if epoch == 20 or epoch == 40:
            update_lr(optimizer, multiplier = .1)

        totalSSIM = 0.0
        totalPSRN = 0.0
        totalLoss = 0.0
        
        for step,(hr,lr) in enumerate(trainData,1):
            net.train(True)
            hr,lr = hr.to(device),lr.to(device)
            net.zero_grad()
            output = net(lr)
            loss = criteria(output,hr)
            loss.backward()
            optimizer.step()

            totalLoss += loss
            totalSSIM += ssim(output,hr)
            totalPSRN += PSRN(output,hr)
            
            print("[Epoch %d] Step: %d/%d Loss: %.4f|ssim: %.4f|psrn: %.4f" %
                (epoch,step,totalStep,totalLoss/step,totalSSIM/step,totalPSRN/step))

            if step >= 100: #對影像進行可視化
                net.train(False)
                outputs = net(lr)
                outputs = torch.cat([hr,outputs],dim = 0)
                save_image(outputs,'./Img/Result_epoch_%08d.jpg' % epoch,nrow = 8,normalize = True)      
  • 完整版代碼支持重新打開代碼自動恢復到上次訓練的功能,只需要關注筆者即可獲得:傳送門

4.2.6 訓練結果

  • 100次訓練后結果:
    在這里插入圖片描述

  • 10,000次訓練后結果:
    在這里插入圖片描述
    此時SSIM:0.6710PSRN:65.6384

  • 由于COCO資料集中的特征不唯一,因此需要更多的訓練才能夠達到更好的結果,

  • 完整版代碼支持重新打開代碼自動恢復到上次訓練的功能,只需要關注筆者即可獲得:傳送門

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/303135.html

標籤:其他

上一篇:OpenCV實用:C++實作低對比度影像臟污區域檢測

下一篇:C/C++實作matlab的imfill()函式

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more