내 연락처 정보
우편메소피아@프로톤메일.com
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
#Datawhale #AIsummercamp#summercamp
경쟁 과제는 얼굴 이미지가 Deepfake 이미지인지 여부를 판단하고 Deepfake 이미지일 확률 점수를 출력하는 것입니다. 참가자는 다양한 딥페이크 생성 기술과 복잡한 응용 시나리오에 대처할 수 있는 탐지 모델을 개발하고 최적화하여 딥페이크 이미지 탐지의 정확성과 견고성을 향상시켜야 합니다.
훈련 세트의 레이블 파일 train_label.txt는 모델 훈련에 사용되는 반면, 검증 세트의 레이블 파일 val_label.txt는 모델 튜닝에만 사용됩니다. 예를 들어 train_label.txt 또는 val_label.txt에서 각 줄은 쉼표로 구분된 두 부분으로 구성됩니다. 첫 번째 부분은 파일 이름(접미사 .mp4)이고 두 번째 부분은 실제 값입니다.
목표 값 1은 딥 페이크 오디오 및 비디오를 나타내고, 목표 값 0은 실제 얼굴 오디오 및 비디오를 나타냅니다.
다음은 train_label.txt 및 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
파일의 각 줄에는 쉼표로 구분된 두 부분이 포함되어 있습니다. 첫 번째 부분은 동영상 파일명이고, 두 번째 부분은 모델 예측에 해당하는 딥페이크 점수(즉, 딥페이크 동영상에 속하는 샘플의 확률값)입니다. 아래 제출 템플릿을 참조하세요.
prediction.csv
video_name,score
658042526e6d0c199adc7bfeb1f7c888.mp4,0.123456
a20cf2d7dea580d0affc4d85c9932479.mp4,0.123456
두 번째 단계는 공개 테스트 세트가 출시되는 첫 번째 단계에 이어집니다. 참가자는 테스트 세트의 예측 점수 파일인 Prediction_test.csv를 시스템에 제출하고, 테스트 점수 결과를 온라인으로 실시간 피드백해야 합니다.
2단계 이후 상위 30개 팀이 3단계로 진출하게 된다. 이 단계에서 참가자는 코드 도커와 기술 보고서를 제출해야 합니다. Docker 요구 사항에는 원본 학습 코드와 테스트 API가 포함됩니다(함수 입력은 이미지 경로이고 출력은 모델에서 예측한 deepfake 점수입니다). 스폰서는 훈련 과정과 테스트 결과를 재현하기 위해 알고리즘 코드를 확인하고 다시 실행합니다.
단일 모델만 제출할 수 있으며 유효한 네트워크 매개변수는 200M을 초과할 수 없습니다(사용홉도구 통계 모델 매개변수).
ImageNet1K를 사용한 사전 모델 학습만 허용됩니다. 게시된 훈련 세트를 기반으로 생성된 확장 샘플(데이터 확대/딥페이크 도구를 통해)을 훈련에 사용할 수 있지만 이러한 도구는 세 번째 단계에서 재현을 위해 제출되어야 합니다.
평가 지표는 주로 ROC 곡선 아래의 AUC를 지표로 사용합니다. AUC의 값 범위는 일반적으로 다음과 같습니다.0.5-1사이에, 그렇지 않으면 우리는 생각합니다이것은 좋은 기계 학습 모델이 아닙니다. . AUC가 1에 가까울수록 모델이 더 좋습니다. AUC가 순위 결과가 모호한 경우 **TPR(참양성률)**을 보조 참조로 사용합니다. 물론 그에 상응하는 방식이 FPR이다.
F1-점수우리가 참고할 수 있는 지표이기도 합니다. 정밀도율과 재현율입니다.조화평균。
F 1 _ S 코어 = 2 ∗ ( TP ) / ( 2 TP + FN + FP ) F1_점수 = 2*(TP)/(2TP+FN+FP)에프1_에스핵심=2∗(티피)/(2티피+FN+FP)
기계 학습을 배우기 전에 우리는 두 가지 중요한 개념을 검토해야 합니다.정확성그리고상기하다。
정확성: 정확도 = TPTP + FP 정확도 = frac{TP}{TP+FP}피기록하다나에스나영형N=티피+FP티피, 이는 모델의 측정에 사용됩니다.성능 확인, 정확하게 예측된 샘플 중 양성으로 예측되는 샘플의 비율입니다.
상기하다: 리콜 = TPTP + FN 리콜 = frac{TP}{TP+FN}아르 자형에크ㅏ나는=티피+FN티피, 이는 모델의 측정에 사용됩니다.검색 실적, 양성으로 예측되는 표본 중 실제로 양성인 표본의 비율입니다.
참양성률(TPR):
총비용 = 총비용 / (총비용 + 총비용)
거짓양성률(FPR):
FPR = FP / (FP + TN)
안에:
TP: 공격 샘플이 공격으로 올바르게 식별됩니다.
TN: 실제 샘플은 실제 샘플로 올바르게 식별됩니다.
FP: 실제 샘플이 공격으로 잘못 식별되었습니다.
FN: 공격 샘플이 실제로 잘못 식별되었습니다.
참고문헌: Aghajan, H., Augusto, JC, & Delgado, RLC (Eds.) (제목에 제공된 링크가 열리지 않으면 다음을 클릭하십시오.)책 전체)
내 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
분류가 필요한 경우 임계값이 필요할 수 있습니다. 예측값과의 관계는 다음과 같습니다.
예측 = 확률 > 임계값 예측 = 확률 > 임계값피답장디나씨티나영형N=피로바비엘나티와이>티시간해상도시간영형엘디
AUC를 학습한 후 배워야 할 또 다른 중요한 측정항목은 로그 손실입니다. 이진 분류 문제의 경우 로그 손실을 다음과 같이 정의합니다.
로그 손실 = − 목표 ∗ log ( p ) − ( 1 − 목표 ) ∗ log ( 1 − p ) 로그 손실 = -목표*log(p) - (1-목표)*log(1-p)엘영형글엘오스=−티ㅏ아르 자형g이자형티∗엘영형g(피)−(1−티ㅏ아르 자형g이자형티)∗엘영형g(1−피)
그 중 목표값은 0 또는 1이고, 예측값은 표본이 카테고리 1에 속할 확률이다. 로그 손실은 매우 확실한 예측과 매우 잘못된 예측 모두에 불이익을 줍니다. 로그 손실이 작을수록 모델에서 예측한 확률이 목표 값에 더 가까워집니다.
분류 문제에 이러한 지표를 사용할 수도 있습니다.
# “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
샘플 수를 나타내는 행 수만 세면 됩니다.
from IPython.display import Video
Video("/kaggle/input/ffdv-sample-dataset/ffdv_phase1_sample/valset/00882a2832edbcab1d3dfc4cc62cfbb9.mp4", embed=True)
Video는 비디오 개체를 생성하며, 포함은 True로 설정되면 비디오 플레이어가 노트북 셀의 출력에 직접 표시된다는 의미입니다.
Kaggle의 기준선에서 실행한 후 다음과 같은 결과가 표시됩니다.
!pip install moviepy librosa matplotlib numpy timm
사용된 라이브러리에 대한 문서 링크:
무비파이
리브로사(librosa는 Python 음성 신호 처리를 위한 매우 강력한 타사 라이브러리입니다. 이 기준선에서는 주로 MEL 스펙트로그램 생성 및 스펙트로그램 변환을 사용합니다.)
맷플롯립
넘파이
팀(이미지 분류 모델 라이브러리, 다양한 sota 모델을 빠르게 구축)
SOTA 란 무엇입니까? SOTA의 정식 명칭은 State of the Arts, 즉 이 분야 최고의 모델을 뜻합니다. SOTA는 일부 벤치마크 데이터 세트에서 매우 높은 점수를 받았습니다.
비엔드-투-엔드 모델(파이프라인): 먼저 끝이 무엇인지 이해해야 합니다. 두 끝은 입력 끝에서 출력 끝을 나타냅니다. 전통적인 머신러닝 프로세스는 서로 독립적인 여러 모듈로 구성됩니다. 후자 모듈의 결과는 이전 결과의 수준에 따라 달라지며 전체 훈련 결과에 영향을 미칩니다.
End-to-End 모델(end to end): 우선 입력단부터 출력단까지 예측이 생성된다는 점을 이해해야 합니다. 이 예측 결과는 실제 결과와 비교하여 오류가 발생합니다(기억해야 함). 머신러닝의 핵심 임무는 여전히예측하다 ), 이 오류는 신경망의 각 계층으로 다시 전파되고 모델이 수렴되거나 기대하는 결과를 얻을 때까지 모델의 가중치와 매개변수가 조정됩니다. 제어 시스템 측면에서 살펴보면 이는 폐쇄 루프 제어 시스템입니다. (예:BP 신경망)
시퀀스-투-시퀀스(seq2seq): 이것은 일반적인끝으로 종료시퀀스 예측 방법은 인코더와 디코더로 구성된 구조입니다. 질문 및 답변 데이터 세트를 사용하여 인코딩/디코딩하면 질문 및 답변 로봇을 얻을 수 있습니다.
질문은 Baseline 자체로 돌아갑니다. Baseline이란 무엇입니까?기준선은 일반적으로 간단하고 구현하기 쉬운 기준선 모델을 나타냅니다.
알고리즘 튜닝 및 매개변수 조정 과정에서 Baseline의 임무는 자신을 비교하여 모델을 점점 더 좋게 만드는 것입니다.
벤치마크 역시 중요한 개념으로, 그 의미는 다음과 같습니다.벤치마크 . 일반적으로 모델 간 차이를 측정하는 데 사용되는 알고리즘, 모델 또는 방법의 성능에 대한 표준화된 평가 및 비교 방법을 나타냅니다.
모델 벤치마킹 사이트에서 자주 보실 수 있습니다.예를 들어시난。
기준을 실행할 때 CUDA 구성 오류가 발생했습니다. 다른 가속기를 사용하십시오.
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은 비디오 파일 경로, Mel 주파수 필터 수, 최고 주파수(계산된 스펙트럼 범위 제어) 및 대상 이미지 크기와 같은 매개변수를 허용합니다.
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
데이터 양이 너무 많아서 여기에는 사진을 게시하지 않겠습니다. 대신 일반적인 상황에서는 Mel 다이어그램을 게시하겠습니다.
이미지 출처:사이먼 프레이저 대학교
전원을 켜서 들어보면 점점 작아지는 오디오 조각입니다.
# 使用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)
AverageMeter 클래스는 변수의 평균 및 현재 값을 계산하고 저장하는 데 사용됩니다.
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__)
ProgressMeter 클래스는 훈련 과정 중에 현재 배치 정보와 통계 지표를 출력하는 데 사용됩니다.
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) + ']'
검증 기능은 훈련 과정 중에 검증 세트에 대한 모델 성능을 정기적으로 평가하고 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
예측 기능은 테스트 세트에 대한 추론을 수행하는 데 사용되며 TTA(테스트 시간 확대) 사용을 지원하여 다중 예측 및 평균화를 통해 모델 예측의 안정성을 향상시킵니다.
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
훈련 함수는 모델 훈련, 손실 함수 및 정확도 계산을 통한 모델 매개변수 업데이트, 역전파 및 최적화 단계 수행을 담당합니다.
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)]
변환은 후속 데이터 향상을 위한 매개변수를 남기며 기본값은 없음입니다.
이미지가 RGB 모드로 변환됩니다.
라벨은 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)
위에 설정된 FFDID 클래스를 참조합니다.
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')
산출:
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
심층 네트워크: 더 높은 성능과 더 복잡한 특징 추출 기능이 필요한 경우 ResNet-34, ResNet-50 또는 더 큰 ResNet 변형(예: ResNet-101 또는 ResNet-152)과 같은 심층 네트워크 사용을 고려할 수 있습니다.
기타 사전 훈련된 모델: ResNet 시리즈 외에도 다음과 같이 선택할 수 있는 다른 사전 훈련된 모델이 많이 있습니다.
EfficientNet: 뛰어난 성능과 매개변수 효율성을 제공합니다.
DenseNet: 조밀하게 연결된 네트워크 구조는 기능을 더 잘 활용하는 데 도움이 됩니다.
VGG 시리즈: 리소스 제약 하에 사용하기에 적합한 단순하고 고전적인 아키텍처입니다.
사용자 정의 모델: 특정 데이터 세트 특성 및 작업 요구 사항에 따라 더 많은 디버깅과 실험이 필요할 수 있는 사용자 정의 모델 아키텍처를 설계하고 교육하는 것을 고려할 수도 있습니다.
앙상블 학습: 배깅 또는 부스팅과 같은 앙상블 학습 방법을 사용하여 여러 모델의 예측을 결합하여 성능과 안정성을 더욱 향상시키는 것을 고려하십시오.
초매개변수 조정: 모델 선택 외에도 학습률, 배치 크기, 최적화 도구 선택 및 데이터 확대 전략을 조정하여 모델 성능을 최적화할 수도 있습니다.
향후 손실 함수를 개선하려면 Dice Loss를 적용하는 것이 좋습니다. Dice Loss는 예측 결과와 대상 마스크 간의 유사성을 측정하며 경계가 명확한 이진 분류 작업에 더 좋습니다. 이는 픽셀 수준 예측에서 더 나은 성능을 발휘하는 손실 함수입니다.
또한 초점 손실(Focal Loss)도 주의 깊게 살펴보세요. 클래스 불균형 문제를 해결하기 위해 특별히 설계된 이 모델은 분류하기 쉬운 샘플의 가중치를 줄여 어려운 샘플에 집중함으로써 소수 범주에 대한 모델 성능을 더욱 향상시킬 수 있습니다.
RAdam은 학습률 보정을 동적으로 조정하여 안정성과 성능을 향상시키는 Adam의 개선 사항입니다.
AdamW는 Adam이 일부 경우, 특히 모델 매개변수 수가 많은 경우 발생할 수 있는 성능 문제를 해결하기 위해 가중치 감소를 도입한 Adam의 변형입니다.
AdamW는 Adam이 일부 경우, 특히 모델 매개변수 수가 많은 경우 발생할 수 있는 성능 문제를 해결하기 위해 가중치 감소를 도입한 Adam의 변형입니다.
# 用模型 (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)
기준선 실행을 완료하는 데는 10분이 걸리지 않습니다. 일반적으로 Mel 스펙트로그램을 생성하려면 4.7에서 멈춰야 합니다. 하지만 환자 탐색에는 5시간이 걸립니다. 다음은 주요 프로세스에 대한 자동 요약입니다.
딥러닝의 작업 정의는 실제로 "역전파"로 요약될 수 있습니다. 그 핵심은 역전파 알고리즘을 사용하여 모델 매개변수를 조정하여 정의된 손실 함수를 최소화하는 것이기 때문입니다.
이러한 오디오 및 비디오 작업을 처리하기 위해 딥러닝을 사용하는 것이 매우 적합하다고 생각합니다. 첫 번째는 엄청난 양의 오디오 및 비디오 데이터와 이러한 데이터를 복잡하게 분류해야 한다는 것입니다.딥러닝의 메커니즘은 엄청난 양의 데이터가 필요하다고 판단하는데, 사실 매우 중요한 점은 딥페이크 자체가 데이터를 필요로 한다는 점입니다.분류사고는 본질적으로 분류 작업이며, 딥러닝은 대용량 데이터와 정제된 분류에서 큰 이점을 갖습니다. 친숙한 예는 적대적 생성 네트워크 GAN입니다.
둘째, 통계적으로 유사한 데이터가 대량으로 생성되며, 엄청난 양의 데이터의 분포를 학습할 수 있습니다. 또한 반대 작업도 수행할 수 있습니다.
AIGC에는 Deepfake가 포함되어야 합니다. 개발 관점에서 볼 때 AIGC의 처리 능력과 함께 Deepfake 기술의 개발 및 차원성은 확실히 증가할 것입니다. 물론 우리는 이러한 비디오가 무엇인지도 확인해야 합니다. 만약 그것이 절약될 수 있다면, 스토리 창작자들의 에너지는 의심할 바 없이 문학과 예술의 발전에 도움이 될 것입니다.
내 생각 중 하나는 현재의 단편 드라마 열풍과 결합하면 Deepfake가 대중에게 초저가 시청각 엔터테인먼트 경험을 제공할 수 있을 뿐만 아니라 전통적인 영화 및 TV 산업, 심지어 어떤 종류의 배우와 배우에게도 도전이 된다는 것입니다. 인간의 눈에는 시청각 자극이 필요합니다. 이것은 논쟁의 여지가 있는 주제입니다.