主頁 >  其他 > 動手學深度學習(三十三)——樣式遷移

動手學深度學習(三十三)——樣式遷移

2021-10-23 09:41:13 其他

文章目錄

    • 一、基于CNN的樣式遷移
      • 1. 直觀理解樣式遷移
      • 2. 基于CNN的樣式遷移方法
    • 二、樣式遷移實作
      • 1. 閱讀內容和樣式影像
      • 2. 預處理和后處理
      • 3. 抽取影像特征
      • 4. 定義損失函式
        • 4.1 內容損失
        • 4.2 樣式損失
        • 4.3 總變差損失
        • 4.4 總損失加權
      • 5. 初始化合成影像
      • 6. 模型訓練
    • 三、總結

一、基于CNN的樣式遷移

1. 直觀理解樣式遷移

??如果你是一位攝影愛好者,你也許接觸過濾鏡,它能改變照片的顏色樣式,從而使風景照更加銳利或者令人像更加美白,但一個濾鏡通常只能改變照片的某個方面,如果要照片達到理想中的樣式,你可能需要嘗試大量不同的組合,這個程序的復雜程度不亞于模型調參,

在本節中,我們將介紹如何使用卷積神經網路,自動將一個影像中的樣式應用在另一影像之上,即樣式遷移(style transfer),這里我們需要兩張輸入影像:一張是內容影像,另一張是樣式影像注意:內容圖和樣式圖都是我們的輸入,和之前的一張輸入影像是明顯不相同的),我們將使用神經網路修改內容影像,使其在樣式上接近樣式影像,

例如,下圖中影像為李沐沐神在西雅圖郊區的雷尼爾山國家公園拍攝的風景照,而樣式影像則是一幅主題為秋天橡樹的油畫,最終輸出的合成影像應用了樣式影像的油畫筆觸讓整體顏色更加鮮艷,同時保留了內容影像中物體主體的形狀,

2. 基于CNN的樣式遷移方法

下面的圖中用簡單的例子闡述了基于卷積神經網路的樣式遷移方法,

  1. 首先,我們初始化合成影像,例如將其初始化為內容影像(初始化成什么都沒關系,可以嘗試不同的初始化),該合成影像是樣式遷移程序中唯一需要更新的變數,即樣式遷移所需迭代的模型引數,
  2. 然后,我們選擇一個預訓練的卷積神經網路來抽取影像的特征,其中的模型引數在訓練中無須更新,這個深度卷積神經網路憑借多個層逐級抽取影像的特征,我們可以選擇其中某些層的輸出作為內容特征或樣式特征,(越是接近底層,抽取的特征越是全域化)

以下圖為例,這里選取的預訓練的神經網路含有3個卷積層,其中第二層輸出內容特征,第一層和第三層輸出樣式特征,

接下來,我們通過正向傳播(實線箭頭方向)計算樣式遷移的損失函式,并通過反向傳播(虛線箭頭方向)迭代模型引數,即不斷更新合成影像,

樣式遷移常用的損失函式由3部分組成:

  • (i) 內容損失使合成影像與內容影像在內容特征上接近;
  • (ii) 樣式損失使合成影像與樣式影像在樣式特征上接近;
  • (iii) 總變差損失則有助于減少合成影像中的噪點,
    最后,當模型訓練結束時,我們輸出樣式遷移的模型引數,即得到最終的合成影像,

在下面,我們將通過代碼來進一步了解樣式遷移的技術細節,

二、樣式遷移實作

1. 閱讀內容和樣式影像

首先,我們讀取內容和樣式影像,
從列印出的影像坐標軸可以看出,它們的尺寸并不一樣,

%matplotlib inline 
import torch 
import torchvision 
from torch import nn 
from d2l import torch as d2l 
import os 
import matplotlib.pyplot as plt

d2l.set_figsize()
content_img = d2l.Image.open('./course_file/pytorch/img/rainier.jpg')
d2l.plt.imshow(content_img)
style_img = d2l.Image.open('./course_file/pytorch/img/autumn-oak.jpg')
d2l.plt.imshow(style_img);

2. 預處理和后處理

"""
下面,定義影像的預處理函式和后處理函式,
預處理函式`preprocess`對輸入影像在RGB三個通道分別做標準化,并將結果變換成卷積神經網路接受的輸入格式,
后處理函式`postprocess`則將輸出影像中的像素值還原回標準化之前的值,
由于影像列印函式要求每個像素的浮點數值在0到1之間,我們對小于0和大于1的值分別取0和1,
"""
rgb_mean = torch.tensor([0.485, 0.456, 0.406])
rgb_std = torch.tensor([0.229, 0.224, 0.225])

def preprocess(img, image_shape):
    """圖片變為tensor"""
    transforms = torchvision.transforms.Compose([
        torchvision.transforms.Resize(image_shape),
        torchvision.transforms.ToTensor(),
        torchvision.transforms.Normalize(mean=rgb_mean, std=rgb_std)])
    return transforms(img).unsqueeze(0)

def postprocess(img):
    """tensor變為圖片"""
    img = img[0].to(rgb_std.device)
    img = torch.clamp(img.permute(1, 2, 0) * rgb_std + rgb_mean, 0, 1)
    return torchvision.transforms.ToPILImage()(img.permute(2, 0, 1))

3. 抽取影像特征

# 我們使用基于ImageNet資料集預訓練的VGG-19模型來抽取影像特征,
pretrained_net = torchvision.models.vgg19(pretrained=True)
pretrained_net
VGG(
  (features): Sequential(
    (0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (1): ReLU(inplace=True)
    (2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (3): ReLU(inplace=True)
    (4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    (5): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (6): ReLU(inplace=True)
    (7): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (8): ReLU(inplace=True)
    (9): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    (10): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (11): ReLU(inplace=True)
    (12): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (13): ReLU(inplace=True)
    (14): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (15): ReLU(inplace=True)
    (16): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (17): ReLU(inplace=True)
    (18): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    (19): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (20): ReLU(inplace=True)
    (21): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (22): ReLU(inplace=True)
    (23): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (24): ReLU(inplace=True)
    (25): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (26): ReLU(inplace=True)
    (27): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    (28): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (29): ReLU(inplace=True)
    (30): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (31): ReLU(inplace=True)
    (32): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (33): ReLU(inplace=True)
    (34): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (35): ReLU(inplace=True)
    (36): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  )
  (avgpool): AdaptiveAvgPool2d(output_size=(7, 7))
  (classifier): Sequential(
    (0): Linear(in_features=25088, out_features=4096, bias=True)
    (1): ReLU(inplace=True)
    (2): Dropout(p=0.5, inplace=False)
    (3): Linear(in_features=4096, out_features=4096, bias=True)
    (4): ReLU(inplace=True)
    (5): Dropout(p=0.5, inplace=False)
    (6): Linear(in_features=4096, out_features=1000, bias=True)
  )
)

為了抽取影像的內容特征和樣式特征,我們可以選擇VGG網路中某些層的輸出,
一般來說:

  • 越靠近輸入層,越容易抽取影像的細節資訊;
  • 反之,則越容易抽取影像的全域資訊,

??為了避免合成影像過多保留內容影像的細節,我們選擇VGG較靠近輸出的層,即內容層,來輸出影像的內容特征,我們還從VGG中選擇不同層的輸出來匹配區域和全域的樣式,這些圖層也稱為樣式層,正如vgg網路中所介紹的,VGG網路使用了5個卷積塊,實驗中,我們選擇第四卷積塊的最后一個卷積層作為內容層,選擇每個卷積塊的第一個卷積層作為樣式層,這些層的索引可以通過打pretrained_net實體獲取,

style_layers, content_layers = [0, 5, 10, 19, 28], [25] # 越小越靠近輸入(區域樣式),越大越靠近輸出(全域樣式)

??使用VGG層抽取特征時,我們只需要用到從輸入層到最靠近輸出層的內容層或樣式層之間的所有層,下面構建一個新的網路net,它只保留需要用到的VGG的所有層,

# 丟棄最大層之后的層
net = nn.Sequential(*[
    pretrained_net.features[i]
    for i in range(max(content_layers + style_layers) + 1)])

??給定輸入X,如果我們簡單地呼叫前向計算net(X),只能獲得最后一層的輸出,由于我們還需要中間層的輸出,因此這里我們逐層計算,并保留內容層和樣式層的輸出,

def extract_features(X, content_layers, style_layers):
    """輸入X,獲取內容層和樣式層的輸出"""
    contents = []
    styles = []
    for i in range(len(net)):
        X = net[i](X)
        if i in style_layers:
            styles.append(X)
        if i in content_layers:
            contents.append(X)
    return contents, styles

# 因為訓練的時候無需改變預訓練的VGG的引數,所以我們可以在訓練開始之前抽取內容特征和樣式特征
# 由于合成影像是樣式遷移時所需要迭代的模型引數,我們只能在訓練程序中呼叫extract_features函式來抽取合成影像的內容特征和樣式特征
def get_contents(image_shape, device):
    """對內容影像抽取內容特征"""
    content_X = preprocess(content_img, image_shape).to(device)
    contents_Y, _ = extract_features(content_X, content_layers, style_layers)
    return content_X, contents_Y

def get_styles(image_shape, device):
    """對樣式影像抽取樣式特征"""
    style_X = preprocess(style_img, image_shape).to(device)
    _, styles_Y = extract_features(style_X, content_layers, style_layers)
    return style_X, styles_Y

4. 定義損失函式

下面我們來描述樣式遷移的損失函式,它由內容損失、樣式損失和總變差損失3部分組成,

4.1 內容損失

??與線性回歸中的損失函式類似,內容損失通過平方誤差函式衡量合成影像與內容影像在內容特征上的差異,平方誤差函式的兩個輸入均為extract_features函式計算所得到的內容層的輸出,

def content_loss(Y_hat, Y):
    """合成影像與內容影像在內容特征上的差異"""
    # 我們從動態計算梯度的樹中分離目標:
    # 這是一個規定的值,而不是一個變數,
    return torch.square(Y_hat - Y.detach()).mean()

4.2 樣式損失

??對于樣式,我們將其看作是像素點在每個通道統計分布,例如要匹配兩張圖片的顏色,我們的一個做法就是匹配這兩張圖片在RGB三個通道上的直方圖,

??樣式損失與內容損失類似,也通過平方誤差函式衡量合成影像與樣式影像在樣式上的差異,為了表達樣式層輸出的樣式,我們先通過extract_features函式計算樣式層的輸出,假設該輸出的樣本數為1,通道數為 c c c,高和寬分別為 h h h w w w,我們可以將此輸出轉換為矩陣 X \mathbf{X} X,其有 c c c行和 h w hw hw列,這個矩陣可以被看作是由 c c c個長度為 h w hw hw的向量 x 1 , … , x c \mathbf{x}_1, \ldots, \mathbf{x}_c x1?,,xc?組合而成的,其中向量 x i \mathbf{x}_i xi?代表了通道 i i i 上的樣式特征,

??在這些向量的格拉姆矩陣 X X ? ∈ R c × c \mathbf{X}\mathbf{X}^\top \in \mathbb{R}^{c \times c} XX?Rc×c 中, i i i j j j 列的元素 x i j x_{ij} xij? 即向量 x i \mathbf{x}_i xi? x j \mathbf{x}_j xj? 的內積,它表達了通道 i i i 和通道 j j j 上樣式特征的相關性,我們用這樣的格拉姆矩陣來表達樣式層輸出的樣式,需要注意的是,當 h w hw hw的值較大時,格拉姆矩陣中的元素容易出現較大的值,此外,格拉姆矩陣的高和寬皆為通道數 c c c,為了讓樣式損失不受這些值的大小影響,下面定義的gram函式將格拉姆矩陣除以了矩陣中元素的個數,即 c h w chw chw

def gram(X):
    num_channels, n = X.shape[1], X.numel() // X.shape[1] # channel為通道數,n為高寬乘積
    X = X.reshape((num_channels, n))
    return torch.matmul(X, X.T) / (num_channels * n)

??自然地,樣式損失的平方誤差函式的兩個格拉姆矩陣輸入分別基于合成影像與樣式影像的樣式層輸出,這里假設基于樣式影像的格拉姆矩陣gram_Y已經預先計算好了,

def style_loss(Y_hat, gram_Y):
    return torch.square(gram(Y_hat) - gram_Y.detach()).mean()

4.3 總變差損失

??有時候,我們學到的合成影像里面有大量高頻噪點,即有特別亮或者特別暗的顆粒像素,一種常見的降噪方法是總變差降噪:假設 x i , j x_{i, j} xi,j? 表示坐標 ( i , j ) (i, j) (i,j) 處的像素值,降低總變差損失

∑ i , j ∣ x i , j ? x i + 1 , j ∣ + ∣ x i , j ? x i , j + 1 ∣ \sum_{i, j} \left|x_{i, j} - x_{i+1, j}\right| + \left|x_{i, j} - x_{i, j+1}\right| i,j?xi,j??xi+1,j?+xi,j??xi,j+1?

能夠盡可能使鄰近的像素值相似,

def tv_loss(Y_hat):
    """TV降噪,使得鄰近像素值類似"""
    return 0.5 * (torch.abs(Y_hat[:, :, 1:, :] - Y_hat[:, :, :-1, :]).mean() +
                  torch.abs(Y_hat[:, :, :, 1:] - Y_hat[:, :, :, :-1]).mean())

4.4 總損失加權

風格轉移的損失函式是內容損失、風格損失和總變化損失的加權和
通過調節這些權值超引數,我們可以權衡合成影像在保留內容、遷移樣式以及降噪三方面的相對重要性,

content_weight, style_weight, tv_weight = 1, 1e3, 10

def compute_loss(X, contents_Y_hat, styles_Y_hat, contents_Y, styles_Y_gram):
    # 分別計算內容損失、樣式損失和總變差損失
    contents_l = [
        content_loss(Y_hat, Y) * content_weight
        for Y_hat, Y in zip(contents_Y_hat, contents_Y)]
    styles_l = [
        style_loss(Y_hat, Y) * style_weight
        for Y_hat, Y in zip(styles_Y_hat, styles_Y_gram)]
    tv_l = tv_loss(X) * tv_weight
    # 對所有損失求和
    l = sum(10 * styles_l + contents_l + [tv_l])
    return contents_l, styles_l, tv_l, l

5. 初始化合成影像

??在樣式遷移中,合成的影像是訓練期間唯一需要更新的變數,因此,我們可以定義一個簡單的模型SynthesizedImage,并將合成的影像視為模型引數,模型的前向計算只需回傳模型引數即可,

class SynthesizedImage(nn.Module):
    def __init__(self, img_shape, **kwargs):
        super(SynthesizedImage, self).__init__(**kwargs)
        self.weight = nn.Parameter(torch.rand(*img_shape))

    def forward(self):
        return self.weight
def get_inits(X, device, lr, styles_Y):
    """
    該函式創建了合成影像的模型實體,并將其初始化為影像 `X` ,
    樣式影像在各個樣式層的格拉姆矩陣 `styles_Y_gram` 將在訓練前預先計算好,
    """
    gen_img = SynthesizedImage(X.shape).to(device)
    gen_img.weight.data.copy_(X.data)
    trainer = torch.optim.Adam(gen_img.parameters(), lr=lr)
    styles_Y_gram = [gram(Y) for Y in styles_Y]
    return gen_img(), styles_Y_gram, trainer

6. 模型訓練

??在訓練模型進行樣式遷移時,我們不斷抽取合成影像的內容特征和樣式特征,然后計算損失函式,下面定義了訓練回圈,訓練程序與傳統的神經網路訓練不同在于

  1. 損失函式更加復雜
  2. 我們只對輸入進行更新(意味著需要對輸入X預先分配梯度)
  3. 我們可能會替換匹配內容和樣式的層,調整他們之間的權重,以得到不同風格的輸出,
  4. 仍然使用簡單的隨機梯度下降,但是每隔n次迭代減小一次學習率
def train(X, contents_Y, styles_Y, device, lr, num_epochs, lr_decay_epoch):
    X, styles_Y_gram, trainer = get_inits(X, device, lr, styles_Y)
    scheduler = torch.optim.lr_scheduler.StepLR(trainer, lr_decay_epoch, 0.8) # 依次降低學習率
    animator = d2l.Animator(xlabel='epoch', ylabel='loss',
                            xlim=[10, num_epochs],
                            legend=['content', 'style',
                                    'TV'], ncols=2, figsize=(7, 2.5))
    for epoch in range(num_epochs):
        trainer.zero_grad()
        contents_Y_hat, styles_Y_hat = extract_features(
            X, content_layers, style_layers)
        contents_l, styles_l, tv_l, l = compute_loss(X, contents_Y_hat,
                                                     styles_Y_hat, contents_Y,
                                                     styles_Y_gram)
        l.backward()
        trainer.step()
        scheduler.step()
        if (epoch + 1) % 10 == 0:
            animator.axes[1].imshow(postprocess(X))
            animator.add(
                epoch + 1,
                [float(sum(contents_l)),
                 float(sum(styles_l)),
                 float(tv_l)])
    return X
# 現在我們[**訓練模型**]:首先將內容影像和樣式影像的高和寬分別調整為300和450像素,用內容影像來初始化合成影像,
device, image_shape = d2l.try_gpu(), (300, 450)
net = net.to(device)
content_X, contents_Y = get_contents(image_shape, device)
_, styles_Y = get_styles(image_shape, device)
output = train(content_X, contents_Y, styles_Y, device, 0.1, 500, 200)
plt.imshow(postprocess(output))
plt.savefig("test.png")

三、總結

  1. 樣式遷移的損失包含三個部分
    • 內容損失:使得合成影像與內容影像在內容特征上接近
    • 樣式損失:使得合成影像與樣式影像在樣式特征上接近
    • 總變差損失:減少合成影像中的噪聲點
  2. 可以通過預訓練模型的卷積神經網路抽取影像的特征,并通過最小化損失函式來不斷更新合成影像作為模型引數
  3. 使用拉格姆矩陣表達樣式層的樣式

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

標籤:其他

上一篇:OpenCV-Python自適應直方圖均衡類CLAHE及方法詳解

下一篇:Jenkins安裝與持續部署

標籤雲
其他(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