一、竞赛相关
竞赛phase1
竞赛phase2
phase1的计分板是根据val_data来评估的,而phase2的计分板才是根据test_data来评估的
二、成绩
phase1:
phase2:
三、一些感想
- 策略:修改baseline,力争高分
问题与解决策略
1 训练数据集存在数据偏移的情况,真实人脸图像[label = 0]数据较少。
采用的策略:对真实人脸图像[label = 0]数据进行拷贝,并对拷贝的相同数据进行不同程度的数据增强。
- baseline中的数据集处理
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)
- 我修改的数据集处理
class BalancedFFDIDataset(Dataset):
def __init__(self, img_path, img_label, transform=None, new_transform=None):
self.img_path = img_path
self.img_label = img_label
if transform is not None:
self.transform = transform
else:
self.transform = None
if new_transform is not None:
self.new_transform = new_transform
else:
self.new_transform = None
self.common_transform = transforms.Compose([transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])])
# Separate majority and minority class samples
self.minority_img_path = [img_path[i] for i in range(len(img_path)) if img_label[i] == 0]
self.minority_img_label = [img_label[i] for i in range(len(img_label)) if img_label[i] == 0]
self.majority_img_path = [img_path[i] for i in range(len(img_path)) if img_label[i] == 1]
self.majority_img_label = [img_label[i] for i in range(len(img_label)) if img_label[i] == 1]
# Augment the minority class
self.extended_img_path = self.majority_img_path.copy()
self.extended_img_label = self.majority_img_label.copy()
for img_path, img_label in zip(self.minority_img_path, self.minority_img_label):
if self.new_transform is not None:
for _ in range(4): # Increase minority samples by a factor of 4
self.extended_img_path.append(img_path)
self.extended_img_label.append(img_label)
combined = list(zip(self.extended_img_path, self.extended_img_label))
random.shuffle(combined)
self.extended_img_path, self.extended_img_label = zip(*combined)
def __getitem__(self, index):
img = Image.open(self.extended_img_path[index]).convert('RGB')
label = self.extended_img_label[index]
if self.transform is not None:
img = self.transform(img)
if label == 0 and self.new_transform is not None:
img = self.new_transform(img)
#return (img, torch.from_numpy(np.array(label))), (img_new, torch.from_numpy(np.array(label)))
img = self.common_transform(img)
return img, torch.from_numpy(np.array(label))
def __len__(self):
return len(self.extended_img_path)
- 测试结果
[前10000数据上进行测试,记录loss和acc的曲线如下]
相比baseline有较大提升,baseline在这里。此处不特意挂出baseline的结果了,感兴趣的读者可以自行复现。
2 augmentation测试
根据1中所述,故比赛期间我将augmentation着重放在了label0的样本上。现在总结一下我的一些尝试和submission中采用的augmentation。[其实是因为测试的augmentation的效果都很差,所以咳咳,submission的augmentation就…]
2(1) 随机噪声 - 由于官方baseline中没有涉及噪声的augmentation,故给出我自己的使用的噪声添加函数。
class RandomAddNoise(object):
def __init__(self, noise_factor=0.1, p=0.5):
self.noise_factor = noise_factor
self.p = p
def __call__(self, input_image):
if random.random() < self.p:
inputs = transforms.ToTensor()(input_image)
noise = inputs + torch.rand_like(inputs) * self.noise_factor
noise = torch.clip(noise, 0, 1.)
output_image = transforms.ToPILImage()(noise)
return output_image
return input_image
- 测试结果
[前10000数据上进行测试,记录loss和acc的曲线如下]
此处采用的参数为RandomAddNoise(0.1, 0.5)
[全局数据上进行测试,记录loss和acc的曲线如下]
此处采用的参数为RandomAddNoise(0.01, 0.5)
2(2) pytorch库中自带的augmentation策略:
以下为测试过的augmentation策略:
transforms.ColorJitter(brightness=0.5)
transforms.RandomRotation(10)
transforms.RandomHorizontalFlip()
transforms.RandomVerticalFlip()
loss和acc的图找不到了,但是最终这些augmentation都没有被我采用,原因就是在val_data上测试下来效果不太好。[最后我才知道,valid中的deepfake生成方法和test中的deepfake生成方法不太一致,valid的生成方法单一,和train的生成方法一致,而test涵盖的内容更加全面。所以这些操作可能在test上的表现可能是好的,但是由于test数据集发出后我没时间了,所以没有测。欢迎感兴趣的读者自测后告诉我结果。]
3 模型选择
baseline使用的是resnet18,但是效果一般。在竞赛群里群众的讨论下,采用了efficientnet-b1。我也采用过更大的模型,但是考虑到我自己没有本地算力,而kaggle免费算力的内存较小,故最终的submission中也是只使用了efficientnet-b1。
四、如果时间充裕,还想做的操作
1 在phase2,碰巧看了一下数据集的构成,发现数据集中包含很多mask的样本,如下图所示:
所以,如果时间充裕,我会尝试随机mask的augmentation,我估计acc可以更上一层楼。
2 选用参数更多的模型
如上述,由于没有本地算力,所以我选择了参数量较少的模型,如果选择参数量更多一些的模型,感觉可能可以更好。
3 尝试更多的augmentation策略
cutmix&mixup,具体详见这里