私の連絡先情報
郵便メール:
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
#データホエール #AIサマーキャンプ#サマーキャンプ
競争タスクは、顔画像がディープフェイク画像であるかどうかを判断し、それがディープフェイク画像である確率スコアを出力することです。参加者は、多様なディープフェイク生成テクノロジーと複雑なアプリケーションシナリオに対処する検出モデルを開発および最適化し、それによってディープフェイク画像検出の精度と堅牢性を向上させる必要があります。
トレーニング セットのラベル ファイル train_label.txt はモデルのトレーニングに使用されますが、検証セットのラベル ファイル val_label.txt はモデルのチューニングにのみ使用されます。たとえば、train_label.txt または val_label.txt では、各行にカンマで区切られた 2 つの部分が含まれています。最初の部分はファイル名 (拡張子 .mp4) で、2 番目の部分は実際の値です。
ターゲット値 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
ファイルの各行には、カンマで区切られた 2 つの部分が含まれています。最初の部分はビデオ ファイル名で、2 番目の部分はモデル予測に対応するディープフェイク スコア (つまり、ディープフェイク ビデオに属するサンプルの確率値) です。以下の提出テンプレートを参照してください。
prediction.csv
video_name,score
658042526e6d0c199adc7bfeb1f7c888.mp4,0.123456
a20cf2d7dea580d0affc4d85c9932479.mp4,0.123456
第 2 フェーズは、パブリック テスト セットがリリースされる第 1 フェーズに続きます。参加者は、テスト セットの予測スコア ファイル precision_test.csv をシステムに送信し、テスト スコア結果をオンラインでリアルタイムにフィードバックする必要があります。
第2ステージ終了後、上位30チームが第3ステージに進む。この段階で、出場者はコード ドッカーと技術レポートを提出する必要があります。 Docker の要件には、元のトレーニング コードとテスト API (関数の入力は画像パス、出力はモデルによって予測されたディープフェイク スコア) が含まれます。スポンサーはアルゴリズム コードをチェックして再実行し、トレーニング プロセスとテスト結果を再現します。
送信できるのは 1 つのモデルのみであり、有効なネットワーク パラメータは 200M を超えてはなりません (次を使用します)。トンプツール統計モデル パラメーター)。
ImageNet1K を使用した事前モデル トレーニングのみが許可されます。公開されたトレーニング セットに基づいて (データ拡張/ディープフェイク ツール経由で) 生成された拡張サンプルはトレーニングに使用できますが、これらのツールは第 3 段階で複製のために提出する必要があります。
評価指標は主に 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_S芯=2∗(TP)/(2TP+翻訳+FP)
機械学習を学ぶ前に、次の 2 つの重要な概念を確認する必要があります。正確さそして想起。
正確さ: 精度 = TPTP + FP 精度 = frac{TP}{TP+FP}ポ記録私s私oん=TP+FPTP、モデルの測定に使用されます。パフォーマンスをチェックする、正しく予測されたサンプルのうち、陽性であると予測されたサンプルの割合。
想起: リコール = TPTP + FN リコール = frac{TP}{TP+FN}Rec1つのll=TP+翻訳TP、モデルの測定に使用されます。検索パフォーマンス、陽性であると予測されるサンプルのうち、実際に陽性であるサンプルの割合。
真陽性率 (TPR):
TPR = TP / (TP + FN)
誤検知率 (FPR):
FPR = FP / (FP + TN)
で:
TP: 攻撃サンプルは攻撃として正しく識別されます。
TN: 本物のサンプルは本物として正しく識別されます。
FP: 本物のサンプルは誤って攻撃として認識されます。
FN: 攻撃サンプルは誤って本物であると識別されています。
参考文献: Aghajan, H.、Augusto, JC, & Delgado, RLC (2009) (タイトルに表示されているリンクが開けない場合は、次をクリックしてください。本全体)
私の 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
分類が必要な場合は、しきい値が必要になる場合があります。予測値との関係は次のとおりです。
予測 = 確率 > 閾値 予測 = 確率 > 閾値ポ再d私ct私oん=ポロバビl私tええ>Th解像度hold
AUC を学習した後、学習する必要があるもう 1 つの重要な指標はログ損失です。バイナリ分類問題の場合、ログ損失を次のように定義します。
ログ損失 = − ターゲット ∗ log ( p ) − ( 1 − ターゲット ) ∗ log ( 1 − p ) ログ損失 = -ターゲット*log(p) - (1-ターゲット)*log(1-p)らo言語オス=−t1つのrグet∗loグ(p)−(1−t1つのrグet)∗loグ(1−p)
このうち、目標値は 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 はビデオ オブジェクトを作成します。Embed は、True に設定すると、ノートブック セルの出力にビデオ プレーヤーが直接表示されることを意味します。
kaggle のベースラインで実行すると、次のような結果が表示されるはずです。
!pip install moviepy librosa matplotlib numpy timm
使用されるライブラリのドキュメント リンク:
ムービーピー
リブロサ(librosa は、Python 音声信号処理用の非常に強力なサードパーティ ライブラリです。このベースラインでは、主に MEL スペクトログラム生成とスペクトログラム変換を使用します)
マットプロット
ナンピー
ティム(画像分類モデルライブラリ、さまざまなsotaモデルを迅速に構築)
SOTAとは何ですか? SOTAの正式名称は「State of the Arts」で、この分野で最高のモデルを指します。 SOTA は、一部のベンチマーク データ セットで非常に高いスコアを示します。
非エンドツーエンド モデル (パイプライン): まず最初に、2 つのエンドとは入力エンドから出力エンドまでを指します。従来の機械学習プロセスは、互いに独立した複数のモジュールで構成されており、後者のモジュールの結果は前の結果のレベルに依存し、トレーニング結果全体に影響します。
エンドツーエンドモデル(エンドツーエンド):まず、入力端から出力端まで予測が生成されることを理解する必要があります(この予測結果は実際の結果と比較して誤差があることを覚えておく必要があります)。機械学習の中核タスクは依然として予測する )、この誤差はニューラル ネットワークの各層に伝播され、モデルが収束するまで、または期待される結果が得られるまで、モデルの重みとパラメーターが調整されます。制御システムの観点から見ると、これは閉ループ制御システムです。 (例:BPニューラルネットワーク)
シーケンス間 (seq2seq): これは一般的なものです。端から端までシーケンス予測手法は、エンコーダとデコーダで構成されており、質問と回答のデータセットを使用してエンコード/デコードすると、シーケンスからシーケンスへのアプリケーションが得られます。
質問はベースライン自体に戻ります。ベースラインとは何ですか?ベースラインは通常、シンプルで実装が簡単なベースライン モデルを指します。
アルゴリズムのチューニングとパラメーター調整のプロセスにおいて、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 は、ビデオ ファイル パス、メル周波数フィルターの数、最高周波数 (計算されたスペクトル範囲を制御)、ターゲット画像サイズなどのパラメーターを受け入れます。
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
データ量が多すぎるため、ここでは写真を掲載しません。代わりに、通常の状況におけるメル図を掲載します。
画像出典:サイモン・フレイザー大学
電源を入れて聞いてみると、徐々に音が小さくなる音声です。
# 使用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) + ']'
validate 関数は、トレーニング プロセス中に検証セットに基づいてモデルのパフォーマンスを定期的に評価し、トップ 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
train 関数は、モデルのトレーニング、損失関数と精度の計算によるモデル パラメーターの更新、バックプロパゲーションと最適化のステップの実行を担当します。
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)]
変換では後続のデータ拡張のためのパラメータが残され、デフォルトは None です。
画像は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 は、予測結果とターゲット マスク間の類似性を測定するため、境界が明らかなバイナリ分類タスクに適しています。これは、ピクセルレベルの予測でより優れたパフォーマンスを発揮する損失関数です。
焦点損失にも注意してください。クラスの不均衡問題を解決するために特別に設計されたこのツールは、分類しやすいサンプルの重みを減らして困難なサンプルに焦点を当てることにより、少数派のカテゴリーでのモデルのパフォーマンスをさらに向上させることができます。
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 分はかかりません。通常、メル スペクトログラムの生成は 4.7 で止まります。ただし、根気強く探索するには 5 時間かかります。以下に主要なプロセスを簡単にまとめます。
深層学習のタスク定義は、実際には「バックプロパゲーション」として要約できます。その核心は、バックプロパゲーションアルゴリズムを使用してモデルパラメータを調整し、定義された損失関数を最小化することだからです。
このようなオーディオやビデオのタスクを処理するには、ディープ ラーニングを使用するのが非常に適しています。1 つ目は、膨大な量のオーディオおよびビデオ データと、これらのデータの複雑な分類の必要性だと思います。ディープラーニングの仕組みからすると、ディープラーニングには膨大な量のデータが必要であることがわかりますが、実は非常に重要な点は、ディープフェイク自体が必要とするデータです。分類思考は本質的に分類タスクであり、ディープラーニングは大量のデータと洗練された分類において大きな利点を持っています。よく知られた例は敵対的生成ネットワーク GAN です。
2つ目は、統計的に類似したデータが大量に作成され、膨大なデータの分布を学習できることです。逆のタスクを実行することもできます。
AIGC にはディープフェイクを含める必要があります。開発の観点から見ると、AIGC の処理能力により、ディープフェイク技術の発展と次元は確実に増加します。もちろん、これらのビデオが何であるかを確認する必要もあります。物語の創作者のエネルギーは間違いなく文学や芸術の発展に有益ですが、もしそれが欺瞞に使われれば、すぐに倫理的、道徳的な問題に直面するでしょう。
私の考えの 1 つは、ディープフェイクは、現在のショートドラマの流行と組み合わせることで、一般の人々が超低コストのオーディオビジュアルエンターテインメント体験を得ることができるようになりますが、同時に伝統的な映画やテレビ業界、さらにはどのような俳優と俳優が出演するかという問題にも挑戦するということです。人間の目には聴覚と視覚の刺激が必要です。これは議論の余地のあるテーマです。