le mie informazioni di contatto
Posta[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
#Datawhale #AIsummercamp#summercamp
Il compito del concorso è determinare se un'immagine del volto è un'immagine Deepfake e fornire un punteggio di probabilità che si tratti di un'immagine Deepfake. I partecipanti devono sviluppare e ottimizzare modelli di rilevamento per far fronte alle diverse tecnologie di generazione dei deepfake e agli scenari applicativi complessi, migliorando così la precisione e la robustezza del rilevamento delle immagini deepfake.
Il file etichetta train_label.txt del set di training viene utilizzato per l'addestramento del modello, mentre il file etichetta val_label.txt del set di convalida viene utilizzato solo per l'ottimizzazione del modello. Ad esempio, in train_label.txt o val_label.txt, ogni riga contiene due parti, separate da virgole. La prima parte è il nome del file (suffisso .mp4), la seconda parte è il valore effettivo.
Un valore target pari a 1 indica audio e video profondamente falsi, mentre un valore target pari a 0 indica audio e video reali.
Di seguito sono riportati esempi di train_label.txt e val_label.txt:
train_label.txt
video_name,target
96b04c80704f02cb426076b3f624b69e.mp4,0
16fe4cf5ae8b3928c968a5d11e870360.mp4,1
val_label.txt
video_name,target
f859cb3510c69513d5c57c6934bc9968.mp4,0
50ae26b3f3ea85babb2f9dde840830e2.mp4,1
Ogni riga del file contiene due parti, separate da virgole. La prima parte è il nome del file video e la seconda parte è il punteggio deepfake corrispondente alla previsione del modello (ovvero il valore di probabilità del campione appartenente al video deepfake). Si prega di fare riferimento al modello di invio riportato di seguito:
prediction.csv
video_name,score
658042526e6d0c199adc7bfeb1f7c888.mp4,0.123456
a20cf2d7dea580d0affc4d85c9932479.mp4,0.123456
Alla prima fase segue la seconda fase, in cui viene rilasciato il set di test pubblico. I partecipanti devono inviare al sistema il file del punteggio di previsione predizione_test.csv del set di test e fornire feedback online in tempo reale sui risultati del punteggio del test.
Dopo la seconda fase, le prime 30 squadre avanzeranno alla terza fase. In questa fase, i concorrenti devono inviare il code docker e le relazioni tecniche. I requisiti Docker includono il codice di training originale e l'API di test (l'input della funzione è il percorso dell'immagine e l'output è il punteggio deepfake previsto dal modello). Lo sponsor controllerà ed eseguirà nuovamente il codice dell'algoritmo per riprodurre il processo di formazione e i risultati dei test.
È consentito inviare un solo modello e i parametri di rete validi non devono superare i 200 M (usecimaparametri del modello statistico dello strumento).
È consentito solo il training pre-modello utilizzando ImageNet1K. Campioni estesi generati sulla base del set di formazione pubblicato (tramite strumenti di aumento dei dati/deepfake) possono essere utilizzati per la formazione, ma questi strumenti devono essere inviati per la riproduzione nella terza fase.
L'indice di valutazione utilizza principalmente l'AUC sotto la curva ROC come indice. L'intervallo di valori dell'AUC è solitamente compreso0.5-1tra, altrimenti pensiamoQuesto non è un buon modello di machine learning . Più l’AUC è vicino a 1, migliore è il modello. Se l'AUC presenta risultati di classificazione ambigui, utilizziamo il **TPR (tasso di veri positivi)** come riferimento ausiliario. Naturalmente il metodo corrispondente è FPR.
Punteggio F1È anche un indicatore a cui possiamo fare riferimento: è il tasso di precisione e il tasso di richiamomedia armonica。
F 1 _ S core = 2 ∗ ( TP ) / ( 2 TP + FN + FP ) F1_Punteggio = 2*(TP)/(2TP+FN+FP)F1_Snucleo=2∗(TP)/(2TP+FN+FP)
Prima di apprendere il machine learning dovremmo rivedere due concetti importanti:PrecisioneERichiamare。
Precisione: P recisione = TPTP + FP Precisione = frac{TP}{TP+FP}PRiprodurreioooooSiooooolllllloN=TP+FPTP, che viene utilizzato per misurare il modelloControlla le prestazioni, la proporzione di campioni previsti positivi tra i campioni previsti correttamente.
Richiamare: Richiamo = TPTP + FN Richiamo = frac{TP}{TP+FN}RecUNLL=TP+FNTP, che viene utilizzato per misurare il modelloPrestazioni di ricerca, la percentuale di campioni effettivamente positivi tra i campioni previsti come positivi.
Tasso di veri positivi (TPR):
TPR = TP / (TP + FN)
Tasso di falsi positivi (FPR):
FPR = FP / (FP + TN)
In:
TP: Il campione di attacco è identificato correttamente come attacco;
TN: I campioni reali vengono correttamente identificati come reali;
FP: I campioni reali vengono erroneamente identificati come attacchi;
FN: Il campione dell'attacco viene erroneamente identificato come reale.
Riferimenti: Aghajan, H., Augusto, JC, & Delgado, RLC (Eds.) (Se il collegamento indicato nel titolo non può essere aperto, fare clic su:).intero libro)
Ecco il mio script di calcolo del TPR:
l1 = [0,1,1,1,0,0,0,1]
l2 = [0,1,0,1,0,1,0,0]
def accuracy(y_true, y_pred):
# 正确预测数初始化一个简单计数器
correct_counter = 0
# 遍历y_true, y_pred中所有元素
# zip函数接受多个元组,返回他们组成的列表
for yt, yp in zip(y_true, y_pred):
if yt == yp:
# 如果预测标签与真实标签相同,则增加计数器
correct_counter += 1
# 返回正确率,正确标签数/总标签数
return correct_counter / len(y_true)
def false_positive(y_true, y_pred):
# 初始化假阳性样本计数器
fp = 0
# 遍历y_true,y_pred中所有元素
for yt, yp in zip(y_true, y_pred):
# 若真实标签为负类但预测标签为正类,计数器增加
if yt == 0 and yp == 1:
fp += 1
return fp
def false_negative(y_true, y_pred):
# 初始化假阴性样本计数器
fn = 0
# 遍历y_true,y_pred中所有元素
for yt, yp in zip(y_true, y_pred):
# 若真实标签为正类但预测标签为负类,计数器增加
if yt == 1 and yp == 0:
fn += 1
return fn
def true_positive(y_true, y_pred):
# 初始化真阳性样本计数器
tp = 0
# 遍历y_true,y_pred中所有元素
for yt, yp in zip(y_true, y_pred):
# 若真实标签为正类且预测标签也为正类,计数器增加
if yt == 1 and yp == 1:
tp += 1
return tp
def true_negative(y_true, y_pred):
# 初始化真阴性样本计数器
tn = 0
# 遍历y_true,y_pred中所有元素
for yt, yp in zip(y_true, y_pred):
# 若真实标签为负类且预测标签也为负类,计数器增加
if yt == 0 and yp == 0:
tn += 1
# 返回真阴性样本数
return tn
# 您可以尝试更好的精确度计算方式
def accuracy_v2(y_true, y_pred):
# 真阳性样本数
tp = true_positive(y_true, y_pred)
# 假阳性样本数
fp = false_positive(y_true, y_pred)
# 假阴性样本数
fn = false_negative(y_true, y_pred)
# 真阴性样本数
tn = true_negative(y_true, y_pred)
# 准确率
accuracy_score = (tp + tn) / (tp + tn + fp + fn)
return accuracy_score
# F1-score的计算方法
def f1(y_true,y_pred):
p = precision(y_true, y_pred)
r = recall(y_true,y_pred)
score = 2*p*r/(p+r)
return score
Se è richiesta la classificazione, potrebbe essere necessaria una soglia. La sua relazione con il valore previsto è la seguente:
Previsione = Probabilità > Soglia Previsione = Probabilità > SogliaPRifDioooooCTiooooolllllloN=PiobambinolioooooTe>THrisp.HllllllolD
Dopo aver appreso l'AUC, un'altra metrica importante che dovresti apprendere è la perdita di log. Per i problemi di classificazione binaria, definiamo la perdita logaritmica come:
L og Loss = − target ∗ log ( p ) − ( 1 − target ) ∗ log ( 1 − p ) LogLoss = -target*log(p) - (1-target)*log(1-p)LllllllogLoss=−TUNRGeT∗llllllloG(P)−(1−TUNRGeT)∗llllllloG(1−P)
Tra questi, il valore target è 0 o 1 e il valore previsto è la probabilità che il campione appartenga alla categoria 1. La perdita di log penalizza sia le previsioni molto certe che quelle molto errate. Quanto minore è la perdita logaritmica, tanto più vicina è la probabilità prevista dal modello al valore target.
Possiamo anche utilizzare questi indicatori nei problemi di classificazione:
# “word count” 的缩写,是一个用于计数的 Unix 命令。-l 只计算行数
!wc -l /kaggle/input/ffdv-sample-dataset/ffdv_phase1_sample/train_label.txt
!wc -l /kaggle/input/ffdv-sample-dataset/ffdv_phase1_sample/val_label.txt
Dobbiamo solo contare il numero di righe, che indica il numero di campioni.
from IPython.display import Video
Video("/kaggle/input/ffdv-sample-dataset/ffdv_phase1_sample/valset/00882a2832edbcab1d3dfc4cc62cfbb9.mp4", embed=True)
Video crea un oggetto video e incorpora significa che, se impostato su True, il lettore video verrà visualizzato direttamente nell'output della cella del notebook.
Dopo aver eseguito sulla linea di base di Kaggle, dovresti vedere risultati come questi:
!pip install moviepy librosa matplotlib numpy timm
Collegamenti alla documentazione per le biblioteche utilizzate:
filmico
librosa(librosa è una libreria di terze parti molto potente per l'elaborazione del segnale vocale Python. In questa linea di base utilizziamo principalmente la generazione di spettrogrammi MEL e la conversione di spettrogrammi)
Matplotlib
numpy
tempo(Libreria di modelli di classificazione delle immagini, crea rapidamente vari modelli Sota)
Cos'è la SOTA? Il nome completo di SOTA è State of the arts, che si riferisce al miglior modello in questo campo. SOTA ottiene punteggi molto alti su alcuni set di dati di riferimento.
Modello non end-to-end (pipeline): prima di tutto dobbiamo capire cos'è un'estremità. Le due estremità si riferiscono all'estremità di input all'estremità di output. Il tradizionale processo di machine learning è costituito da più moduli, indipendenti l'uno dall'altro. Il risultato di quest'ultimo modulo dipende dal livello del risultato precedente, influenzando l'intero risultato della formazione.
Modello end-to-end (end to end): prima di tutto, devi capire che la previsione viene generata dall'estremità dell'input all'estremità dell'output. Questo risultato della previsione avrà un errore rispetto al risultato reale (deve essere ricordato che il compito principale dell’apprendimento automatico è ancoraprevedere ), questo errore viene propagato a ogni livello della rete neurale e i pesi e i parametri del modello vengono regolati fino alla convergenza del modello o fino all'ottenimento dei risultati attesi. Se lo consideriamo in termini di sistema di controllo, si tratta di un sistema di controllo a circuito chiuso. (ad esempio rete neurale BP)
Sequenza-sequenza (seq2seq): questo è un generaleda un capo all'altroMetodo di previsione della sequenza, la sua struttura è un codificatore e un decodificatore Se si utilizza il set di dati di domande e risposte per codificare/decodificare, è possibile ottenere un robot di domande e risposte. Questa è un'applicazione sequenza-sequenza.
La domanda risale alla Baseline stessa: cos'è la Baseline?La linea di base si riferisce solitamente a un modello di base semplice e facile da implementare.
Nel processo di messa a punto dell’algoritmo e aggiustamento dei parametri, il compito di Baseline è confrontarsi con se stesso per rendere il modello sempre migliore.
Anche il benchmark è un concetto importante, il suo significato lo èPunti di riferimenti . Di solito si riferisce a un metodo standardizzato di valutazione e confronto delle prestazioni di algoritmi, modelli o metodi, utilizzato per misurare le differenze tra modelli.
Puoi vederli frequentemente sui siti di benchmarking dei modelli.Per esempioSi Nan。
Quando ho eseguito la linea di base, si è verificato un errore di configurazione CUDA. Utilizza un altro acceleratore:
import torch
# 设置pytorch的种子
torch.manual_seed(0)
# deterministic当设置为False时,cuDNN将允许一些操作的非确定性优化
torch.backends.cudnn.deterministic = False
# benchmark设置为true允许cuDNN在每个前向传播中自动寻找最适合当前配置的卷积算法,以提高性能。
torch.backends.cudnn.benchmark = True
# 导入必要的库,我们需要用到cv2,glob,os,PIL
import torchvision.models as models
import torchvision.transforms as transforms
import torchvision.datasets as datasets
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torch.autograd import Variable
from torch.utils.data.dataset import Dataset
import timm
import time
import pandas as pd
import numpy as np
import cv2, glob, os
from PIL import Image
Generate_mel_spectrogram accetta parametri come il percorso del file video, il numero di filtri di frequenza Mel, la frequenza più alta (che controlla l'intervallo dello spettro calcolato) e la dimensione dell'immagine target.
import moviepy.editor as mp
import librosa
import numpy as np
import cv2
def generate_mel_spectrogram(video_path, n_mels=128, fmax=8000, target_size=(256, 256)):
# 提取音频
audio_path = 'extracted_audio.wav'
# video_path 应该是之前定义的变量,包含了要处理的视频文件的路径。创建了一个 VideoFileClip 对象,存储在 video 变量中。
video = mp.VideoFileClip(video_path)
# video.audio 访问视频的音频轨道。write_audiofile() 方法将音频写入文件。verbose=False: 设置为False表示不在控制台输出处理进度。logger=None: 设置为None表示不使用日志记录器。实际上我们做这个预测没有这样的需求,也就不消耗占存。
# 其默认参数:write_audiofile(self, filename, fps=None, nbytes=2, buffersize=2000, codec=None, bitrate=None, ffmpeg_params=None, write_logfile=False, verbose=True, logger='bar')
video.audio.write_audiofile(audio_path, verbose=False, logger=None)
# 加载音频文件,加载采样率
y, sr = librosa.load(audio_path)
# 生成MEL频谱图(梅尔频谱图,与之相对应的有mel倒频谱图)
# 默认参数:librosa.feature.melspectrogram(y=None, sr=22050, S=None, n_fft=2048, hop_length=512, power=2.0, **kwargs)
# 参数解释:y:音频时间序列,sr:采样率,n_mels 是指在计算梅尔频谱图时,将频谱图划分为多少个梅尔频率滤波器(Mel filters),其决定了最终生成的梅尔频谱图的分辨率,也可以理解为梅尔频谱图的高度。
S = librosa.feature.melspectrogram(y=y, sr=sr, n_mels=n_mels)
# 将频谱图转换为dB单位,S:输入功率,ref:作为参考,如果是标量,则振幅 abs(S) 相对于 ref: 10 * log10(S / ref) 进行缩放。此处np.max指的是将谱图中的最大值作为参考值,这也是一种常用的参考值取法
S_dB = librosa.power_to_db(S, ref=np.max)
# 归一化到0-255之间,NORM_MINMAX:数组的数值被平移或缩放到一个指定的范围,线性归一化。
S_dB_normalized = cv2.normalize(S_dB, None, 0, 255, cv2.NORM_MINMAX)
# 将浮点数转换为无符号8位整型
S_dB_normalized = S_dB_normalized.astype(np.uint8)
# 缩放到目标大小256,256
img_resized = cv2.resize(S_dB_normalized, target_size, interpolation=cv2.INTER_LINEAR)
return img_resized
# 使用示例
video_path = '/kaggle/input/ffdv-sample-dataset/ffdv_phase1_sample/trainset/001b0680999447348bc9f89efce0f183.mp4' # 替换为您的视频文件路径
mel_spectrogram_image = generate_mel_spectrogram(video_path)
!mkdir ffdv_phase1_sample
!mkdir ffdv_phase1_sample/trainset
!mkdir ffdv_phase1_sample/valset
La quantità di dati è troppo grande, quindi non pubblicherò un'immagine qui, pubblicherò invece un diagramma Mel in circostanze normali:
Fonte immagine:Università Simon Fraser
Se lo accendi e lo ascolti, è un pezzo di audio che diminuisce gradualmente.
# 使用glob.glob函数查找/kaggle/input/ffdv-sample-dataset/ffdv_phase1_sample/trainset/目录下前400个.mp4视频文件的路径。
for video_path in glob.glob('/kaggle/input/ffdv-sample-dataset/ffdv_phase1_sample/trainset/*.mp4')[:400]:
mel_spectrogram_image = generate_mel_spectrogram(video_path)
cv2.imwrite('./ffdv_phase1_sample/trainset/' + video_path.split('/')[-1][:-4] + '.jpg', mel_spectrogram_image)
# a. 调用generate_mel_spectrogram(video_path)函数生成梅尔频谱图,并将其存储在mel_spectrogram_image变量中。b. 使用cv2.imwrite函数将梅尔频谱图保存为JPEG图像。图像被保存在./ffdv_phase1_sample/trainset/目录下,并使用与原始视频文件相同的名称(但扩展名改为.jpg)。
for video_path in glob.glob('/kaggle/input/ffdv-sample-dataset/ffdv_phase1_sample/valset/*.mp4'):
mel_spectrogram_image = generate_mel_spectrogram(video_path)
cv2.imwrite('./ffdv_phase1_sample/valset/' + video_path.split('/')[-1][:-4] + '.jpg', mel_spectrogram_image)
La classe AverageMeter viene utilizzata per calcolare e archiviare il valore medio e corrente di una variabile.
class AverageMeter(object):
"""Computes and stores the average and current value"""
def __init__(self, name, fmt=':f'):
self.name = name
self.fmt = fmt
self.reset()
def reset(self):
self.val = 0
self.avg = 0
self.sum = 0
self.count = 0
def update(self, val, n=1):
self.val = val
self.sum += val * n
self.count += n
self.avg = self.sum / self.count
def __str__(self):
fmtstr = '{name} {val' + self.fmt + '} ({avg' + self.fmt + '})'
return fmtstr.format(**self.__dict__)
La classe ProgressMeter viene utilizzata per generare informazioni sul batch corrente e indicatori statistici durante il processo di training.
class ProgressMeter(object):
def __init__(self, num_batches, *meters):
self.batch_fmtstr = self._get_batch_fmtstr(num_batches)
self.meters = meters
self.prefix = ""
def pr2int(self, batch):
entries = [self.prefix + self.batch_fmtstr.format(batch)]
entries += [str(meter) for meter in self.meters]
print('t'.join(entries))
def _get_batch_fmtstr(self, num_batches):
num_digits = len(str(num_batches // 1))
fmt = '{:' + str(num_digits) + 'd}'
return '[' + fmt + '/' + fmt.format(num_batches) + ']'
La funzione di convalida valuta regolarmente le prestazioni del modello in base alla convalida impostata durante il processo di addestramento e calcola e stampa la precisione Top-1.
def validate(val_loader, model, criterion):
batch_time = AverageMeter('Time', ':6.3f')# 批处理时间
losses = AverageMeter('Loss', ':.4e')# 损失
top1 = AverageMeter('Acc@1', ':6.2f')# Top-1准确率
progress = ProgressMeter(len(val_loader), batch_time, losses, top1)# 输出ProgressMeter
# switch to evaluate mode,eval()为评估函数,关闭训练时使用的一些特定层(如 Dropout),并启用 Batch Normalization 层的运行统计。
model.eval()
with torch.no_grad():# 定时设置requires_grad为False,防止梯度计算并节省内存。
end = time.time()
for i, (input, target) in enumerate(val_loader):
input = input.cuda()# 将输入数据和目标数据转移到GPU计算
target = target.cuda()
# compute output
output = model(input)
loss = criterion(output, target)# 计算训练损失
# measure accuracy and record loss,acc百分比显示
acc = (output.argmax(1).view(-1) == target.float().view(-1)).float().mean() * 100
losses.update(loss.item(), input.size(0))
top1.update(acc, input.size(0))
# measure elapsed time
batch_time.update(time.time() - end)
end = time.time()
# TODO: this should also be done with the ProgressMeter
print(' * Acc@1 {top1.avg:.3f}'
.format(top1=top1))
return top1
La funzione di previsione viene utilizzata per fare inferenze sul set di test e supporta l'uso del test time augmentation (TTA) per migliorare la stabilità delle previsioni del modello effettuando più previsioni e calcolando la media.
def predict(test_loader, model, tta=10):
# switch to evaluate mode
model.eval()
# TTA(Test Time Augmentation)
test_pred_tta = None
for _ in range(tta):# 执行 TTA 次数的循环,每次循环会生成一个略有不同的输入数据。
test_pred = []
with torch.no_grad():
end = time.time()
for i, (input, target) in enumerate(test_loader):
input = input.cuda()
target = target.cuda()
# compute output
output = model(input)
output = F.softmax(output, dim=1)# 对模型输出进行 softmax 归一化处理,以获得类别概率。
output = output.data.cpu().numpy()
test_pred.append(output)
test_pred = np.vstack(test_pred)
if test_pred_tta is None:
test_pred_tta = test_pred
else:
test_pred_tta += test_pred
return test_pred_tta
La funzione train è responsabile dell'addestramento del modello, dell'aggiornamento dei parametri del modello calcolando la funzione di perdita e dell'accuratezza e dell'esecuzione delle fasi di backpropagation e ottimizzazione.
def train(train_loader, model, criterion, optimizer, epoch):
batch_time = AverageMeter('Time', ':6.3f')
losses = AverageMeter('Loss', ':.4e')
top1 = AverageMeter('Acc@1', ':6.2f')
progress = ProgressMeter(len(train_loader), batch_time, losses, top1)
# switch to train mode
model.train()
end = time.time()
for i, (input, target) in enumerate(train_loader):
input = input.cuda(non_blocking=True)
target = target.cuda(non_blocking=True)
# compute output
output = model(input)
loss = criterion(output, target)
# measure accuracy and record loss
losses.update(loss.item(), input.size(0))
acc = (output.argmax(1).view(-1) == target.float().view(-1)).float().mean() * 100
top1.update(acc, input.size(0))# 更新 top1 计量器,记录当前批次的准确率。
# compute gradient and do SGD step
optimizer.zero_grad() # 清除之前累积的梯度。
loss.backward()# 计算损失相对于模型参数的梯度
optimizer.step()# 根据 backward() 计算的梯度更新模型参数。
# measure elapsed time
batch_time.update(time.time() - end)# 更新 batch_time 计量器,记录当前批次的处理时间。
end = time.time()
if i % 100 == 0:
progress.pr2int(i)
train_label = pd.read_csv("/kaggle/input/ffdv-sample-dataset/ffdv_phase1_sample/train_label.txt")
val_label = pd.read_csv("/kaggle/input/ffdv-sample-dataset/ffdv_phase1_sample/val_label.txt")
train_label['path'] = '/kaggle/working/ffdv_phase1_sample/trainset/' + train_label['video_name'].apply(lambda x: x[:-4] + '.jpg')
val_label['path'] = '/kaggle/working/ffdv_phase1_sample/valset/' + val_label['video_name'].apply(lambda x: x[:-4] + '.jpg')
train_label = train_label[train_label['path'].apply(os.path.exists)]
val_label = val_label[val_label['path'].apply(os.path.exists)]
La trasformazione lascia un parametro per il successivo miglioramento dei dati e il valore predefinito è Nessuno.
L'immagine viene convertita in modalità RGB.
Le etichette vengono restituite come torch.Tensor.
class FFDIDataset(Dataset):
def __init__(self, img_path, img_label, transform=None):
self.img_path = img_path
self.img_label = img_label
if transform is not None:
self.transform = transform
else:
self.transform = None
def __getitem__(self, index):
img = Image.open(self.img_path[index]).convert('RGB')
if self.transform is not None:
img = self.transform(img)
return img, torch.from_numpy(np.array(self.img_label[index]))
def __len__(self):
return len(self.img_path)
Fa riferimento alla classe FFDID impostata sopra.
train_loader = torch.utils.data.DataLoader(
FFDIDataset(train_label['path'].values, train_label['target'].values,
transforms.Compose([
transforms.Resize((256, 256)),
transforms.RandomHorizontalFlip(),
transforms.RandomVerticalFlip(),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])
), batch_size=40, shuffle=True, num_workers=12, pin_memory=True
)
val_loader = torch.utils.data.DataLoader(
FFDIDataset(val_label['path'].values, val_label['target'].values,
transforms.Compose([
transforms.Resize((256, 256)),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])
), batch_size=40, shuffle=False, num_workers=10, pin_memory=True
)
# 重点:这里调用timm提供的resnet18模型,因为分类为0/1(真视频/假视频),可以在后续改进,比如换用更深的网络ResNet-34、ResNet-50或是其他变体
model = timm.create_model('resnet18', pretrained=True, num_classes=2)
model = model.cuda()
# 交叉熵损失,针对多类别
criterion = nn.CrossEntropyLoss().cuda()
# Adam优化器,学习率设置为0.003。
optimizer = torch.optim.Adam(model.parameters(), 0.003)
# 每4个epoch将学习率按0.85的因子进行调整。
scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=4, gamma=0.85)
# 初始化最优acc
best_acc = 0.0
for epoch in range(10):
scheduler.step()
print('Epoch: ', epoch)
# 调用train函数
train(train_loader, model, criterion, optimizer, epoch)
# 调用validate函数
val_acc = validate(val_loader, model, criterion)
if val_acc.avg.item() > best_acc:
best_acc = round(val_acc.avg.item(), 2)
torch.save(model.state_dict(), f'./model_{best_acc}.pt')
Produzione:
Epoch: 0
[ 0/10] Time 6.482 ( 6.482) Loss 7.1626e-01 (7.1626e-01) Acc@1 35.00 ( 35.00)
* Acc@1 64.000
Epoch: 1
[ 0/10] Time 0.819 ( 0.819) Loss 4.6079e-01 (4.6079e-01) Acc@1 80.00 ( 80.00)
* Acc@1 75.500
Epoch: 2
[ 0/10] Time 0.914 ( 0.914) Loss 1.4983e-01 (1.4983e-01) Acc@1 97.50 ( 97.50)
* Acc@1 88.500
Epoch: 3
[ 0/10] Time 0.884 ( 0.884) Loss 2.4681e-01 (2.4681e-01) Acc@1 87.50 ( 87.50)
* Acc@1 84.000
Epoch: 4
[ 0/10] Time 0.854 ( 0.854) Loss 5.3736e-02 (5.3736e-02) Acc@1 100.00 (100.00)
* Acc@1 90.500
Epoch: 5
[ 0/10] Time 0.849 ( 0.849) Loss 5.9881e-02 (5.9881e-02) Acc@1 97.50 ( 97.50)
* Acc@1 89.500
Epoch: 6
[ 0/10] Time 0.715 ( 0.715) Loss 1.6215e-01 (1.6215e-01) Acc@1 92.50 ( 92.50)
* Acc@1 65.000
Epoch: 7
[ 0/10] Time 0.652 ( 0.652) Loss 5.3892e-01 (5.3892e-01) Acc@1 80.00 ( 80.00)
* Acc@1 78.500
Epoch: 8
[ 0/10] Time 0.847 ( 0.847) Loss 6.6098e-02 (6.6098e-02) Acc@1 97.50 ( 97.50)
* Acc@1 81.000
Epoch: 9
[ 0/10] Time 0.844 ( 0.844) Loss 9.4254e-02 (9.4254e-02) Acc@1 97.50 ( 97.50)
* Acc@1 81.500
Reti più profonde: se hai bisogno di prestazioni più elevate e capacità di estrazione di funzionalità più complesse, puoi prendere in considerazione l'utilizzo di reti più profonde come ResNet-34, ResNet-50 o varianti ResNet ancora più grandi (come ResNet-101 o ResNet-152).
Altri modelli pre-addestrati: oltre alla serie ResNet, ci sono molti altri modelli pre-addestrati tra cui scegliere, come:
EfficientNet: ha prestazioni eccellenti ed efficienza dei parametri.
DenseNet: la struttura di rete densamente connessa aiuta a utilizzare meglio le funzionalità.
Serie VGG: architettura semplice e classica, adatta per l'uso con risorse limitate.
Modello personalizzato: a seconda delle caratteristiche specifiche del set di dati e dei requisiti dell'attività, potresti anche prendere in considerazione la progettazione e il training di un'architettura del modello personalizzata, che potrebbe richiedere più debug e sperimentazione.
Apprendimento d'insieme: prendi in considerazione l'utilizzo di metodi di apprendimento d'insieme come Bagging o Boosting per combinare le previsioni di più modelli per migliorare ulteriormente le prestazioni e la stabilità.
Ottimizzazione degli iperparametri: oltre alla selezione del modello, le prestazioni del modello possono anche essere ottimizzate regolando la velocità di apprendimento, la dimensione del batch, la selezione dell'ottimizzatore e le strategie di aumento dei dati.
Considerare l'applicazione di Dice Loss per migliorare la funzione di perdita in futuro. Dice Loss misura la somiglianza tra il risultato della previsione e la maschera di destinazione ed è migliore per attività di classificazione binaria con confini evidenti. È una funzione di perdita che offre prestazioni migliori nella previsione a livello di pixel.
Tieni d'occhio anche la perdita focale. Progettato specificatamente per risolvere il problema dello squilibrio delle classi, può migliorare ulteriormente le prestazioni del modello sulle categorie minoritarie riducendo il peso dei campioni facili da classificare per concentrarsi su campioni difficili.
RAdam è un miglioramento di Adam che migliora la stabilità e le prestazioni regolando dinamicamente la correzione del tasso di apprendimento.
AdamW è una variante di Adam che introduce il decadimento del peso per risolvere i problemi di prestazioni che Adam può introdurre in alcuni casi, soprattutto quando il numero di parametri del modello è elevato.
AdamW è una variante di Adam che introduce il decadimento del peso per risolvere i problemi di prestazioni che Adam può introdurre in alcuni casi, soprattutto quando il numero di parametri del modello è elevato.
# 用模型 (model) 对验证数据集 (val_loader) 进行预测。这部分假设 [:, 1] 给出了类别1的概率。
val_pred = predict(val_loader, model, 1)[:, 1]
# 赋值,预测的概率(或者预测值)赋给了 val_label 数据框中名为 "y_pred" 的列
val_label["y_pred"] = val_pred
submit = pd.read_csv("/kaggle/input/multi-ffdv/prediction.txt.csv")
# 使用 merge 函数将提交文件 (submit) 中的数据与验证数据集标签 (val_label) 中的 video_name 和 y_pred 列合并
merged_df = submit.merge(val_label[['video_name', 'y_pred']], on='video_name', suffixes=('', '_df2'), how='left', )
# 将合并后的数据中 y_pred_df2 列(从验证集中获取的预测结果)的值填充到 y_pred 列中
merged_df['y_pred'] = merged_df['y_pred_df2'].combine_first(merged_df['y_pred'])
merged_df[['video_name', 'y_pred']].to_csv('submit.csv', index=None)
Non sono necessari 10 minuti per completare l'esecuzione della linea di base. Di solito verrà bloccato a 4,7 per generare lo spettrogramma Mel. Ma ci vogliono 5 ore di paziente esplorazione. Ecco un riepilogo silenzioso dei processi chiave:
La definizione del compito del deep learning può in realtà essere riassunta come "propagazione all'indietro", perché il suo nucleo è utilizzare l'algoritmo di propagazione all'indietro per regolare i parametri del modello per ridurre al minimo la funzione di perdita definita.
È molto adatto utilizzare il deep learning per gestire tali attività audio e video. Penso che il primo sia l'enorme quantità di dati audio e video e la necessità di una classificazione complessa di questi dati.Il meccanismo del deep learning fa sì che richieda un’enorme quantità di dati e, in effetti, un punto molto importante è che il deepfake stesso richiedeClassificazioneIl pensiero è essenzialmente un compito di classificazione e l’apprendimento profondo presenta grandi vantaggi in grandi volumi di dati e classificazione raffinata. Un esempio familiare è la rete di generazione avversaria GAN.
In secondo luogo, i dati statisticamente simili vengono creati in grandi quantità e possono apprendere la distribuzione di enormi quantità di dati. Può anche svolgere il compito inverso.
L’AIGC dovrebbe includere Deepfake. Dal punto di vista dello sviluppo, lo sviluppo e la dimensionalità della tecnologia Deepfake aumenteranno sicuramente con la potenza di elaborazione dell'AIGC. Ci troveremo di fronte a un vasto mare di dati reali e falsi. Naturalmente dobbiamo anche vedere cosa sono questi video usato per Se può salvare L'energia dei creatori di storie è senza dubbio benefica per lo sviluppo dell'intrattenimento letterario e artistico se viene utilizzata per l'inganno, dovrà presto affrontare sfide etiche e morali;
Uno dei miei pensieri è che, se combinato con l’attuale mania dei brevi drammi, Deepfake può consentire al pubblico di ottenere un’esperienza di intrattenimento audiovisivo a bassissimo costo, ma sfida anche l’industria cinematografica e televisiva tradizionale e persino il tipo di attori e la stimolazione audiovisiva di cui gli occhi umani hanno bisogno. Questo è un argomento discutibile.