Kaggle competition: Deepfake Detection Challenge
<SOS> metric: LogLoss Kaggle data source: deepfake-detection-challenge<prepare_x_and_y>
%%time
%%capture
y = train_df['y']
train_df.drop(['y'], axis=1, inplace=True )<categorify>
test_dir = "/kaggle/input/deepfake-detection-challenge/test_videos/"
test_videos = sorted([x for x in os.listdir(test_dir)if x[-4:] == ".mp4"])
 len(test_videos )
class MeanEncoding(BaseEstimator):

 def __init__(self, feature, C=0.1):
self.C = C
self.feature = feature
def fit(self, X_train, y_train):
df = pd.DataFrame({'feature': X_train[self.feature], 'target': y_train} ).dropna()
self.global_mean = df.target.mean()
mean = df.groupby('feature' ).target.mean()
size = df.groupby('feature' ).target.size()
self.encoding =(self.global_mean * self.C + mean * size)/(self.C + size)
 def transform(self, X_test):
X_test[self.feature] = X_test[self.feature].map(self.encoding ).fillna(self.global_mean ).values
return X_test
def fit_transform(self, X_train, y_train):
df = pd.DataFrame({'feature': X_train[self.feature], 'target': y_train} ).dropna()
self.global_mean = df.target.mean()
mean = df.groupby('feature' ).target.mean()
size = df.groupby('feature' ).target.size()
self.encoding =(self.global_mean * self.C + mean * size)/(self.C + size)
 X_train[self.feature] = X_train[self.feature].map(self.encoding ).fillna(self.global_mean ).values
return X_train<categorify>
print("PyTorch version:", torch.__version__)
 print("CUDA version:", torch.version.cuda)
 print("cuDNN version:", torch.backends.cudnn.version() )
for f in cat_cols:
me = MeanEncoding(f, C=0.99)
 me.fit(train_df, y)
 train_df = me.transform(train_df)
 test_df = me.transform(test_df )<predict_on_test>
device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
km = KMeans(n_clusters=2, random_state=13)
 km.fit(pd.DataFrame(y))
y_clust = km.predict(pd.DataFrame(y))<count_values>
facedet = BlazeFace().to(device)
 facedet.load_weights("/kaggle/input/blazeface-pytorch/blazeface.pth")
 facedet.load_anchors("/kaggle/input/blazeface-pytorch/anchors.npy")
 _ = facedet.train(False )
pd.Series(y_clust ).value_counts(normalize=True )<split>
input_size = 256
X_train, X_val, y_train, y_val, y_train_clust, y_val_clust = train_test_split(
 train_df, y, pd.Series(y_clust),
test_size=0.25,
stratify=y_clust,
random_state=777
)<count_values>
mean = [0.485, 0.456, 0.406]
std = [0.229, 0.224, 0.225]
normalize_transform = Normalize(mean, std )
y_train_clust.value_counts(normalize=True )<normalization>
def disable_grad(model):
for parameter in model.parameters() :
parameter.requires_grad = False
return model
def normalize(img):
y, x, _ = img.shape
if y > x and x < 256:
ratio_x = x / y
ratio_y = y / x
return cv2.resize(img,(256, int(ratio_y * 256)))
 elif y < x and y < 256:
ratio_x = x / y
ratio_y = y / x
return cv2.resize(img,(int(ratio_x * 256), 256))
else:
return cv2.resize(img,(256, 256))
def weight_preds(preds, weights):
final_preds = []
for i in range(len(preds)) :
for j in range(len(preds[i])) :
if len(final_preds)!= len(preds[i]):
final_preds.append(preds[i][j] * weights[i])
 else:
final_preds[j] += preds[i][j] * weights[i]
return torch.FloatTensor(final_preds)
 def predict_faces(models, x, weigths, n):
x = torch.tensor(x, device=device ).float()
x = x.permute(( 0, 3, 1, 2))
for i in range(len(x)) :
x[i] = normalize_transform(x[i] / 255.)
with torch.no_grad() :
y_pred = 0
preds = []
for i in range(len(models)) :
preds.append(models[i](x ).squeeze() [:n])
 del x
y_pred = torch.sigmoid(weight_preds(preds, weigths)).mean().item()
return y_pred
scaler = StandardScaler()
scaler.fit(X_train)
 X_train_sc = pd.DataFrame(scaler.transform(X_train))
X_val_sc = pd.DataFrame(scaler.transform(X_val))
test_df_sc = pd.DataFrame(scaler.transform(test_df))<normalization>
frames_per_video = 32
video_reader = VideoReader()
video_read_fn = lambda x: video_reader.read_frames(x, num_frames=frames_per_video)
 face_extractor = FaceExtractor(video_read_fn, facedet )
pca = PCA(n_components=2)
 pca.fit(X_train_sc)
 train_pca_transformed = pca.transform(X_train_sc )<compute_train_metric>
class MetaModel(nn.Module):
def __init__(self, models=None, device='cuda:0', extended=False):
super(MetaModel, self ).__init__()
self.extended = extended
self.device = device
self.models = models
self.len = len(models)
 if self.extended:
self.bn = nn.BatchNorm1d(self.len)
 self.relu = nn.ReLU()
self.dropout = nn.Dropout(0.2)
 self.fc = nn.Linear(self.len, 1)
 def forward(self, x):
x = torch.cat(tuple(x), dim=1)
 if self.extended:
x = self.bn(x)
 x = self.relu(x)
 x = self.fc(x)
 return x
lasso = LassoCV(max_iter=9999)
 lasso.fit(X_train_sc, y_train)
 lasso_train_pred = lasso.predict(X_train_sc)
 lasso_val_pred = lasso.predict(X_val_sc)
 print('train', metrics.r2_score(y_train, lasso_train_pred), 'val', metrics.r2_score(y_val, lasso_val_pred))<compute_train_metric>
MODELS_PATH = "/kaggle/input/deepfake-detection-model-20k/"
WEIGTHS_EXT = '.pth'
models = []
weigths = []
raw_data_stack = \
[
['0.8548137313946486 0.3376769562025044', 'efficientnet-b2'],
['EfficientNetb3 0.8573518024606384 0.34558522378585194', 'efficientnet-b3'],
['EfficientNetb4 0.8579110384582294 0.3383911053075265', 'efficientnet-b4'],
['EfficientNet6 0.8602770369095758 0.33193617861157143', 'efficientnet-b6'],
['EfficientNetb0 t2 0.8616966359803837 0.3698434531609828', 'efficientnet-b0'],
['EfficientNetb1 t2 0.8410909403768391 0.36058002083572327', 'efficientnet-b1'],
['EfficientNetb2 t2 0.8659554331928073 0.35598630783834084', 'efficientnet-b2'],
['EfficientNetb3 t2 0.8486191172674868 0.3611779548592305', 'efficientnet-b3'],
['EfficientNetb3 0.8635894347414609 0.328333642473084', 'efficientnet-b3'],
['EfficientNetb6 0.8593736556826981 0.32286693639934694', 'efficientnet-b6'],
['tf_efficientnet_b1_ns 0.8571367116923342 0.3341234226295108', 'tf_efficientnet_b1_ns'],
['tf_efficientnet_b3_ns 0.8712466660930913 0.3277394129117183', 'tf_efficientnet_b3_ns'],
['tf_efficientnet_b4_ns 0.8708595027101437 0.3152573955405342', 'tf_efficientnet_b4_ns'],
['tf_efficientnet_b6_ns 0.8733115374688118 0.3156576980666498', 'tf_efficientnet_b6_ns'],
]
stack_models = []
for raw_model in raw_data_stack:
checkpoint = torch.load(MODELS_PATH + raw_model[0] + WEIGTHS_EXT, map_location=device)
 if '-' in raw_model[1]:
model = EfficientNet.from_name(raw_model[1])
 model._fc = nn.Linear(model._fc.in_features, 1)
 else:
model = timm.create_model(raw_model[1], pretrained=False)
 model.classifier = nn.Linear(model.classifier.in_features, 1)
 model.load_state_dict(checkpoint)
 _ = model.eval()
_ = disable_grad(model)
 model = model.to(device)
 stack_models.append(model)
 del checkpoint, model
meta_models = \
[
['MetaModel 0.30638167556896007', slice(4, 8), False, 0.37780],
['MetaModel 0.2919331893755284', slice(0, 4), False, 0.33357],
['MetaModel 0.30281482560578044', slice(0, 8, None), True, 0.34077],
['MetaModel 0.26302117601197256', slice(0, 10, None), False, 0.35134],
['MetaModel 0.256337642808031', slice(10, 14, None), False, 0.32698],
['MetaModel 0.264787397152165', slice(0, 14, None), False, 0.34974]
]
for meta_raw in meta_models:
checkpoint = torch.load(MODELS_PATH + meta_raw[0] + WEIGTHS_EXT, map_location=device)
 model = MetaModel(models=raw_data_stack[meta_raw[1]], extended=meta_raw[2] ).to(device)
 model.load_state_dict(checkpoint)
 _ = model.eval()
_ = disable_grad(model)
 model.to(device)
 models.append(model)
 weigths.append(meta_raw[3])
 del model, checkpoint
total = sum([1-score for score in weigths])
 weigths = [(1-score)/ total for score in weigths]
ridge = RidgeCV()
ridge.fit(X_train_sc, y_train)
 ridge_train_pred = ridge.predict(X_train_sc)
 ridge_val_pred = ridge.predict(X_val_sc)
 print('train', metrics.r2_score(y_train, ridge_train_pred), 'val', metrics.r2_score(y_val, ridge_val_pred))<compute_train_metric>
def predict_on_video(video_path, batch_size):
try:
faces = face_extractor.process_video(video_path)
 face_extractor.keep_only_best_face(faces)
 if len(faces)> 0:
x = np.zeros(( batch_size, input_size, input_size, 3), dtype=np.uint8)
 n = 0
for frame_data in faces:
for face in frame_data["faces"]:
resized_face = normalize(face)
 resized_face = torchvision.transforms.CenterCrop(( input_size, input_size))(Image.fromarray(resized_face))
if n < batch_size:
x[n] = resized_face
n += 1
else:
print("WARNING: have %d faces but batch size is %d" %(n, batch_size))
del faces
if n > 0:
x = torch.tensor(x, device=device ).float()
x = x.permute(( 0, 3, 1, 2))
for i in range(len(x)) :
x[i] = normalize_transform(x[i] / 255.)
with torch.no_grad() :
y_pred = 0
stacked_preds = []
preds = []
for i in range(len(stack_models)) :
stacked_preds.append(stack_models[i](x ).squeeze() [:n].unsqueeze(dim=1))
for i in range(len(models)) :
preds.append(models[i](stacked_preds[meta_models[i][1]]))
del x, stacked_preds
y_pred = torch.sigmoid(weight_preds(preds, weigths)).mean().item()
del preds
return y_pred
except Exception as e:
print("Prediction error on video %s: %s" %(video_path, str(e)))
 return 0.5
enet = ElasticNetCV()
enet.fit(X_train_sc, y_train)
 enet_train_pred = enet.predict(X_train_sc)
 enet_val_pred = enet.predict(X_val_sc)
 print('train', metrics.r2_score(y_train, enet_train_pred), 'val', metrics.r2_score(y_val, enet_val_pred))<compute_train_metric>
def predict_on_video_single(video_path, batch_size):
try:
faces = face_extractor.process_video(video_path)
 face_extractor.keep_only_best_face(faces)
 if len(faces)> 0:
x = np.zeros(( batch_size, input_size, input_size, 3), dtype=np.uint8)
 n = 0
for frame_data in faces:
for face in frame_data["faces"]:
resized_face = cv2.resize(face,(input_size, input_size))
if n < batch_size:
x[n] = resized_face
n += 1
else:
print("WARNING: have %d faces but batch size is %d" %(n, batch_size))
del faces
if n > 0:
x = torch.tensor(x, device=device ).float()
x = x.permute(( 0, 3, 1, 2))
for i in range(len(x)) :
x[i] = normalize_transform(x[i] / 255.)
with torch.no_grad() :
stacked_preds = []
preds = []
for i in range(len(stack_models)) :
stacked_preds.append(stack_models[i](x ).squeeze() [:n].unsqueeze(dim=1))
del x
y_pred = torch.sigmoid(models[-1](stacked_preds)).mean().item()
return y_pred
except Exception as e:
print("Prediction error on video %s: %s" %(video_path, str(e)))
 return 0.5
huber = HuberRegressor(alpha=0.05)
 huber.fit(X_train_sc, y_train)
 huber_train_pred = huber.predict(X_train_sc)
 huber_val_pred = huber.predict(X_val_sc)
 print('train', metrics.r2_score(y_train, huber_train_pred), 'val', metrics.r2_score(y_val, huber_val_pred))<compute_train_metric>
def predict_on_video_set(videos, num_workers):
def process_file(i):
filename = videos[i]
y_pred = predict_on_video(os.path.join(test_dir, filename), batch_size=frames_per_video)

return y_pred
with ThreadPoolExecutor(max_workers=num_workers)as ex:
predictions = ex.map(process_file, range(len(videos)))
 return list(predictions )
rf = RandomForestRegressor(n_estimators=5)
 rf.fit(X_train_sc, y_train)
 rf_train_pred = rf.predict(X_train_sc)
 rf_val_pred = rf.predict(X_val_sc)
 print('train', metrics.r2_score(y_train, rf_train_pred), 'val', metrics.r2_score(y_val, rf_val_pred))<predict_on_test>
speed_test = False
sub_df['y'] = np.round(np.exp(lasso.predict(test_df_sc)) , 4 )<save_to_csv>
if speed_test:
start_time = time.time()
speedtest_videos = test_videos[:5]
predictions = predict_on_video_set(speedtest_videos, num_workers=4)
 elapsed = time.time() - start_time
print("Elapsed %f min.Average per video: %f sec." %(elapsed / 60, elapsed / len(speedtest_videos)) )
sub_df.to_csv('sub.csv', index=False )<set_options>
predictions = predict_on_video_set(test_videos, num_workers=4 )
plt.ion()<load_from_csv>
submission_df = pd.DataFrame({"filename": test_videos, "label": predictions})
 submission_df.to_csv("submission.csv", index=False )
<define_variables><EOS> 
!rm -r reader && rm install.sh