使用Pytorch從零開始構建DCGAN

在本文中,我們將深入研究生成建模的世界,并使用流行的 PyTorch 框架探索 DCGAN(生成對抗網絡 (GAN) 的一種變體)的實現。具體來說,我們將使用 CelebA 數據集(名人面部圖像的集合)來生成逼真的合成面部。在深入了解實現細節之前,我們首先了解 GAN 是什么以及 DCGAN 與它們有何不同,并詳細探討其架構。
在這里插入圖片描述
那么,什么是 GAN?

簡而言之,生成對抗網絡(GAN)是一種令人著迷的機器學習模型,其中兩個玩家(生成器和鑒別器)參與競爭性游戲。生成器的目的是創建真實的合成樣本,例如圖像或文本,而鑒別器的工作是區分真實樣本和假樣本。通過這場貓鼠游戲,GAN 學會生成高度令人信服且真實的輸出,最終突破人工智能在創建新的多樣化數據方面的界限。

在這里插入圖片描述
理解DCGAN:

DCGAN(深度卷積生成對抗網絡)是一種令人興奮的機器學習模型,可以創建極其逼真和詳細的圖像。想象一下,一個系統可以通過分析數千個示例來學習生成全新的圖片,例如面孔或風景。DCGAN 通過巧妙地結合兩個網絡來實現這一目標——一個網絡生成圖像,另一個網絡試圖區分真假圖像。通過競爭過程,DCGAN 成為生成令人信服且難以與真實圖像區分開的圖像的大師,展示了人工智能的巨大創造潛力。

DCGAN的架構:

DCGAN(深度卷積生成對抗網絡)的架構??由兩個基本組件組成:生成器和判別器。

生成器將隨機噪聲作為輸入,并逐漸將其轉換為類似于訓練數據的合成樣本。它通過一系列層來實現這一點,包括轉置卷積、批量歸一化和激活函數。這些層使生成器能夠學習復雜的模式和結構,從而生成捕獲真實數據的復雜細節的高維樣本。

另一方面,鑒別器充當二元分類器,區分真實樣本和生成樣本。它接收輸入樣本并將其傳遞給卷積層、批量歸一化和激活函數。鑒別器的作用是評估樣本的真實性并向生成器提供反饋。通過對抗性訓練過程,生成器和鑒別器不斷競爭并提高性能,最終生成越來越真實的樣本。

讓我們開始實現我們的第一個 DCGAN:

假設您的環境中安裝了 PyTorch 和 CUDA,我們首先導入必要的庫。

import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
from tqdm import tqdm
import torchvision.datasets as datasets
from torchvision.datasets import ImageFolder
from torchvision.utils import make_grid
import torchvision.utils as vutils
import torchvision.transforms as transforms
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt
from torch.utils.data import Subset
import numpy as np

導入這些庫后,您就可以使用 CelebA 數據集在 PyTorch 中繼續實施 DCGAN。

為了設置訓練 DCGAN 模型所需的配置,我們可以定義設備、學習率、批量大小、圖像大小、輸入圖像中的通道數、潛在空間維度、歷元數以及特征數判別器和生成器。以下是配置:

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
LEARNING_RATE = 2e-4  # could also use two lrs, one for gen and one for disc
BATCH_SIZE = 128
IMAGE_SIZE = 64
CHANNELS_IMG = 3
Z_DIM = 100
NUM_EPOCHS = 5
FEATURES_DISC = 64
FEATURES_GEN = 64

“device”變量確保代碼在可用的 GPU 上運行,否則返回到 CPU。“LEARNING_RATE”決定了模型在優化過程中學習的速率。“BATCH_SIZE”表示每次迭代中處理的樣本數量。“IMAGE_SIZE”表示輸入圖像的所需尺寸。“CHANNELS_IMG”指定輸入圖像中顏色通道的數量(例如,RGB 為 3)。“Z_DIM”表示潛在空間的維度,它是生成器的輸入。“NUM_EPOCHS”決定了訓練期間遍歷整個數據集的次數。“FEATURES_DISC”和“FEATURES_GEN”分別表示鑒別器和生成器網絡中的特征數量。

這些配置對于訓練 DCGAN 模型至關重要,可以根據具體要求和可用資源進行調整。

要加載 CelebA 數據集并準備進行訓練,我們可以定義數據轉換、創建數據集對象并設置數據加載器:

transform = transforms.Compose([transforms.Resize((IMAGE_SIZE, IMAGE_SIZE)),transforms.ToTensor(),transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])dataset = datasets.ImageFolder('<path_to_celeba_dataset_in_your_directoty>', transform=transform)
dataloader = DataLoader(dataset=dataset, batch_size=BATCH_SIZE, shuffle=True)

要可視化 CelebA 數據集中的一批訓練圖像:

real_batch = next(iter(dataloader))
plt.figure(figsize=(7,7))
plt.axis("off")
plt.title("Training Images")
plt.imshow(np.transpose(vutils.make_grid(real_batch[0].to(device)[:49], padding=2, normalize=True).cpu(),(1,2,0)))

在這里插入圖片描述
創建生成器網絡:
在這里插入圖片描述
在 DCGAN 架構中,噪聲數據最初表示為形狀為 100x1x1 的張量,經過一系列轉置卷積運算,將其轉換為大小為 3x64x64 的輸出圖像。

以下是重塑過程的逐步分解:

  1. 輸入噪聲:100x1x1
  2. 第一個轉置卷積層:
    — 輸出大小:1024x4x4
    — 內核大小:4x4,步長:1,填充:0
  3. 第二個轉置卷積層:
    — 輸出大小:512x8x8
    — 內核大小:4x4,步長:2,填充:1
  4. 第三轉置卷積層:
    — 輸出大小:256x16x16
    — 內核大小:4x4,步長:2,填充:1 5.
  5. 第四轉置卷積層:
    — 輸出大小:128x32x32
    — 內核大小:4x4,步長:2,填充:1
  6. 最終轉置卷積層:
    — 輸出大小:3x64x64
    — 內核大小:4x4,步幅:2,填充:1

通過將噪聲數據傳遞到這些轉置卷積層,生成器逐漸將低維噪聲放大為與所需大小 3x64x64 匹配的高維圖像。重塑過程涉及增加空間維度,同時減少通道數量,從而產生具有代表 RGB 顏色通道的三個通道和 64x64 像素尺寸的最終輸出圖像。

class Generator(nn.Module):def __init__(self, z_dim, channels_img, features_g):super(Generator, self).__init__()self.net = nn.Sequential(self._block(z_dim, features_g * 16, 4, 1, 0),self._block(features_g * 16, features_g * 8, 4, 2, 1),self._block(features_g * 8, features_g * 4, 4, 2, 1),self._block(features_g * 4, features_g * 2, 4, 2, 1),nn.ConvTranspose2d(features_g * 2, channels_img, kernel_size=4, stride=2, padding=1),nn.Tanh())def _block(self, in_channels, out_channels, kernel_size, stride, padding):return nn.Sequential(nn.ConvTranspose2d(in_channels,out_channels,kernel_size,stride,padding,bias=False),nn.BatchNorm2d(out_channels),nn.ReLU())def forward(self, x):return self.net(x)

Generator 類代表 DCGAN 架構中的生成器網絡。它將潛在空間的維度 (z_dim)、輸出圖像中的通道數 (channels_img) 和特征數 (features_g) 作為輸入。生成器被定義為順序模塊。

該_block方法在生成器中定義了一個塊,其中包含轉置卷積層、批量歸一化和 ReLU 激活函數。該塊重復多次,逐漸增加輸出圖像的空間維度。

在該forward方法中,輸入噪聲 (x) 通過生成器的連續層,從而生成生成的圖像。

生成器的架構旨在將低維潛在空間轉換為高維圖像,并逐漸將其放大到所需的輸出大小。然后輸出圖像通過雙曲正切激活函數 ( nn.Tanh()) 以確保其像素值在 [-1, 1] 范圍內。

通過以這種方式定義生成器,當提供隨機噪聲作為輸入時,它學會生成類似于訓練數據的合成圖像。

創建鑒別器網絡:
在這里插入圖片描述
在 DCGAN 架構中,判別器采用大小為 3x64x64 的輸入圖像,并通過一系列卷積層對其進行處理,從而產生 1x1x1 的輸出。以下是重塑過程的逐步分解:

  1. 輸入圖像:3x64x64
  2. 第一個卷積層:
    — 輸出大小:64x32x32
    — 內核大小:4x4,步長:2,填充:1
  3. 第二個卷積層:
    — 輸出大小:128x16x16
    — 內核大小:4x4,步長:2 ,填充:1
  4. 第三個卷積層:
    — 輸出大小:256x8x8
    — 內核大小:4x4,步長:2,填充:1 5.
  5. 第四個卷積層:
    — 輸出大小:512x4x4
    — 內核大小:4x4,步長:2,填充:1
  6. 最終卷積層:
    — 輸出大小:1x1x1
    — 內核大小:4x4,步長:2,填充:0

通過將輸入圖像傳遞給這些卷積層,鑒別器逐漸減小空間維度,同時增加通道數量。這種轉換允許鑒別器評估圖像并對其真實性做出決定。1x1x1 的輸出大小表示單個值,該值表示輸入圖像為真或假的概率。

class Discriminator(nn.Module):def __init__(self, channels_img, features_d):super(Discriminator, self).__init__()self.disc = nn.Sequential(nn.Conv2d(channels_img, features_d, kernel_size=4, stride=2, padding=1),nn.LeakyReLU(0.2),self._block(features_d, features_d * 2, 4, 2, 1),self._block(features_d * 2, features_d * 4, 4, 2, 1),self._block(features_d * 4, features_d * 8, 4, 2, 1),nn.Conv2d(features_d * 8, 1, kernel_size=4, stride=2, padding=0),nn.Sigmoid())def _block(self, in_channels, out_channels, kernel_size, stride, padding):return nn.Sequential(nn.Conv2d(in_channels,out_channels,kernel_size,stride,padding,bias=False),nn.BatchNorm2d(out_channels),nn.LeakyReLU(0.2))def forward(self, x):return self.disc(x)

Discriminator 類代表 DCGAN 架構中的鑒別器網絡。它將輸入圖像中的通道數 (channels_img) 和特征數 (features_d) 作為輸入。鑒別器被定義為一個順序模塊。

該_block方法在判別器內定義了一個塊,由卷積層、批量歸一化和 LeakyReLU 激活組成。該塊重復多次,逐漸增加特征數量并減少輸入圖像的空間維度。

在該forward方法中,輸入圖像 (x) 通過鑒別器的連續層,由于最后的 sigmoid 激活,輸出表示輸入為真 (1) 或假 (0) 的概率。

鑒別器的架構使其能夠區分真假圖像,使其成為 DCGAN 對抗訓練過程的重要組成部分。

創建一個函數來初始化權重:

def initialize_weights(model):classname = model.__class__.__name__if classname.find('Conv') != -1:nn.init.normal_(model.weight.data, 0.0, 0.02)elif classname.find('BatchNorm') != -1:nn.init.normal_(model.weight.data, 1.0, 0.02)nn.init.constant_(model.bias.data, 0)

在此函數中,我們接收 amodel作為輸入,它可以引用生成器或鑒別器網絡。我們迭代模型的各層并根據層類型初始化權重。這些權重是由 DCGAN 論文建議的。

對于卷積層 ( Conv),我們使用nn.init.normal_平均值 0 和標準差 0.02 來初始化權重。

對于批量歸一化層 ( BatchNorm),我們使用 來初始化權重,平均值為 1,標準差為 0.02 nn.init.normal_,并使用 來將偏差設置為 0 nn.init.constant_。

通過調用此函數并將生成器和鑒別器網絡作為參數傳遞,您可以確保網絡的權重得到適當初始化以訓練 DCGAN 模型。

gen = Generator(Z_DIM, CHANNELS_IMG, FEATURES_GEN).to(device)
disc = Discriminator(CHANNELS_IMG, FEATURES_DISC).to(device)initialize_weights(gen)
initialize_weights(disc)

gen現在,我們通過傳遞潛在空間的維度 ( Z_DIM)、輸出圖像中的通道數 ( CHANNELS_IMG) 以及生成器中的特征數量 ( FEATURES_GEN)來創建生成器網絡 ( ) 的實例。disc類似地,我們通過指定輸入通道的數量 ( CHANNELS_IMG) 和鑒別器中的特征數量 ( )創建鑒別器網絡 ( ) 的實例FEATURES_DISC。

創建網絡實例后,我們調用initialize_weights生成器和鑒別器網絡上的函數,根據 DCGAN 論文中建議的權重初始化技術來初始化它們的權重。

通過執行此代碼,您將準備好生成器和鑒別器網絡,并正確初始化它們的權重,用于訓練 DCGAN 模型。

opt_gen = optim.Adam(gen.parameters(), lr=LEARNING_RATE, betas=(0.5, 0.999))
opt_disc = optim.Adam(disc.parameters(), lr=LEARNING_RATE, betas=(0.5, 0.999))
criterion = nn.BCELoss()fixed_noise = torch.randn(32, Z_DIM, 1, 1).to(device)

我們為生成器和鑒別器網絡定義了優化器。我們使用模塊中的 Adam 優化器torch.optim。生成器優化器 ( opt_gen) 使用生成器參數、學習率LEARNING_RATE以及 Adam 優化器的 beta 參數(0.5 和 0.999)進行初始化。

類似地,判別器優化器 ( opt_disc) 使用判別器的參數、相同的學習率和 beta 參數進行初始化。

接下來,我們定義對抗訓練過程的損失標準。在這里,我們使用二元交叉熵損失 (Binary Cross Entropy Loss nn.BCELoss()),它在 GAN 中常用來將判別器的預測與真實標簽進行比較。

最后,我們創建一個固定噪聲張量 ( fixed_noise),用于在訓練過程中生成樣本圖像。該torch.randn函數根據正態分布生成隨機數。

通過設置優化器、損失準則和固定噪聲張量,您就可以開始訓練 DCGAN 模型了。

def show_tensor_images(image_tensor, num_images=32, size=(1, 64, 64)):image_tensor = (image_tensor + 1) / 2image_unflat = image_tensor.detach().cpu()image_grid = make_grid(image_unflat[:num_images], nrow=4)plt.imshow(image_grid.permute(1, 2, 0).squeeze())plt.show()

“show_tensor_images”函數是一個實用函數,它獲取圖像張量,對它們進行標準化,創建圖像網格,并使用 matplotlib 顯示它們,以便在訓練過程中輕松可視化。

訓練模型:

gen.train()
disc.train()for epoch in range(NUM_EPOCHS):for batch_idx, (real, _ ) in enumerate(dataloader):real = real.to(device)### create noise tensornoise = torch.randn((BATCH_SIZE, Z_DIM, 1, 1)).to(device)fake = gen(noise)### Train Discriminator: max log(D(x)) + log(1 - D(G(z)))disc_real = disc(real).reshape(-1)loss_disc_real = criterion(disc_real, torch.ones_like(disc_real))disc_fake = disc(fake.detach()).reshape(-1)loss_disc_fake = criterion(disc_fake, torch.zeros_like(disc_fake))loss_disc = (loss_disc_real + loss_disc_fake) / 2disc.zero_grad()loss_disc.backward()opt_disc.step()### Train Generator: min log(1 - D(G(z))) <-> max log(D(G(z))output = disc(fake).reshape(-1)loss_gen = criterion(output, torch.ones_like(output))gen.zero_grad()loss_gen.backward()opt_gen.step()### Print losses occasionally and fake images occasionallyif batch_idx % 50 == 0:print(f"Epoch [{epoch}/{NUM_EPOCHS}] Batch {batch_idx}/{len(dataloader)} \Loss D: {loss_disc:.4f}, loss G: {loss_gen:.4f}")with torch.no_grad():fake = gen(fixed_noise)img_grid_real = torchvision.utils.make_grid(real[:32], normalize=True)img_grid_fake = torchvision.utils.make_grid(fake[:32], normalize=True)show_tensor_images(img_grid_fake)

我們可以將本次培訓分為四個部分以便更好地理解。

  1. 噪聲生成:隨機噪聲 ( noise) 使用形狀為 的正態分布生成(BATCH_SIZE, Z_DIM, 1, 1)。
  2. 判別器訓練:判別器網絡是通過評估真實圖像 ( ) 并根據判別器與地面真實標簽(全部)的預測real計算損失 ( ) 來訓練的。loss_disc_real假圖像 ( fake) 是通過將噪聲傳遞到生成器網絡來生成的。評估鑒別器對假圖像 ( ) 的預測,并根據與地面真實標簽(全零)相比的預測來計算disc_fake損失 ( ) 。loss_disc_fake平均損失 ( ) 計算為和loss_disc的平均值。判別器參數的梯度設置為零,反向傳播損失,并更新判別器的優化器。loss_disc_realloss_disc_fake
  3. 生成器訓練:生成器網絡是通過fake使用噪聲生成假圖像( )來訓練的。獲得判別器對假圖像 ( ) 的預測,并根據與地面真實標簽(全部)相比的預測來計算output損失 ( )。loss_gen生成器參數的梯度設置為零,反向傳播損失,并更新生成器的優化器。
  4. 進度跟蹤和圖像可視化:每 50 個批次后,打印當前紀元、批次索引、鑒別器損失 ( loss_disc) 和生成器損失 ( )。loss_gen樣本圖像是通過將固定噪聲傳遞到生成器網絡來生成的。真實圖像和生成圖像都被轉換為圖像網格,然后顯示圖像網格以可視化生成器網絡的學習進度。

每個時期生成的假圖像:

Starting of the first epoch:Starting of the first epoch
After first epoch:
在這里插入圖片描述
After second epoch:
在這里插入圖片描述
After third epoch:
在這里插入圖片描述
After fourth epoch:
在這里插入圖片描述
End results ( After 5 epochs):
在這里插入圖片描述

結論: 如果您能夠獲得更好的結果,

  1. 增加模型容量:在生成器和鑒別器網絡中添加更多層或增加濾波器數量,以增強模型學習復雜模式并生成更高質量圖像的能力。
  2. 利用更深的卷積層:實施ResNet 或 DenseNet 等更深層次的架構來捕獲更復雜的特征和紋理,從而提高圖像質量。
  3. 使用更大的數據集:在更大、更多樣化的數據集上訓練 DCGAN 可以幫助模型學習更廣泛的圖像變化,并提高其生成高分辨率圖像的能力。
  4. 調整訓練參數:試驗學習率、批量大小和訓練迭代等超參數,以優化訓練過程并提高模型生成更高分辨率圖像的能力。

博文譯自Manohar Kedamsetti的博客。

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

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

相關文章

網絡安全等級保護收費標準?

不同省份價格會略有不同&#xff0c;二級等保一般不低于5萬元;三級等保不低于9萬元&#xff0c;個別省份也可能7萬也能辦理&#xff0c;根據企業實際情況和省市選定的代理機構確定。 等級保護二級? 第二級等保是指信息系統受到破壞后&#xff0c;會對公民、法人和其他組織的合…

刷到一個很騷氣的 Go 錯誤處理新提案

在比較一段長的時間里&#xff0c;Go 的錯誤處理已經沒有什么特別的進展和新改進了。看著已經到了瓶頸期。 今天在 GitHub 上學習時&#xff0c;看到 Go 社區里有人提了個錯誤處理的優化提案《proposal: Go 2: Error-Handling Paradigm with !err Grammar Sugar》&#xff0c;…

《YOLOv8創新改進》專欄指導書冊 手把手創新教程

&#x1f680;&#x1f680;&#x1f680;YOLOv8改進專欄&#xff1a;http://t.csdnimg.cn/hGhVK 學姐帶你學習YOLOv8&#xff0c;從入門到創新&#xff0c;輕輕松松搞定科研&#xff1b; 本專欄為訂閱者提供答疑服務&#xff0c;每一篇提供源代碼和詳細的每一個步驟改進地方。…

Navicat 技術指引 | 適用于 GaussDB 的模型功能

Navicat Premium&#xff08;16.2.8 Windows版或以上&#xff09; 已支持對 GaussDB 主備版的管理和開發功能。它不僅具備輕松、便捷的可視化數據查看和編輯功能&#xff0c;還提供強大的高階功能&#xff08;如模型、結構同步、協同合作、數據遷移等&#xff09;&#xff0c;這…

工業交換機具備哪些功能?

在工業網絡中&#xff0c;工業交換機起著至關重要的作用&#xff0c;具備多樣功能和廣泛的應用。 1、工業交換機的作用是實現不同網絡設備之間的互聯。它能夠連接各種不同類型的設備&#xff0c;如計算機、服務器、傳感器和監控設備&#xff0c;實現設備間的相互通信和數據傳輸…

應用高斯高通濾波器提取圖像輪廓

任務要求&#xff1a; 圖為HALCON中的例圖“tooth_rim”&#xff0c;請用高斯高通濾波器提取圖像的輪廓。 任務分析&#xff1a; 圖像的邊緣對應頻譜的高頻部分&#xff0c;可以通過構造一個高頻濾波器&#xff0c;過濾掉圖像的低頻部分&#xff0c;從而得到圖像的邊緣。HALC…

蘋果怎么關閉懸浮球?讓我來解答您的疑惑!

懸浮球是蘋果設備上的一種可進行自定義的快捷操作功能&#xff0c;它可以位于手機屏幕的任意位置&#xff0c;以浮動的方式顯示。然而&#xff0c;有時候懸浮球對某些朋友來說可能會變得多余&#xff0c;那么蘋果怎么關閉懸浮球呢&#xff1f;接下來&#xff0c;小編將為大家揭…

docker compose搭建滲透測試vulstudy靶場示例

前言 滲透測試&#xff08;Penetration test&#xff09;即網絡安全工程師/安全測試工程師/滲透測試工程師通過模擬黑客&#xff0c;在合法授權范圍內&#xff0c;通過信息搜集、漏洞挖掘、權限提升等行為&#xff0c;對目標對象進行安全測試&#xff08;或攻擊&#xff09;&am…

【快應用】小程序轉快應用中如何獲取用戶已授權的權限

【關鍵詞】 權限、SystemInfo、setting 【問題背景】 小程序轉快應用&#xff0c;用戶在使用快應用的過程中如果產生了一些授權行為&#xff0c;開發者是否有辦法去收集到用戶已經授權過的權限呢&#xff0c;從而進行更好管理呢&#xff1f; 【解決方案】 小程序轉快應用中是…

詳解——菱形繼承及菱形虛擬繼承

目錄 一&#xff0c;菱形繼承 1.1單繼承 1.2多繼承 1.3菱形繼承 1.4菱形繼承的問題 1.5虛擬繼承解決數據冗余和二義性的原理 二.繼承的總結和反思 一&#xff0c;菱形繼承 C三大特性——繼承-CSDN博客 1.1單繼承 單繼承&#xff1a;一個子類只有一個直接父類時稱這個繼…

javaScript解決手機瀏覽器下載為圖片之后,圖片漆黑無法保存的問題

pc端能正常下載圖片并查看 手機移動端下載的圖片全是黑色的并且無法保存&#xff0c;這個問題可能與移動瀏覽器的安全策略有關 解決辦法&#xff1a;使用Blob對象和createObjectURL方法來創建一個臨時URL&#xff0c;然后將其賦給鏈接的href屬性下載&#xff1a; // 轉blob函…

anaconda安裝配置

創建分區 conda create -n cpu 安裝Cpu版本 https://pytorch.org/ conda install pytorch torchvision torchaudio cpuonly -c pytorch 激活環境 conda activate cpu 驗證 退出當前分區 conda deactivate 安裝GPU版本 創建分區conda create -n gpu 激活環境 conda…

Java面向對象(高級)-- final關鍵字的使用

文章目錄 一、 final的意義二、 final的使用&#xff08;1&#xff09; final修飾類&#xff08;2&#xff09; final修飾方法&#xff08;3&#xff09; final修飾變量1. 修飾成員變量1.1 舉例11.2 舉例2 2. 修飾局部變量2.1 舉例12.2 舉例2 &#xff08;4&#xff09;final搭…

java協程操作mysql數據庫

我的項目&#xff1a; nanshaws/nettyWeb: 復習一下netty&#xff0c;并打算做一個web項目出來 (github.com) 最近在項目中分別添加了虛擬線程操作mysql數據庫&#xff0c;和用協程操作mysql數據庫 同理先跟我這個博客操作一下前面的&#xff1a;就單純代碼的時候進行修改&a…

TikTok與精神健康:社交媒體在壓力時代的作用

在當今數字化和社交化的時代&#xff0c;社交媒體已成為人們生活中不可或缺的一部分。其中&#xff0c;TikTok作為一款備受歡迎的短視頻應用&#xff0c;不僅改變了人們的娛樂方式&#xff0c;也對精神健康產生了深遠的影響。 本文將深入探討TikTok在壓力時代對精神健康的作用…

2023年中國油田工程建設市場規模現狀及行業競爭分析[圖]

油田工程建設是在確定油氣田有開發生產的價值的基礎上&#xff0c;進行系統的工程建設&#xff0c;油田工程建設包括井場建設、管道施工、土石方工程、道路建設及綠化等服務。 油田工程建設主要內容 資料來源&#xff1a;共研產業咨詢&#xff08;共研網&#xff09; 油田服務…

oapi-codegen 安裝和使用

背景描述 oapi-codegen 是代碼自動生成工具&#xff0c;其大致邏輯是&#xff1a;&#xff08;1&#xff09;編寫遵循 openAPI 規范的 yaml 格式 api 接口文檔&#xff1b;&#xff08;2&#xff09;使用 oapi-codegen 使用 yaml 文件生成 gin 框架的 server 端代碼。 除此以…

編輯 | 古代漢語知識

文章目錄 文字通假字古今字異體字&#xff08;了解&#xff09; 詞匯古漢語中的單音詞與雙音詞&#xff08;掌握&#xff09;詞的本義與引申義的特點和主要差異&#xff08;掌握&#xff09;詞的古義與今義的特點和主要差異&#xff08;掌握&#xff09;與現代漢語用法相同與現…

反向傳播BP算法

神經網絡的反向傳播 反向傳播機制與代碼微分引擎與代碼原理闡述 如需轉載&#xff0c;請注明出處&#xff01; 如有幫助點贊收藏關注&#xff01; 反向傳播機制與代碼 這里主要介紹反向傳播是如何運作的&#xff0c;代碼中會加注釋&#xff0c;便于大家理解。 在訓練神經網絡時…

抖音商城小程序源碼系統 附帶完整的搭建教程

大家好啊&#xff0c;今天小編來給大家分享一款抖音商城小程序源碼系統。這可是當下最熱門的的項目之一。。抖音作為國內最大的短視頻平臺之一&#xff0c;擁有龐大的用戶群體和豐富的社交功能。為了滿足用戶在抖音上購物和交易的需求&#xff0c;抖音商城小程序應運而生。 以…