從認識AI開始-----生成對抗網絡(GAN):通過博弈機制,引導生成

前言

生成對抗網絡(GAN)是lan J. Goodfellow團隊在2014年提出的生成架構, 該架構自誕生起,就產生了很多的話題,更是被稱為生成對抗網絡是“新世紀以來機器學習領域內最有趣的想法”。如今,基于生成對抗網絡思想的架構在圖像處理、生成方面的能力越來越強大,已經成為視覺領域中不可忽視的存在,可以這樣說,GAN的誕生,讓這個世界的物理表象變得具有欺騙性了


一、GAN的原理

最初GAN的目標就是用來生成圖像,首先GAN的目標就是利用生成器 G 根據真實數據生成的假數據,并希望生成的假數據能夠以假亂真,從而騙過判別器 D;同時,又希望判別器 D 能夠區分真假數據。如下所示:

整個網絡由生成器 G 和判別器 D 構成,隨機初始化噪聲數據,然后輸入生成器生成假數據,判別器判斷生成的數據和真實數據哪個才是真的。生成器沒有標簽,是無監督網絡,判別器是監督網絡,標簽是“真或假”(0/1)。原始論文規定判別器輸出當前數據為真的概率(標簽為1的概率),當概率大于0.5,判別器認為樣本是真實數據,小于0.5,判別器認為樣本是由生成器生成的假數據。

其核心思想就是:

  • 通過兩個神經網絡(生成器 G 與判別器 D)之間的對抗博弈,讓生成器學會產生以假亂真的數據

二、GAN的損失函數

其實GAN的整過訓練過程就是一個零和博弈。在訓練過程中,生成器和判別器的目標是相互競爭的:生成器的任務是盡可能生成以假亂真的數據,讓判別器判斷不出來,其目的就是讓判別器的準確性降低;箱單,判別器的目的是盡量判斷出真偽,讓自己判斷的準確性越來越高。

當生成器生成的數據越來越真時,判別器為保證自己的準確性,就會朝著判斷能力強的方向迭代。當判斷器判斷能力越來越強大時,生成器為了保證自己生成的真實性,就會朝著生成能力強的方向迭代。在整個的關系中,判別器的準確性由論文中定義的交叉熵 V 來衡量,判別器和生成器共同影響著 V

1. 交叉熵 V

在生成器和判別器的特殊關系中,GAN的目標損失 V?為:

\min\limits_{G}\max\limits_{D}V(D,G)=\mathbb{E}_{x\sim p_{data}}\left[\log D(x_) \right ]+\mathbb{E}_{z\sim p_z}\left[\log (1-D(G(z))) \right ]

由于期望代表的是數據均值,因此,式子可以改為:

\begin{aligned} \min\limits_{G}\max\limits_{D}V(D,G) &=\frac {1}{n}\sum_{i=1}^{n}\log D(x_i)+\frac {1}{n}\sum_{i=1}^{n}\log (1-D(G(z_i))) \\ &= \frac {1}{n}\sum_{i=1}^{n}\left [ \log D(x_i)+\log (1-D(G(z_i))) \right ] \end{aligned}

?其中,x_i?為真實數據,z_i?為與真實數據結構相似的隨機噪音,G(z_i)?為生成器生成的假數據,D(x_i)?為判別器在真實數據?x_i?上的判別的結果,D(G(z_i))?為判別器在假數據(G(z_i))上判別的結果,其中?D(x_i)?與?D(G(z_i))?都是樣本為真(標簽為1)的概率。

由于?D(x_i)?與?D(G(z_i))?都是概率,所以值在 (0,1] 之間,因此,取對數后的值域為(-\propto ,0),所以損失?V 的值域也在(-\propto ,0)。并且 V 在判別器的能力最好時達到最大值,說明判別器越準確,V反而越大,這顯然與普通的二分類損失相反。但是,如果分別從判別器和生成器的角度看,又是合理的。

2. 對于判別器損失

在 V 的表達式中,對數都與判別器有關,因此,對于判別器來說,V 即判別器的損失:

\min\limits_{G}\max\limits_{D}V(D,G)=\frac {1}{n}\sum_{i=1}^{n}\left [ \log D(x_i)+\log (1-D(G(z_i))) \right ]

我解釋一下,判別器的目的是盡量使自己作出正確的判斷,且判別器輸出的是標簽為真的概率,因此,判別器的最佳表現是:對于所有在真實數據上的判別器的輸出?D(x_i)?都接近1,所有假數據上判別器?D(G(z_i))?都接近0,因此,對于判別器的最佳損失就是:

\begin{aligned} \max\limits_{D}L_D &= \frac {1}{n} \sum _{i=1}^{n}\left [ \log D(x_i)+\log (1-D(G(z_i)) \right ] \\ &=\frac {1}{n} \sum _{i=1}^{n}\left [ \log 1+\log (1-0) \right ] \\ &=0 \end{aligned}

  • 因此,判別器希望?L_D?越大越好,即\max\limits_{D},判別能力越強,值越大,理想情況下值最大為0。

3. 對于生成器損失

V 的表達式中,生成器只會影響?D(G(z_i)),因此只有 V 的后半部分的表達式與生成器有關,即:

\min\limits_{G}L_G=\frac {1}{n} \sum _{i=1}^{n}\left[C+\log (1-D(G(z_i))) \right ]

去掉常數項:

\min\limits_{G}L_G=\frac {1}{n} \sum _{i=1}^{n}\log (1-D(G(z_i)))

生成器的目標是盡可能使生成的假數據讓判別器判斷為真,即?D(G(z_i))?越接近1越好,因此,對于生成器的最佳損失為:

\min\limits_{G}L_G=\frac {1}{n} \sum _{i=1}^{n}\log (1-1))=-\propto

  • 可以看出,生成器希望?L_G?越小越好,即\min\limits_{G}無限接近負無窮,因此生成器的本質就是追求D(G(z_i))?無限接近 1。對生成器而言,V 更像是一個損失,即模型表現越好,該指標的值越低。
  • 從整個GAN的角度看,我們的目標就是與生成器的目標一致,因此,對于我們而言,V就被當做損失,并且越低越好。

4. 求最優解

上面我已經推導了GAN損失函數?V?的由來,那么如何求最優解呢?下面我們來推導一下:

\min\limits_{G}\max\limits_{D}V(D,G)=\mathbb{E}_{x\sim p_{data}}\left[\log D(x_) \right ]+\mathbb{E}_{z\sim p_z}\left[\log (1-D(G(z))) \right ]

第一步:固定生成器 G,求最優判別器 D:

當我們固定 G 時,要求最優判別器 D,此時 G 是確定的,因此?G(z)?生成了一個偽樣本?x,這意味這我們可以把:

x=G(z)x?服從分布p_g(x),即x\sim p_g(x)

因此,第二項期望就可以寫作:

\mathbb{E}_{z\sim p_z(z)}\left[\log (1-D(G(x))) \right ]=\mathbb{E}_{x\sim p_g(x)}\left[\log(1-D(x)) \right ]

所以,原式就變為了:

\min\limits_{G}\max\limits_{D}V(D,G)=\mathbb{E}_{x\sim p_{data}}\left[\log D(x_) \right ]+\mathbb{E}_{x\sim p_g(x)}\left[\log(1-D(x)) \right ]

我們將期望轉化為積分:

V(D,G)=\int _x p_{data}(x)\log D(x)dx+\int _xp_{g}\log(1-D(x))dx

將兩個分布?p_{data}?和?p_{g}?放在同一個積分中:

V(D,G)=\int _x \left[ p_{data}(x)\log D(x)+p_{g}(x)\log(1-D(x)) \right ]dx

這是一個關于?D(x)?的泛化優化問題,對每個點?x,我們要最大化,令:

f(D(x))=p_{data}(x)\log D(x)+p_{g}\log(1-D(x))

對?D(x)?求導數,令導數為 0,得到最優?D(x)

\frac {df}{dD}=\frac {p_{data}(x)}{D(x)}- \frac {p_g(x)}{1-D(x)}=0

解得:

\frac {p_{data}(x)}{D(x)}=\frac {p_g(x)}{1-D(x)}

D(x)=\frac {p_{data}(x)}{p_{data}(x)+p_g(x)}

第二步:將?D(x)?代入原損失函數,優化生成器的目標??\min\limits_{G} \max\limits_{D}V(D,G)

\begin{aligned} V(D,G) =\int _xp_{data}(x)log(\frac {p_{data}(x)}{p_{data}(x)+p_g(x)})dx+\int _x p_g(x)log(\frac {p_{g}(x)}{p_{data}(x)+p_g(x)})dx \end{aligned}

我們對其化簡:

\begin{aligned} V(D,G) &=\int _xp_{data}(x)log(\frac {p_{data}(x)}{\frac {p_{data}(x)+p_g(x)}{2}}\frac {1}{2})dx+\int _x p_{x}\log (\frac {p_g(x)}{\frac {p_g(x)+p_{data}(x)}{2}}\frac {1}{2})dx \\ &= \int _xp_{data}(x)log(\frac {p_{data}(x)}{\frac {p_{data}(x)+p_g(x)}{2}})dx+\int _x p_{x}\log (\frac {p_g(x)}{\frac {p_g(x)+p_{data}(x)}{2}})dx +\int _x \log \frac {1}{2} p_{data}(x)dx+\int _x \log \frac {1}{2} p_g(x)dx \\ &= \int _xp_{data}(x)log(\frac {p_{data}(x)}{\frac {p_{data}(x)+p_g(x)}{2}})dx+\int _x p_{x}\log (\frac {p_g(x)}{\frac {p_g(x)+p_{data}(x)}{2}})dx +\log \frac {1}{2}\int _x p_{data}(x)dx+\log \frac {1}{2}\int _x p_g(x)dx \\ &= \int _xp_{data}(x)log(\frac {p_{data}(x)}{\frac {p_{data}(x)+p_g(x)}{2}})dx+\int _x p_{x}\log (\frac {p_g(x)}{\frac {p_g(x)+p_{data}(x)}{2}})dx +\log \frac {1}{2}+\log \frac {1}{2} \\ &= \int _xp_{data}(x)log(\frac {p_{data}(x)}{\frac {p_{data}(x)+p_g(x)}{2}})dx+\int _x p_{x}\log (\frac {p_g(x)}{\frac {p_g(x)+p_{data}(x)}{2}})dx +\log \frac {1}{4} \\ &= KL\left ( p_{data}(x)||\frac {p_{data}(x)+p_g(x)}{2} \right )+KL\left ( p_g(x)||\frac {p_{data}(x)+p_g(x)}{2} \right )-\log 4 \end{aligned}

這里,我們介紹一個概念,Jensen-Shannon散度,是衡量兩個分布差異的對稱度量,它與KL散度有如下關系:

\begin{aligned} JS(p_{a}(x)||p_{b}(x))=\frac {1}{2}KL(p_{a}(x)||m)+\frac {1}{2}KL(p_{b}(x)||m) \end{aligned}

因此,最終式子變為:

\begin{aligned} V(D,G) &= 2*JS(p_{data}{x}||p_{g)(x)})-\log \frac {1}{4} \end{aligned}

若要使得?V(D,G)?取得最小,那么KL散度應當為0,當KL散度為0時,就相當于:

\begin{aligned} p_{data}(x) &=\frac {p_{data}(x)+p_g(x)}{2} \\ p_{data}(x) &=p_g(x) \end{aligned})

由此可知,?p_{g}(x)?逼近p_{data}(x)?時,目標函數取得最優值,并且當

\begin{aligned} D(x) &=\frac {p_{data}(x)}{p_g(x)+p_{data}(x)} \\ &=\frac {1}{2} \end{aligned}

判別器就無法判斷出樣本是來自假數據樣本?p_{g}(x),還是來自真實數據樣本p_{data}(x)?了,此時生成器的生成效果便達到了最好。


三、GAN的訓練流程

接下來,我將使用MINST數據集來實現一下GAN的訓練流程:

訓練過程:

import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
from torchvision.utils import save_image, make_grid
from torch.utils.tensorboard import SummaryWriter
import os# 定義生成器與判別器
class Generator(nn.Module):def __init__(self, latent_dim):super().__init__()self.net = nn.Sequential(nn.ConvTranspose2d(latent_dim, 256, 4, 1, 0),  # 1x1 -> 4x4nn.BatchNorm2d(256),nn.ReLU(True),nn.ConvTranspose2d(256, 128, 4, 2, 1),  # 4x4 -> 8x8nn.BatchNorm2d(128),nn.ReLU(True),nn.ConvTranspose2d(128, 64, 4, 2, 1),   # 8x8 -> 16x16nn.BatchNorm2d(64),nn.ReLU(True),nn.ConvTranspose2d(64, 1, 4, 4, 0),     # 16x16 -> 64x64nn.Tanh())def forward(self, z):return self.net(z)class Discriminator(nn.Module):def __init__(self):super().__init__()self.net = nn.Sequential(nn.Conv2d(1, 64, 4, 4, 0),  # 64x64 -> 16x16nn.LeakyReLU(0.2, inplace=True),nn.Conv2d(64, 128, 4, 2, 1),  # 16x16 -> 8x8nn.BatchNorm2d(128),nn.LeakyReLU(0.2, inplace=True),nn.Conv2d(128, 256, 4, 2, 1),  # 8x8 -> 4x4nn.BatchNorm2d(256),nn.LeakyReLU(0.2, inplace=True),nn.Conv2d(256, 1, 4, 1, 0),   # 4x4 -> 1x1nn.Sigmoid())def forward(self, x):return self.net(x).view(-1, 1).squeeze(1)
# 設置超參數
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
latent_dim = 100
batch_size = 128
epochs = 50
image_size = 64
lr = 2e-4
log_dir = "./GAN/runs/log"
sample_dir = "./GAN/samples"
os.makedirs(sample_dir, exist_ok=True)# 加載數據
transform = transforms.Compose([transforms.Resize(image_size),transforms.ToTensor(),transforms.Normalize([0.5], [0.5])
])
dataset = datasets.MNIST(root='./GAN', train=True, transform=transform, download=False)
dataloader = torch.utils.data.DataLoader(dataset, batch_size=batch_size, shuffle=True)G = Generator(latent_dim).to(device)
D = Discriminator().to(device)
criterion = nn.BCELoss()
optimizer_G = optim.Adam(G.parameters(), lr=lr, betas=(0.5, 0.999))
optimizer_D = optim.Adam(D.parameters(), lr=lr, betas=(0.5, 0.999))writer = SummaryWriter(log_dir)
fixed_noise = torch.randn(64, latent_dim, 1, 1, device=device)
best_d_loss = float('inf')
# 訓練
for epoch in range(epochs):for i, (real_imgs, _) in enumerate(dataloader):real_imgs = real_imgs.to(device)valid = torch.ones(real_imgs.size(0), device=device)fake = torch.zeros(real_imgs.size(0), device=device)# -------------------#  訓練生成器 G# -------------------optimizer_G.zero_grad()z = torch.randn(real_imgs.size(0), latent_dim, 1, 1, device=device)gen_imgs = G(z)g_loss = criterion(D(gen_imgs), valid)g_loss.backward()optimizer_G.step()# -----------------------#  訓練判別器 D# -----------------------optimizer_D.zero_grad()real_loss = criterion(D(real_imgs), valid)fake_loss = criterion(D(gen_imgs.detach()), fake)d_loss = real_loss + fake_lossd_loss.backward()optimizer_D.step()# 日志記錄batches_done = epoch * len(dataloader) + iwriter.add_scalar("Loss/Generator", g_loss.item(), batches_done)writer.add_scalar("Loss/Discriminator", d_loss.item(), batches_done)print(f"Epoch {epoch+1}/{epochs} | G_loss: {g_loss.item():.4f} | D_loss: {d_loss.item():.4f}")# 保存最優模型if d_loss.item() < best_d_loss:best_d_loss = d_loss.item()torch.save(G.state_dict(), "best_generator.pth")torch.save(D.state_dict(), "best_discriminator.pth")

生成:

# 生成新圖像
加載保存訓練好的生成器
G.load_state_dict(torch.load("best_generator.pth", map_location=device))
G.eval()
noise = torch.randn(64, latent_dim, 1, 1, device=device)
with torch.no_grad():fake_imgs = G(noise).detach().cpu()
os.makedirs("final_samples", exist_ok=True)
grid = make_grid(fake_imgs, nrow=8, normalize=True)
save_image(grid, "final_samples/generated_grid.png")

在這里,我簡單的訓練了一個GAN網絡,并生成64張數字圖片,生成效果如下:

可以看到,簡單訓練的GAN能夠生成不錯的效果。


總結

?以上就是本文對GAN原理的全部介紹,相信小伙伴們在看完之后對GAN的原理會有更深刻的理解。總的來說,GAN為我們帶來了新的視角,它讓我們不再試圖去擬合復雜的數據分布,而是建立一個“博弈系統”,通過競爭機制驅動模型學習。從14年到現在,基于GAN架構的生成模型已經發展了很多,比如StyleGAN、CycleGAN等模型,但是它們的核心仍然是GAN的架構。


如果小伙伴們覺得本文對各位有幫助,歡迎:👍點贊 |?? 收藏 | ?🔔 關注。我將持續在專欄《人工智能》中更新人工智能知識,幫助各位小伙伴們打好扎實的理論與操作基礎,歡迎🔔訂閱本專欄,向AI工程師進階!

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

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

相關文章

限流算法java實現

參考教程&#xff1a;2小時吃透4種分布式限流算法 1.計數器限流 public class CounterLimiter {// 開始時間private static long startTime System.currentTimeMillis();// 時間間隔&#xff0c;單位為msprivate long interval 1000L;// 限制訪問次數private int limitCount…

Maven 構建性能優化深度剖析:原理、策略與實踐

&#x1f9d1; 博主簡介&#xff1a;CSDN博客專家&#xff0c;歷代文學網&#xff08;PC端可以訪問&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移動端可微信小程序搜索“歷代文學”&#xff09;總架構師&#xff0c;15年工作經驗&#xff0c;精通Java編…

JS手寫代碼篇---手寫深拷貝

17、深拷貝 深拷貝與淺拷貝最大的不同就是對象的屬性是嵌套對象&#xff0c;會新建一個對象 步驟&#xff1a; 判斷是否為對象判斷是否為i數組或者對象&#xff0c;給新的有個容器遍歷循環&#xff0c;如果是對象要遍歷循環&#xff0c;采用遞歸 function deepCopy(obj){// …

【react實戰】如何實現監聽窗口大小變化

在日常開發場景中&#xff0c;監聽窗口變化是一個比較常見又很重要的業務功能&#xff0c;其實實現起來也很簡單&#xff0c;今天就來記錄一下具體的實現以及注意事項。 實現思路 在 React 中&#xff0c;可以通過監聽 window 的 resize 事件來檢測可視區域&#xff08;viewp…

AVCap視頻處理成幀和音頻腳本

###############處理原視頻&#xff0c;使其格式和原數據一樣 import os import cv2 import subprocess import json from PIL import Image from pydub import AudioSegmentimport sys import shutil # &#x1f539; 第一步&#xff1a;強制檢測并設置FFmpeg路徑 &#x1f5…

數據冗余對企業運營的隱性成本

從客戶管理到供應鏈優化&#xff0c;再到市場分析&#xff0c;數據無處不在&#xff0c;數據已成為企業運營的核心驅動力。然而&#xff0c;隨著企業IT系統的多樣化和數據量的激增&#xff0c;數據冗余&#xff08;Data Redundancy&#xff09;問題逐漸浮出水面&#xff0c;成為…

HTML原生日期插件增加周次顯示

<div id="app" class="box box-info" style="border-top-color:white;"><!-- // 日期部分 --><div class="date-picker-container" style="position: relative; max-width: 200px;"><!-- 日期輸入框 -…

滲透測試PortSwigger Labs:遭遇html編碼和轉義符的反射型XSS

1 處是我們輸入的標簽被服務器 html 編碼后返回&#xff0c;被瀏覽器當作字符串顯示出來&#xff0c;無法執行 javascript 2 處是唯一能控制的地方&#xff0c;正好在script標簽范圍內&#xff0c;可以嘗試構造 依然存在轉移單引號&#xff0c;我們輸入轉義符\讓服務器添加的轉…

Ansible 錯誤處理:確保高效自動化

當 Ansible 收到命令的非零返回碼或模塊故障時,默認情況下,它會停止在該主機上的執行,并在其他主機上繼續執行。但是,在某些情況下,您可能需要不同的行為。有時非零返回碼表示成功。有時您希望一臺主機上的故障導致所有主機上的執行停止。Ansible 提供了處理這些情況的工具…

【無標題】NP完全問題的拓撲對偶統一解法 ——四色問題到P=NP的普適框架

NP完全問題的拓撲對偶統一解法 ——四色問題到PNP的普適框架 **摘要** 本文提出基于**拓撲膨脹-收縮對偶性**的計算理論框架&#xff0c;突破傳統NP完全性理論局限。通過將離散組合問題轉化為連續幾何問題&#xff0c;并引入規范場量子求解機制&#xff0c;實現四色問題、子…

【Zephyr 系列 19】打造 BLE 模塊完整 SDK:AT 命令系統 + 狀態機 + NVS + OTA 一體化構建

??關鍵詞:Zephyr、BLE 模塊、SDK 構建、AT 命令框架、有限狀態機、Flash 配置、MCUboot OTA ??面向讀者:希望將 BLE 項目標準化、封裝化、支持量產使用的開發團隊與架構師 ??預計字數:5500+ 字 ?? 背景與目標 在完成多個 BLE 功能模塊后,一個企業級產品往往需要:…

機器學習核心概念速覽

機器學習基本概念 有監督學習分類、回歸無監督學習聚類、降維 一維數組 import numpy as np data np.array([1,2,3,4,5]) print(data) print(data.shape) print(len(data.shape))[1 2 3 4 5] (5,) 1二維數組 data2 np.array([[1,2,3],[4,5,6]]) print(data2) print(data2…

在 Java 中實現一個標準 Service 接口,并通過配置動態選擇具體實現類供 Controller 調用

在 Java 中實現一個標準 Service 接口&#xff0c;并通過配置動態選擇具體實現類供 Controller 調用&#xff0c;是解耦和靈活擴展的常見設計模式。 需求分析 當你需要開發一個需要靈活切換業務實現的系統&#xff0c;比如不同環境使用不同策略&#xff08;如測試環境用Mock實…

input+disabled/readonly問題

背景&#xff1a; vue2elementui <el-input v-model"inputForm.projectName" class"input-font" :disabled"projectDisabled" placeholder"請選擇" :readonly"isReadonly"><el-button slot"append"…

Office2019下載安裝教程(2025最新永久方法)(附安裝包)

文章目錄 Office2019安裝包下載Office2019一鍵安裝步驟&#xff08;超詳細&#xff01;&#xff09; 大家好&#xff01;今天給大家帶來一篇超實用的Office2019專業版安裝教程&#xff01;作為日常辦公和學習的必備軟件&#xff0c;Office的安裝對很多朋友來說可能有點復雜&…

【編譯工具】(版本控制)Git + GitHub Actions:自動化工作流如何讓我的開發效率提升200%?

目錄 引言&#xff1a;現代開發中版本控制和 CI/CD 的重要性 一、Git&#xff1a;為什么它是版本控制的首選&#xff1f; &#xff08;1&#xff09;Git 的核心優勢 &#xff08;2&#xff09;Git 高效工作流示例 ① 功能開發流程 ② 緊急修復流程 二、GitHub Acti…

碼蹄杯真題分享

我的個人主頁 我的專欄&#xff1a; 人工智能領域、java-數據結構、Javase、C語言&#xff0c;MySQL&#xff0c;希望能幫助到大家&#xff01;&#xff01;&#xff01; 點贊&#x1f44d;收藏? 1&#xff1a;房間打掃&#xff08;題目鏈接&#xff09; 思路&#xff1a;要想…

小米玄戒O1架構深度解析(二):多核任務調度策略詳解

上篇文章中&#xff0c;就提到了小米玄戒O1的多核任務調度策略&#xff0c;但講得不夠詳細&#xff0c;尤其是對于完全公平調度器和能效感知調度&#xff0c;這次我們就深度剖析一下這兩種調度策略。 目錄 1. 完全公平調度器&#xff08;CFS&#xff09;1.1 完全公平調度基本原…

【技巧】win10和ubuntu互相掛在共享文件夾

回到目錄 【技巧】win10和ubuntu互相掛在共享文件夾 1. ubuntu掛載win10共享文件夾 $ sudo apt update $ sudo apt install cifs-utils $ sudo mkdir /mnt/[這里改為ubuntu共享目錄名] $ sudo mount -t cifs -o usernameadministrator //[這里改為win10機器IP]/[這里改為win…

線程(下)【Linux操作系統】

文章目錄 線程控制線程共享進程地址空間中的所有數據線程會瓜分進程的時間片線程相關庫函數庫函數&#xff1a;pthread_create庫函數&#xff1a;pthread_self庫函數&#xff1a;pthread_join庫函數&#xff1a;pthread_exit庫函數&#xff1a;pthread_cancel[盡量少用]庫函數&…