Berbagi teknologi

[Praktik Pembelajaran Mesin] Datawhale Summer Camp 2: Serangan dan pertahanan audio dan video (deepfake) Penjelasan kalimat dasar

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

#Datawhale #AIsummercamp#summercamp

1. Pengenalan singkat soal-soal kompetisi

Tugas kompetisi ini adalah menentukan apakah suatu gambar wajah merupakan gambar Deepfake dan menghasilkan skor probabilitas bahwa itu adalah gambar Deepfake. Peserta perlu mengembangkan dan mengoptimalkan model deteksi untuk mengatasi beragam teknologi pembuatan deepfake dan skenario aplikasi yang kompleks, sehingga meningkatkan akurasi dan ketahanan deteksi gambar deepfake.

2. Kumpulan data pertanyaan kompetisi

File label train_label.txt dari set pelatihan digunakan untuk melatih model, sedangkan file label val_label.txt dari set validasi hanya digunakan untuk penyetelan model. Misalnya, di train_label.txt atau val_label.txt, setiap baris berisi dua bagian, dipisahkan dengan koma. Bagian pertama adalah nama file (akhiran .mp4), bagian kedua adalah nilai sebenarnya.
Nilai target 1 menunjukkan audio dan video palsu, dan nilai target 0 menunjukkan audio dan video wajah asli.

Di bawah ini adalah contoh train_label.txt dan val_label.txt:

train_label.txt

video_name,target
96b04c80704f02cb426076b3f624b69e.mp4,0
16fe4cf5ae8b3928c968a5d11e870360.mp4,1
  • 1
  • 2
  • 3
  • 4
  • 5

val_label.txt

video_name,target
f859cb3510c69513d5c57c6934bc9968.mp4,0
50ae26b3f3ea85babb2f9dde840830e2.mp4,1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

Setiap baris dalam file berisi dua bagian, dipisahkan dengan koma. Bagian pertama adalah nama file video, dan bagian kedua adalah skor deepfake yang sesuai dengan prediksi model (yaitu, nilai probabilitas sampel yang termasuk dalam video deepfake). Silakan merujuk ke templat pengiriman di bawah ini:

prediction.csv

video_name,score
658042526e6d0c199adc7bfeb1f7c888.mp4,0.123456
a20cf2d7dea580d0affc4d85c9932479.mp4,0.123456
  • 1
  • 2
  • 3
  • 4
  • 5

Fase kedua mengikuti fase pertama, di mana set pengujian publik dirilis. Peserta perlu mengirimkan file skor prediksi prediksi_test.csv dari set tes ke sistem, dan memberikan umpan balik terhadap hasil skor tes secara online secara real-time.

Setelah tahap kedua, 30 tim teratas akan melaju ke tahap ketiga. Pada tahap ini, kontestan perlu menyerahkan kode docker dan laporan teknis. Persyaratan Docker mencakup kode pelatihan asli dan API pengujian (input fungsi adalah jalur gambar dan outputnya adalah skor deepfake yang diprediksi oleh model). Sponsor akan memeriksa dan menjalankan kembali kode algoritma untuk mereproduksi proses pelatihan dan hasil tes.

Hanya satu model yang diperbolehkan untuk dikirimkan, dan parameter jaringan yang valid tidak boleh melebihi 200 juta (gunakanthopParameter model statistik alat).

Hanya pelatihan pra-model dengan ImageNet1K yang diperbolehkan. Sampel tambahan yang dihasilkan berdasarkan set pelatihan yang dipublikasikan (melalui alat augmentasi data/deepfake) dapat digunakan untuk pelatihan, namun alat ini harus diserahkan untuk direproduksi pada tahap ketiga.

3. Indikator evaluasi

Indeks evaluasi terutama menggunakan AUC di bawah kurva ROC sebagai indeks. Kisaran nilai AUC biasanya berada dalam kisaran tersebut0.5-1antara, sebaliknya kami berpikirIni bukan model pembelajaran mesin yang bagus . Semakin dekat AUC ke 1, maka semakin baik model tersebut. Jika AUC memberikan hasil pemeringkatan yang ambigu, kami kemudian menggunakan **TPR (true positive rate)** sebagai referensi tambahan. Tentu saja metode yang sesuai adalah FPR.

F1-SkorIni juga merupakan indikator yang dapat kita rujuk: tingkat presisi dan tingkat perolehan kembalirata-rata harmonik

F 1 _ Skor = 2 ∗ ( TP ) / ( 2 TP + FN + FP ) F1_ Skor = 2 * (TP) / (2TP + FN + FP)F1_Sinti=2(T.P.)/(2T.P.+Bahasa Inggris Bahasa Inggris FN+Bahasa Inggris)

Sebelum mempelajari pembelajaran mesin, kita harus meninjau dua konsep penting:KetepatanDanMengingat

Ketepatan Presisi = TPTP + FP Presisi = frac{TP}{TP+FP}PmerekamSayaSSayaHaiN=T.P.+Bahasa InggrisT.P., yang digunakan untuk mengukur modelPeriksa kinerja, proporsi sampel yang diprediksi positif di antara sampel yang diprediksi dengan benar.

Mengingat Penarikan kembali = TPTP + FN Penarikan kembali = frac{TP}{TP+FN}RekAII=T.P.+Bahasa Inggris Bahasa Inggris FNT.P., yang digunakan untuk mengukur modelKinerja pencarian, proporsi sampel yang benar-benar positif di antara sampel yang diprediksi positif.

Tingkat Positif Sejati (TPR):
TPR = TP / (TP + FN)
Tingkat positif palsu (FPR):
FPR = FP / (FP + TN)
di dalam:
TP: Sampel serangan diidentifikasi dengan benar sebagai serangan;
TN: Sampel nyata diidentifikasi dengan benar sebagai nyata;
FP: Sampel nyata salah diidentifikasi sebagai serangan;
FN: Sampel serangan salah diidentifikasi sebagai nyata.

Referensi: Aghajan, H., Augusto, JC, & Delgado, RLC (Eds.). (Jika link yang diberikan pada judul tidak dapat dibuka, silakan klik:seluruh buku)

Berikut skrip perhitungan TPR saya:

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
    

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78

Jika klasifikasi diperlukan, Anda mungkin memerlukan ambang batas. Hubungannya dengan nilai prediksi adalah sebagai berikut:

Prediksi = Probabilitas > Ambang Batas Prediksi = Probabilitas > Ambang BatasPulangDSayaCTSayaHaiN=Porang kulit hitambabiakuSayaTkamu>THresHHaiakuD

Setelah mempelajari AUC, metrik penting lainnya yang harus Anda pelajari adalah kehilangan log. Untuk masalah klasifikasi biner, kami mendefinisikan kehilangan log sebagai:

Log Kerugian = - target ∗ log ( p ) − ( 1 − target ) ∗ log ( 1 − p ) LogKerugian = - target * log (p) - (1-target) * log (1-p)SayaHaibahasa inggristulang rusuk=TARGBahasa Inggris:TakuHaiG(P)(1TARGBahasa Inggris:T)akuHaiG(1P)

Diantaranya, nilai targetnya adalah 0 atau 1, dan nilai prediksinya adalah probabilitas sampel tersebut termasuk dalam kategori 1. Kehilangan log memberikan hukuman pada prediksi yang sangat pasti dan sangat salah. Semakin kecil log loss, semakin dekat probabilitas prediksi model terhadap nilai target.

Kita juga dapat menggunakan indikator berikut dalam masalah klasifikasi:

  • Presisi rata-rata makro: Hitung keakuratan semua kategori secara terpisah lalu rata-rata
  • Presisi rata-rata mikro: Hitung keakuratan semua kategori lalu hitung rata-rata tertimbangnya.
  • Presisi tertimbang : Hitung keakuratan semua kategori lalu hitung rata-rata tertimbangnya. Rata-rata tertimbang merupakan hasil perkalian bobot tiap kategori.

4. Dasar keseluruhan

4.1 Hitung jumlah sampel

# “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
  • 1
  • 2
  • 3

Kita hanya perlu menghitung jumlah baris, yang menunjukkan jumlah sampel.

4.2 Membuat objek video

from IPython.display import Video
Video("/kaggle/input/ffdv-sample-dataset/ffdv_phase1_sample/valset/00882a2832edbcab1d3dfc4cc62cfbb9.mp4", embed=True)
  • 1
  • 2

Video membuat objek video, dan penyematan berarti bila disetel ke True, pemutar video akan langsung ditampilkan di output sel buku catatan.
Setelah menjalankan baseline kaggle, Anda akan melihat hasil seperti ini:
Masukkan deskripsi gambar di sini

4.3 Unduh perpustakaan&&pengetahuan tambahan yang diperlukan

!pip install moviepy librosa matplotlib numpy timm
  • 1

Tautan dokumentasi untuk perpustakaan yang digunakan:
filmpy
buku(librosa adalah perpustakaan pihak ketiga yang sangat kuat untuk pemrosesan sinyal ucapan python. Dalam dasar ini kami terutama menggunakan pembuatan spektogram MEL dan konversi spektogram)
matplotlib
orang bodoh
waktu(Perpustakaan model klasifikasi gambar, dengan cepat membuat berbagai model sota)

Apa itu SOTA? Nama lengkap SOTA adalah State of the art, yang mengacu pada model terbaik di bidang ini. SOTA mendapat skor sangat tinggi pada beberapa kumpulan data benchmark.

Model non-end-to-end (pipa): Pertama-tama, kita harus memahami apa itu akhir. Kedua ujung mengacu pada ujung masukan dan ujung keluaran. Proses pembelajaran mesin tradisional terdiri dari beberapa modul, yang independen satu sama lain. Hasil dari modul terakhir bergantung pada tingkat hasil sebelumnya, sehingga memengaruhi keseluruhan hasil pelatihan.
Model ujung ke ujung (end to end): Pertama-tama, Anda harus memahami bahwa prediksi dihasilkan dari ujung masukan hingga ujung keluaran. Hasil prediksi ini akan memiliki kesalahan dibandingkan dengan hasil sebenarnya (harus diingat bahwa tugas inti pembelajaran mesin masih tetap adameramalkan ), kesalahan ini disebarkan kembali ke setiap lapisan di jaringan saraf, dan bobot serta parameter model disesuaikan hingga model konvergen, atau diperoleh hasil yang kita harapkan. Jika kita melihatnya dari segi sistem kendali, ini adalah sistem kendali loop tertutup. (misalnya jaringan saraf BP)
Urutan-ke-urutan (seq2seq): Ini bersifat umumujung ke ujungMetode prediksi urutan, strukturnya adalah encoder dan decoder. Jika Anda menggunakan kumpulan data tanya jawab untuk menyandikan/mendekode, Anda bisa mendapatkan robot tanya jawab.

Pertanyaannya kembali ke Baseline itu sendiri, apa itu Baseline?Baseline biasanya mengacu pada model baseline yang sederhana dan mudah diimplementasikan.
Dalam proses penyetelan algoritma dan penyesuaian parameter, tugas Baseline adalah membandingkan dirinya dengan dirinya sendiri untuk membuat model menjadi lebih baik dan lebih baik lagi.

Tolok ukur juga merupakan konsep penting, begitulah maknanyaTolak ukur . Biasanya mengacu pada metode evaluasi dan perbandingan standar kinerja algoritma, model atau metode, yang digunakan untuk mengukur perbedaan antar model.

Anda dapat sering melihatnya di situs pembandingan model.MisalnyaSinan

4.4 Tetapkan konfigurasi seed &&CUDNN acak pytorch

Saat saya menjalankan baseline, terjadi kesalahan konfigurasi CUDA. Harap gunakan Akselerator lain:

Masukkan deskripsi gambar di sini

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

4.5 Pemrosesan awal audio dan video

Parameter yang diterima oleh generate_mel_spectrogram meliputi jalur file video, jumlah filter untuk membagi frekuensi Mel, frekuensi tertinggi (mengontrol rentang spektrum yang dihitung), dan ukuran gambar 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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

4.6 Membuat folder data pelatihan

!mkdir ffdv_phase1_sample
!mkdir ffdv_phase1_sample/trainset
!mkdir ffdv_phase1_sample/valset
  • 1
  • 2
  • 3

4.7 Menghasilkan Spektogram Mel

Jumlah datanya terlalu besar, jadi saya tidak akan memposting gambarnya di sini. Sebaliknya, saya akan memposting diagram Mel dalam keadaan normal:
Masukkan deskripsi gambar di sini
Sumber gambar:Universitas Simon Fraser
Jika Anda menyalakannya dan mendengarkannya, itu adalah bagian audio yang berkurang secara bertahap.

# 使用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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

4.8 Mendefinisikan AverageMeter dan ProgressMeter

Kelas AverageMeter digunakan untuk menghitung dan menyimpan nilai rata-rata dan nilai saat ini dari suatu variabel.

  • nama: Nama variabel.
  • fmt: format string, digunakan untuk keluaran yang diformat.
  • reset(): Mereset semua statistik (val, rata-rata, jumlah, hitungan).
  • update(val, n=1): Perbarui statistik, val adalah nilai saat ini, dan n adalah bobot nilai (biasanya jumlah sampel).
  • kuat(): Mengembalikan string yang diformat, termasuk nilai saat ini dan nilai rata-rata.
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__)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

Kelas ProgressMeter digunakan untuk mengeluarkan informasi batch terkini dan indikator statistik selama proses pelatihan.

  • num_batches: jumlah total batch.
  • meter: Daftar berisi objek AverageMeter yang digunakan untuk menyimpan metrik yang berbeda.
  • awalan: Awalan dari jalur keluaran.
  • print(batch): Mencetak informasi batch saat ini, termasuk nomor batch saat ini dan nilai masing-masing indikator saat ini.
  • _get_batch_fmtstr(num_batches): Menghasilkan string format batch untuk memastikan penyelarasan dan pemformatan keluaran.
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) + ']'
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

4.9 Pembelajaran mendalam dan proses evaluasi model (poin-poin penting)

Fungsi validasi secara rutin mengevaluasi performa model pada set validasi selama proses pelatihan, dan menghitung serta mencetak akurasi 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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

Fungsi prediksi digunakan untuk membuat kesimpulan pada set pengujian dan mendukung penggunaan augmentasi waktu pengujian (TTA) untuk meningkatkan stabilitas prediksi model dengan membuat beberapa prediksi dan rata-rata.

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

Fungsi train bertanggung jawab untuk melatih model, memperbarui parameter model dengan menghitung fungsi kerugian dan akurasi, serta melakukan langkah backpropagation dan optimasi.

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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

4.10 Memuat label untuk kumpulan data pelatihan dan validasi

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)]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

4.11 Memuat gambar dan konversi gambar

transform meninggalkan parameter untuk peningkatan data selanjutnya, dan defaultnya adalah Tidak Ada.
Gambar diubah ke mode RGB.
Label dikembalikan sebagai 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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

4.12 Menyiapkan proses pelatihan (poin-poin penting)

Referensi set kelas FFDID di atas.

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')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

Keluaran:

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

4.12.1 Ide untuk meningkatkan model resnet18

Jaringan yang lebih dalam: Jika Anda memerlukan performa yang lebih tinggi dan kemampuan ekstraksi fitur yang lebih kompleks, Anda dapat mempertimbangkan untuk menggunakan jaringan yang lebih dalam seperti ResNet-34, ResNet-50, atau varian ResNet yang lebih besar (seperti ResNet-101 atau ResNet-152).

Model terlatih lainnya: Selain seri ResNet, masih banyak model terlatih lainnya yang dapat dipilih, seperti:

EfficientNet: memiliki kinerja dan efisiensi parameter yang sangat baik.
DenseNet: Struktur jaringan yang terhubung secara padat membantu memanfaatkan fitur dengan lebih baik.
Seri VGG: Arsitektur sederhana dan klasik, cocok untuk digunakan dalam keterbatasan sumber daya.
Model khusus: Bergantung pada karakteristik kumpulan data tertentu dan persyaratan tugas, Anda juga dapat mempertimbangkan merancang dan melatih arsitektur model yang disesuaikan, yang mungkin memerlukan lebih banyak proses debug dan eksperimen.

Pembelajaran ansambel: Pertimbangkan untuk menggunakan metode pembelajaran ansambel seperti bagging atau boosting untuk menggabungkan prediksi beberapa model guna lebih meningkatkan performa dan stabilitas.

Penyetelan hyperparameter: Selain pemilihan model, performa model juga dapat dioptimalkan dengan menyesuaikan kecepatan pembelajaran, ukuran batch, pemilihan pengoptimal, dan strategi augmentasi data.

4.12.2 Peningkatan pemilihan fungsi kerugian

Pertimbangkan untuk menerapkan Dice Loss untuk meningkatkan fungsi kerugian di masa mendatang. Dice Loss mengukur kesamaan antara hasil prediksi dan mask target, dan lebih baik untuk tugas klasifikasi biner dengan batasan yang jelas. Ini adalah fungsi kerugian yang berkinerja lebih baik pada prediksi tingkat piksel.

Perhatikan juga Focal Loss. Dirancang khusus untuk mengatasi masalah ketidakseimbangan kelas, model ini dapat lebih meningkatkan performa model pada kategori minoritas dengan mengurangi bobot sampel yang mudah diklasifikasi untuk fokus pada sampel yang sulit.

4.12.3 Peningkatan pemilihan pengoptimal

RAdam merupakan penyempurnaan dari Adam yang meningkatkan stabilitas dan performa dengan menyesuaikan koreksi kecepatan pemelajaran secara dinamis.

AdamW adalah varian Adam yang memperkenalkan peluruhan bobot untuk memecahkan masalah kinerja yang mungkin ditimbulkan Adam dalam beberapa kasus, terutama ketika jumlah parameter model banyak.

AdamW adalah varian Adam yang memperkenalkan peluruhan bobot untuk memecahkan masalah kinerja yang mungkin ditimbulkan Adam dalam beberapa kasus, terutama ketika jumlah parameter model banyak.

4.13 Model evaluasi

# 用模型 (model) 对验证数据集 (val_loader) 进行预测。这部分假设 [:, 1] 给出了类别1的概率。
val_pred = predict(val_loader, model, 1)[:, 1]
# 赋值,预测的概率(或者预测值)赋给了 val_label 数据框中名为 "y_pred" 的列
val_label["y_pred"] = val_pred
  • 1
  • 2
  • 3
  • 4

4.14 Mengintegrasikan kumpulan data akhir

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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

5. Kesimpulan

Tidak diperlukan waktu 10 menit untuk menyelesaikan menjalankan Baseline. Biasanya akan terhenti di 4,7 untuk menghasilkan spektogram Mel. Namun butuh 5 jam eksplorasi yang sabar. Berikut adalah ringkasan diam-diam dari proses-proses utama:

  • Hitung jumlah sampel
  • Buat objek audio dan video
  • Impor kumpulan data pelatihan
  • Impor data audio dan video
  • Tetapkan benih acak/CUDNN
  • Pemrosesan awal audio dan video
  • Menghasilkan spektogram mel
  • Tentukan set validasi, set prediksi, dan metode set pelatihan
  • konversi gambar
  • Gunakan pelatihan SOTA, model evaluasi optimasi yang disediakan oleh timm

6. Perluas

6.1 Definisi tugas pembelajaran mendalam

Definisi tugas pembelajaran mendalam sebenarnya dapat diringkas sebagai "propagasi balik", karena intinya adalah menggunakan algoritma propagasi balik untuk menyesuaikan parameter model guna meminimalkan fungsi kerugian yang ditentukan.

Sangat cocok menggunakan pembelajaran mendalam untuk menangani tugas audio dan video seperti itu. Menurut saya, yang pertama adalah banyaknya data audio dan video, dan perlunya klasifikasi yang rumit dari data tersebut.Mekanisme pembelajaran mendalam menentukan bahwa hal itu membutuhkan data dalam jumlah besar, dan faktanya, hal yang sangat penting adalah bahwa deepfake itu sendiri membutuhkanKlasifikasiPemikiran pada dasarnya adalah tugas klasifikasi, dan pembelajaran mendalam memiliki keuntungan besar dalam volume data yang besar dan klasifikasi yang disempurnakan. Contoh umum adalah jaringan generasi permusuhan GAN.

Kedua, data yang serupa secara statistik dibuat dalam jumlah besar, dan dapat mempelajari distribusi data dalam jumlah besar. Ia juga dapat melakukan tugas sebaliknya.

6.2 Hubungan antara AIGC dan Deepfake

Masukkan deskripsi gambar di sini

AIGC harus menyertakan Deepfake. Dari segi perkembangan, perkembangan dan dimensi teknologi Deepfake pasti akan meningkat dengan kekuatan pemrosesan AIGC. Kita akan dihadapkan pada lautan luas data asli dan palsu video-video ini. Jika dapat menghemat energi para pencipta cerita, tidak diragukan lagi bermanfaat bagi perkembangan hiburan sastra dan seni, jika digunakan untuk penipuan, maka akan segera menghadapi tantangan etika dan moral;

Salah satu pemikiran saya adalah jika digabungkan dengan kegemaran drama pendek saat ini, Deepfake dapat memungkinkan masyarakat memperoleh pengalaman hiburan audio-visual yang sangat murah, tetapi juga menantang industri film dan televisi tradisional dan bahkan aktor seperti apa. dan stimulasi audio visual yang dibutuhkan mata manusia. Ini adalah topik yang bisa diperdebatkan.