File size: 5,188 Bytes
9e14838 | 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 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | import os
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.decomposition import PCA
import pickle
import torch
import torch.nn as nn
color_map = ['tab:blue', 'tab:orange', 'tab:green', 'tab:red', 'tab:purple']
label_dict = {
0: 'FF-Real', 1: 'FF-Fake', 2: 'CDF-Real', 3: 'CDF-Fake', 4: 'FF-Fsh'
}
import argparse
parser = argparse.ArgumentParser(description='Process some paths.')
parser.add_argument("--test_dataset", nargs="+", default=['FF-DF'])
parser.add_argument("--model_name", nargs="+")
args = parser.parse_args()
def plot_explained_variance(explained_variance_ratio, cumulative_explained_variance_ratio, save_path):
plt.figure(figsize=(10, 8))
plt.plot(explained_variance_ratio[:200], marker='o', alpha=0.4, markersize=12)
plt.title('Explained Variance Ratio of Principal Components', fontsize=24, weight='bold', y=1.05)
plt.xlabel('Principal Component Index', fontsize=24, weight='bold')
plt.ylabel('Explained Variance Ratio', fontsize=24, weight='bold')
plt.tick_params(axis='both', labelsize=20) # 或者设置成24,如果希望和轴标签一样大
plt.grid(True)
plt.savefig(os.path.join(save_path, 'explained_variance_ratio.png'), dpi=300)
plt.figure(figsize=(10, 8))
plt.plot(cumulative_explained_variance_ratio[:200], marker='o', alpha=0.4, markersize=12)
plt.title('Cumulative Explained Variance Ratio', fontsize=24, weight='bold', y=1.05)
plt.xlabel('Number of Principal Components', fontsize=24, weight='bold')
plt.ylabel('Cumulative Explained Variance Ratio', fontsize=24, weight='bold')
plt.grid(True)
plt.savefig(os.path.join(save_path, 'cumulative_explained_variance_ratio.png'), dpi=300)
def main():
base_dir = './zhiyuanyan/DeepfakeBenchv2/features'
model_name = args.model_name[0]
base_dir = os.path.join(base_dir, model_name)
test_dataset = args.test_dataset
all_testing_data = []
all_testing_label = []
pool = nn.AdaptiveAvgPool2d((1, 1))
for name in os.listdir(base_dir):
if name in test_dataset:
with open(os.path.join(base_dir, name, 'tsne.pkl'), 'rb') as f:
data = pickle.load(f)
feat = data['feat']
print(f'shape of {name}:', feat.shape)
if feat.ndim == 4: # pool
print(f'shape of {name} before pooling:', feat.shape)
feat = torch.from_numpy(feat)
feat = pool(feat).squeeze()
feat = feat.numpy()
print(f'shape of {name} after pooling:', feat.shape)
label = data['label']
if name == 'Celeb-DF-v2':
label = label + 2
elif name == 'FaceShifter':
label_mask = (label == 1)
feat = feat[label_mask]
label = label[label_mask] * 4
all_testing_data.append(feat)
all_testing_label.append(label)
all_testing_data = np.concatenate(all_testing_data, axis=0)
all_testing_label = np.concatenate(all_testing_label, axis=0)
print('Total number of samples:', len(all_testing_label))
print('Label distribution:', np.unique(all_testing_label, return_counts=True))
# Perform PCA analysis
feat = all_testing_data
pca = PCA(n_components=min(feat.shape[0], feat.shape[1]))
pca.fit(feat)
explained_variance_ratio = pca.explained_variance_ratio_
cumulative_explained_variance_ratio = np.cumsum(explained_variance_ratio)
# Plot explained variance ratio and cumulative explained variance ratio
save_path = './zhiyuanyan/DeepfakeBenchv2/pca_results/' + model_name
os.makedirs(save_path, exist_ok=True)
plot_explained_variance(explained_variance_ratio, cumulative_explained_variance_ratio, save_path)
# Output the number of principal components needed to explain 90% variance
num_components_90 = np.argmax(cumulative_explained_variance_ratio >= 0.9) + 1
print(f'Number of principal components explaining 90% variance: {num_components_90}')
print(f'Feature dimension: {feat.shape[1]}')
# 计算特征值衰减系数
eigenvalues = pca.explained_variance_
decay_rate = np.diff(np.log(eigenvalues)) / np.diff(np.arange(len(eigenvalues)))
print("平均衰减率:", np.mean(decay_rate[:100]))
# Optional: Plot scatter plot of the first two principal components
feat_transformed = pca.transform(feat)[:, :2]
numerical_labels = all_testing_label
labels = [label_dict[label] for label in numerical_labels]
plt.figure(figsize=(10, 8))
sns.scatterplot(
x=feat_transformed[:, 0],
y=feat_transformed[:, 1],
hue=labels,
palette=color_map[:len(np.unique(numerical_labels))],
alpha=0.4
)
plt.title('Scatter Plot of the First Two Principal Components', fontsize=20)
plt.xlabel('Principal Component 1', fontsize=20)
plt.ylabel('Principal Component 2', fontsize=20)
plt.legend(title='Classes', loc='best')
plt.savefig(os.path.join(save_path, 'pca_scatter.png'), dpi=300)
if __name__ == '__main__':
main() |