網(wǎng)站設(shè)計(jì)建設(shè)公司廣州seo優(yōu)化排名公司
對(duì)抗生成網(wǎng)絡(luò)
知識(shí)點(diǎn)回顧:
- 對(duì)抗生成網(wǎng)絡(luò)的思想:關(guān)注損失從何而來(lái)
- 生成器、判別器
- nn.sequential容器:適合于按順序運(yùn)算的情況,簡(jiǎn)化前向傳播寫法
- leakyReLU介紹:避免relu的神經(jīng)元失活現(xiàn)象
對(duì)抗生成網(wǎng)絡(luò)(GAN)
知識(shí)點(diǎn)回顧
-
對(duì)抗生成網(wǎng)絡(luò)的思想
-
思想:就像在餐廳中,有一個(gè)廚師(生成器)負(fù)責(zé)制作假菜,一個(gè)評(píng)論家(判別器)負(fù)責(zé)區(qū)分真菜和假菜。廚師的目標(biāo)是制作出評(píng)論家無(wú)法區(qū)分的假菜,而評(píng)論家的目標(biāo)是找出假菜。通過(guò)不斷的對(duì)抗訓(xùn)練,廚師的廚藝(生成器的生成能力)和評(píng)論家的鑒賞力(判別器的判別能力)都會(huì)不斷提高。
-
對(duì)抗生成網(wǎng)絡(luò)(GAN)由兩個(gè)模型組成:生成器和判別器。生成器的目標(biāo)是生成盡可能真實(shí)的樣本,而判別器的目標(biāo)是區(qū)分真實(shí)樣本和生成樣本。兩者通過(guò)對(duì)抗訓(xùn)練不斷優(yōu)化,最終達(dá)到納什均衡。
-
損失來(lái)源:GAN 的損失函數(shù)來(lái)自生成器和判別器之間的對(duì)抗。判別器的損失來(lái)自于它對(duì)真實(shí)樣本和生成樣本的誤判,生成器的損失來(lái)自于它生成的樣本被判別器識(shí)別為假樣本。
-
-
生成器和判別器
-
生成器:廚師,負(fù)責(zé)制作假菜,目標(biāo)是讓評(píng)論家無(wú)法區(qū)分真假菜。類似于一個(gè)“偽造者”,負(fù)責(zé)生成盡可能真實(shí)的樣本。
-
判別器:評(píng)論家,負(fù)責(zé)區(qū)分真菜和假菜,目標(biāo)是找出所有的假菜。類似于一個(gè)“警察”,負(fù)責(zé)區(qū)分真實(shí)樣本和生成樣本。
-
-
nn.Sequential
容器-
定義:
nn.Sequential
是一個(gè)順序容器,用于按順序堆疊多個(gè)神經(jīng)網(wǎng)絡(luò)層。這簡(jiǎn)化了前向傳播的寫法,適合于層與層之間按順序運(yùn)算的情況。
-
-
LeakyReLU 介紹
-
定義:就像是餐廳的菜譜,按順序列出每個(gè)烹飪步驟,簡(jiǎn)化了廚師的烹飪流程。LeakyReLU 是 ReLU 的變種,允許一小部分梯度通過(guò),避免神經(jīng)元失活現(xiàn)象。類似于在烹飪過(guò)程中,允許某些食材保留一定的原始風(fēng)味,避免某些食材完全失活,從而豐富菜品的層次感。
-
公式:
LeakyReLU(x) = max(0.01 * x, x)
,其中 0.01 是負(fù)斜率。
-
作業(yè)
-
對(duì)于心臟病數(shù)據(jù)集,對(duì)于病人這個(gè)不平衡的樣本用 GAN 來(lái)學(xué)習(xí)并生成病人樣本,觀察不用 GAN 和用 GAN 的 F1 分?jǐn)?shù)差異
-
步驟:
-
數(shù)據(jù)準(zhǔn)備:加載心臟病數(shù)據(jù)集,處理數(shù)據(jù)以適應(yīng) GAN 的輸入要求。
-
定義生成器和判別器:使用
nn.Sequential
定義生成器和判別器。 -
訓(xùn)練 GAN:通過(guò)對(duì)抗訓(xùn)練生成器和判別器。
-
數(shù)據(jù)增強(qiáng):使用生成器生成額外的病人樣本,增加數(shù)據(jù)集的多樣性。
-
模型訓(xùn)練:使用原始數(shù)據(jù)集和增強(qiáng)后的數(shù)據(jù)集分別訓(xùn)練分類模型,比較 F1 分?jǐn)?shù)。
-
-
import pandas as pd
import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import f1_score
from sklearn.impute import SimpleImputer# 加載數(shù)據(jù)
df = pd.read_csv('heart.csv')# 特征和標(biāo)簽分離
X = df.drop('target', axis=1)
y = df['target']# 檢查缺失值
print("原始數(shù)據(jù)集中缺失值情況:")
print(df.isnull().sum())# 使用SimpleImputer填補(bǔ)缺失值
imp = SimpleImputer(missing_values=np.nan, strategy='mean')
X_imputed = imp.fit_transform(X)# 將數(shù)據(jù)分為病人和健康人
X_patients = X_imputed[y == 1]
X_healthy = X_imputed[y == 0]# 特征標(biāo)準(zhǔn)化
scaler = StandardScaler()
X_patients = scaler.fit_transform(X_patients)
X_healthy = scaler.transform(X_healthy)# 將數(shù)據(jù)轉(zhuǎn)換為PyTorch張量
X_patients_tensor = torch.tensor(X_patients, dtype=torch.float32)
X_healthy_tensor = torch.tensor(X_healthy, dtype=torch.float32)# 定義生成器
generator = nn.Sequential(nn.Linear(100, 128),nn.ReLU(),nn.Linear(128, 256),nn.ReLU(),nn.Linear(256, X_patients.shape[1]),nn.Tanh()
)# 定義判別器
discriminator = nn.Sequential(nn.Linear(X_patients.shape[1], 256),nn.LeakyReLU(0.2),nn.Linear(256, 128),nn.LeakyReLU(0.2),nn.Linear(128, 1),nn.Sigmoid()
)# 定義損失函數(shù)和優(yōu)化器
criterion = nn.BCELoss()
lr = 0.0002
optimizer_g = optim.Adam(generator.parameters(), lr=lr)
optimizer_d = optim.Adam(discriminator.parameters(), lr=lr)# 訓(xùn)練 GAN
num_epochs = 1000
batch_size = 32for epoch in range(num_epochs):# 訓(xùn)練判別器# 真實(shí)樣本real_data = X_patients_tensor[torch.randint(0, X_patients_tensor.shape[0], (batch_size,))]real_labels = torch.ones(batch_size, 1)d_real_loss = criterion(discriminator(real_data), real_labels)# 生成樣本noise = torch.randn(batch_size, 100)fake_data = generator(noise)fake_labels = torch.zeros(batch_size, 1)d_fake_loss = criterion(discriminator(fake_data.detach()), fake_labels)# 總損失和優(yōu)化d_loss = d_real_loss + d_fake_lossoptimizer_d.zero_grad()d_loss.backward()optimizer_d.step()# 訓(xùn)練生成器noise = torch.randn(batch_size, 100)fake_data = generator(noise)g_loss = criterion(discriminator(fake_data), real_labels)optimizer_g.zero_grad()g_loss.backward()optimizer_g.step()if epoch % 100 == 0:print(f'Epoch [{epoch}/{num_epochs}] | D Loss: {d_loss.item():.4f} | G Loss: {g_loss.item():.4f}')# 生成額外的病人樣本
num_new_samples = 100
noise = torch.randn(num_new_samples, 100)
generated_samples = generator(noise).detach().numpy()# 反標(biāo)準(zhǔn)化生成的樣本
generated_samples = scaler.inverse_transform(generated_samples)# 將生成的樣本添加到原始數(shù)據(jù)集中
X_generated = pd.DataFrame(generated_samples, columns=df.columns[:-1])
y_generated = pd.Series([1] * num_new_samples, name='target')# 合并原始數(shù)據(jù)集和生成的數(shù)據(jù)集
X_augmented = pd.concat([df, X_generated])
y_augmented = pd.concat([y, y_generated])# 使用 SimpleImputer 填補(bǔ)增強(qiáng)數(shù)據(jù)集中的缺失值
X_augmented_imputed = imp.transform(X_augmented)# 使用原始數(shù)據(jù)集訓(xùn)練模型
X_train, X_test, y_train, y_test = train_test_split(X_imputed, y, test_size=0.2, random_state=42)
model = LogisticRegression()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
f1_original = f1_score(y_test, y_pred)# 使用增強(qiáng)后的數(shù)據(jù)集訓(xùn)練模型
X_augmented_train, X_augmented_test, y_augmented_train, y_augmented_test = train_test_split(X_augmented_imputed, y_augmented, test_size=0.2, random_state=42)
model_augmented = LogisticRegression()
model_augmented.fit(X_augmented_train, y_augmented_train)
y_augmented_pred = model_augmented.predict(X_augmented_test)
f1_augmented = f1_score(y_augmented_test, y_augmented_pred)print(f'Original F1 Score: {f1_original:.4f}')
print(f'Augmented F1 Score: {f1_augmented:.4f}')
import pandas as pd
import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import f1_score
from sklearn.impute import SimpleImputer# 加載數(shù)據(jù)
df = pd.read_csv('heart.csv')# 特征和標(biāo)簽分離
X = df.drop('target', axis=1)
y = df['target']# 檢查缺失值
print("原始數(shù)據(jù)集中缺失值情況:")
print(df.isnull().sum())# 使用 SimpleImputer 填補(bǔ)缺失值
imp = SimpleImputer(missing_values=np.nan, strategy='mean')
X_imputed = imp.fit_transform(X)# 將數(shù)據(jù)分為病人和健康人
X_patients = X_imputed[y == 1]
X_healthy = X_imputed[y == 0]# 特征標(biāo)準(zhǔn)化
scaler = StandardScaler()
X_patients = scaler.fit_transform(X_patients)
X_healthy = scaler.transform(X_healthy)# 將數(shù)據(jù)轉(zhuǎn)換為 PyTorch 張量
X_patients_tensor = torch.tensor(X_patients, dtype=torch.float32)
X_healthy_tensor = torch.tensor(X_healthy, dtype=torch.float32)# 定義生成器
generator = nn.Sequential(nn.Linear(100, 128),nn.ReLU(),nn.Linear(128, 256),nn.ReLU(),nn.Linear(256, X_patients.shape[1]),nn.Tanh()
)# 定義判別器
discriminator = nn.Sequential(nn.Linear(X_patients.shape[1], 256),nn.LeakyReLU(0.2),nn.Linear(256, 128),nn.LeakyReLU(0.2),nn.Linear(128, 1),nn.Sigmoid()
)# 定義損失函數(shù)和優(yōu)化器
criterion = nn.BCELoss()
lr = 0.0002
optimizer_g = optim.Adam(generator.parameters(), lr=lr)
optimizer_d = optim.Adam(discriminator.parameters(), lr=lr)# 訓(xùn)練 GAN
num_epochs = 1000
batch_size = 32for epoch in range(num_epochs):# 訓(xùn)練判別器# 真實(shí)樣本real_data = X_patients_tensor[torch.randint(0, X_patients_tensor.shape[0], (batch_size,))]real_labels = torch.ones(batch_size, 1)d_real_loss = criterion(discriminator(real_data), real_labels)# 生成樣本noise = torch.randn(batch_size, 100)fake_data = generator(noise)fake_labels = torch.zeros(batch_size, 1)d_fake_loss = criterion(discriminator(fake_data.detach()), fake_labels)# 總損失和優(yōu)化d_loss = d_real_loss + d_fake_lossoptimizer_d.zero_grad()d_loss.backward()optimizer_d.step()# 訓(xùn)練生成器noise = torch.randn(batch_size, 100)fake_data = generator(noise)g_loss = criterion(discriminator(fake_data), real_labels)optimizer_g.zero_grad()g_loss.backward()optimizer_g.step()if epoch % 100 == 0:print(f'Epoch [{epoch}/{num_epochs}] | D Loss: {d_loss.item():.4f} | G Loss: {g_loss.item():.4f}')# 生成額外的病人樣本
num_new_samples = 100
noise = torch.randn(num_new_samples, 100)
generated_samples = generator(noise).detach().numpy()# 反標(biāo)準(zhǔn)化生成的樣本
generated_samples = scaler.inverse_transform(generated_samples)# 將生成的樣本轉(zhuǎn)換為 DataFrame
generated_df = pd.DataFrame(generated_samples, columns=X.columns)# 合并原始數(shù)據(jù)集和生成的數(shù)據(jù)集
augmented_df = pd.concat([df, generated_df])
augmented_df['target'] = pd.concat([y, pd.Series([1] * num_new_samples)])# 使用 SimpleImputer 填補(bǔ)增強(qiáng)數(shù)據(jù)集中的缺失值
augmented_imputer = SimpleImputer(missing_values=np.nan, strategy='mean')
augmented_imputer.fit(X) # 使用原始特征來(lái)擬合
X_augmented_imputed = augmented_imputer.transform(augmented_df.drop('target', axis=1))# 使用原始數(shù)據(jù)集訓(xùn)練模型
X_train, X_test, y_train, y_test = train_test_split(X_imputed, y, test_size=0.2, random_state=42)
model = LogisticRegression()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
f1_original = f1_score(y_test, y_pred)# 使用增強(qiáng)后的數(shù)據(jù)集訓(xùn)練模型
X_augmented_train, X_augmented_test, y_augmented_train, y_augmented_test = train_test_split(X_augmented_imputed, augmented_df['target'], test_size=0.2, random_state=42)
model_augmented = LogisticRegression()
model_augmented.fit(X_augmented_train, y_augmented_train)
y_augmented_pred = model_augmented.predict(X_augmented_test)
f1_augmented = f1_score(y_augmented_test, y_augmented_pred)print(f'Original F1 Score: {f1_original:.4f}')
print(f'Augmented F1 Score: {f1_augmented:.4f}')
ps;如果你學(xué)有余力,對(duì)于gan的損失函數(shù)的理解,建議去找找視頻看看,如果只是用,沒(méi)必要學(xué)
@浙大疏錦行