Kaggle competition: Humpback Whale Identification
<SOS> metric: MAP@{K} Kaggle data source: humpback-whale-identification<prepare_x_and_y>
%matplotlib inline
warnings.filterwarnings("ignore",category=DeprecationWarning )
config = tf.compat.v1.ConfigProto()
config.gpu_options.allow_growth = True
sess=tf.compat.v1.Session(graph=detection_graph, config=config)
 image_tensor = detection_graph.get_tensor_by_name('image_tensor:0')
 boxes_tensor = detection_graph.get_tensor_by_name('detection_boxes:0')
 scores_tensor = detection_graph.get_tensor_by_name('detection_scores:0')
 num_detections = detection_graph.get_tensor_by_name('num_detections:0' )<categorify>
train_df = pd.read_csv('.. /input/humpback-whale-identification/train.csv')
 sub = pd.read_csv('.. /input/humpback-whale-identification/sample_submission.csv')
 best_model_path = '.. /input/bbox-seresnext101-pytorch-hung96ad/best_model.pth'
TRN_IMGS_DIR = '.. /input/humpback-whale-identification/train/'
TST_IMGS_DIR = '.. /input/humpback-whale-identification/test/'
BBOX_TRAIN_CSV = '.. /input/box-whale/bounding/bounding_boxes_train.csv'
BBOX_TEST_CSV = '.. /input/box-whale/bounding/bounding_boxes_test.csv'
bbox_train = pd.read_csv(BBOX_TRAIN_CSV)
 bbox_test = pd.read_csv(BBOX_TEST_CSV)
 bbox_train = train_df.join(bbox_train.set_index('Image'), on='Image' )
def get_img(images):
global boxes,scores,num_detections
im_heights,im_widths=[],[]
imgs=[]
for image in images: 
(im_height,im_width)=image.shape[:-1]
imgs.append(image)
 im_heights.append(im_height)
 im_widths.append(im_widths)
 imgs=np.array(imgs)
(boxes, scores_)= sess.run(
 [boxes_tensor, scores_tensor],
feed_dict={image_tensor: imgs})
 finals=[]
for x in range(boxes.shape[0]):
scores=scores_[x]
max_=np.where(scores==scores.max())[0][0]
box=boxes[x][max_]
ymin, xmin, ymax, xmax = box 
(left, right, top, bottom)=(xmin * im_width, xmax * im_width,
ymin * im_height, ymax * im_height)
 left, right, top, bottom = int(left), int(right), int(top), int(bottom)
 image=imgs[x]
finals.append(cv2.cvtColor(cv2.resize(image[max([0,top-40]):bottom+80,max([0,left-40]):right+80],(240,240)) ,cv2.COLOR_BGR2RGB))
return finals
def detect_video(video):
frame_count=10
capture = cv2.VideoCapture(video)
 v_len = int(capture.get(cv2.CAP_PROP_FRAME_COUNT))
frame_idxs = np.linspace(0,v_len,frame_count, endpoint=False, dtype=np.int)
 imgs=[]
i=0
for frame_idx in range(int(v_len)) :
ret = capture.grab()
if not ret:
print("Error grabbing frame %d from movie %s" %(frame_idx, video))
if frame_idx >= frame_idxs[i]:
if frame_idx-frame_idxs[i]>20:
return None
ret, frame = capture.retrieve()
if not ret or frame is None:
print("Error retrieving frame %d from movie %s" %(frame_idx, video))
else:
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
 imgs.append(frame)
 i += 1
if i >= len(frame_idxs):
break
imgs=get_img(imgs)
 if len(imgs)<10:
return None
return np.hstack(imgs)
<train_model>
def prepare_labels(y):
values = np.array(y)
 label_encoder = LabelEncoder()
integer_encoded = label_encoder.fit_transform(values)
 onehot_encoder = OneHotEncoder(sparse=False)
 integer_encoded = integer_encoded.reshape(len(integer_encoded), 1)
 onehot_encoded = onehot_encoder.fit_transform(integer_encoded)
 y = onehot_encoded
return y, label_encoder
os.mkdir('./videos/')
 for x in tqdm(glob.glob('.. /input/deepfake-detection-challenge/test_videos/*.mp4')) :
try:
filename=x.replace('.. /input/deepfake-detection-challenge/test_videos/','' ).replace('.mp4','.jpg')
 a=detect_video(x)
 if a is None:
continue
cv2.imwrite('./videos/'+filename,a)
 except Exception as err:
print(err )<choose_model_class>
y, label_encoder = prepare_labels(train_df['Id'])
 NCLASSES = len(y[0] )
bottleneck = efn.EfficientNetB1(weights=None,include_top=False,pooling='avg')
 inp=Input(( 10,240,240,3))
x=TimeDistributed(bottleneck )(inp)
 x = LSTM(128 )(x)
 x = Dense(64, activation='elu' )(x)
 x = Dense(1,activation='sigmoid' )(x )<load_pretrained>
trn_trnsfms = transforms.Compose([
transforms.Resize(( 224, 224)) ,
transforms.RandomHorizontalFlip() ,
transforms.RandomVerticalFlip() ,
transforms.RandomAffine(degrees=30),
transforms.ToTensor() ,
transforms.Normalize(
 mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225] 
)
 ])
 tst_trnsfms = transforms.Compose([
transforms.Resize(( 224, 224)) ,
transforms.ToTensor() ,
transforms.Normalize(
 mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225] 
)
 ] )
model=Model(inp,x)
 model.load_weights('.. /input/dfdc-model3/model.h5')
 def get_birghtness(img):
return img/img.max()
def process_img(img,flip=False):
imgs=[]
for x in range(10):
if flip:
imgs.append(get_birghtness(cv2.flip(img[:,x*240:(x+1)*240,:],1)))
 else:
imgs.append(get_birghtness(img[:,x*240:(x+1)*240,:]))
return np.array(imgs )<load_from_csv>
class WhaleDataLoader(Dataset):
def __init__(self, image_folder, process='train', bbox=None, df=None, transform=None, y=None):
self.image_folder = image_folder
self.imgs_list = [img for img in os.listdir(image_folder)]
self.process = process
self.transform = transform
self.y = y
if self.process == 'train':
self.df = df.values
self.bbox = bbox.values
def __len__(self):
return len(self.imgs_list)
 def __getitem__(self, idx):
if self.process == 'train':
img_name = os.path.join(self.image_folder, self.df[idx][0])
 label = self.y[idx]
elif self.process == 'test':
img_name = os.path.join(self.image_folder, self.imgs_list[idx])
 label = np.zeros(( NCLASSES,))
img = Image.open(img_name ).convert('RGB')
 if self.process == 'train':
area =(self.bbox[idx][2], self.bbox[idx][3], self.bbox[idx][4], self.bbox[idx][5])
 elif self.process == 'test':
area =(self.bbox[idx][1], self.bbox[idx][2], self.bbox[idx][3], self.bbox[idx][4])
 img = img.crop(area)
 img = self.transform(img)
 if self.process == 'train':
return img, label
elif self.process == 'test':
return img, label, self.imgs_list[idx]
sample_submission = pd.read_csv(".. /input/deepfake-detection-challenge/sample_submission.csv")
 test_files=glob.glob('./videos/*.jpg')
 submission=pd.DataFrame()
submission['filename']=os.listdir(( '.. /input/deepfake-detection-challenge/test_videos/'))
submission['label']=0.5
filenames=[]
batch=[]
batch1=[]
preds=[]<define_variables>
train_dataloader = WhaleDataLoader(image_folder = TRN_IMGS_DIR, process='train', bbox=bbox_train, df=train_df, transform=trn_trnsfms, y=y)
 test_dataloader = WhaleDataLoader(image_folder = TST_IMGS_DIR, process='test', bbox=bbox_test,transform=tst_trnsfms )
new_preds=[]
for x in preds:
new_preds.append(x[0])
 print(sum(new_preds)/len(new_preds))<feature_engineering>
batch_size = 10
num_workers = 4
train_loader = DataLoader(train_dataloader, batch_size=batch_size, num_workers=num_workers, pin_memory=True, shuffle=True)
 test_loader = DataLoader(test_dataloader, batch_size=batch_size, num_workers=num_workers, pin_memory=True )
for x,y in zip(new_preds,filenames):
submission.loc[submission['filename']==y,'label']=min([max([0.1,x]),0.9] )<save_to_csv>

 pretrained_settings = {
'se_resnext101_32x4d': {
'imagenet': {
'url': 'http://data.lip6.fr/cadene/pretrainedmodels/se_resnext101_32x4d-3b2fe3d8.pth',
'input_space': 'RGB',
'input_size': [3, 224, 224],
'input_range': [0, 1],
'mean': [0.485, 0.456, 0.406],
'std': [0.229, 0.224, 0.225],
'num_classes': 1000
}
},
}
class SEModule(nn.Module):
def __init__(self, channels, reduction):
super(SEModule, self ).__init__()
self.avg_pool = nn.AdaptiveAvgPool2d(1)
 self.fc1 = nn.Conv2d(channels, channels // reduction, kernel_size=1,
padding=0)
 self.relu = nn.ReLU(inplace=True)
 self.fc2 = nn.Conv2d(channels // reduction, channels, kernel_size=1,
padding=0)
 self.sigmoid = nn.Sigmoid()
def forward(self, x):
module_input = x
x = self.avg_pool(x)
 x = self.fc1(x)
 x = self.relu(x)
 x = self.fc2(x)
 x = self.sigmoid(x)
 return module_input * x
class Bottleneck(nn.Module):

 def forward(self, x):
residual = x
out = self.conv1(x)
 out = self.bn1(out)
 out = self.relu(out)
 out = self.conv2(out)
 out = self.bn2(out)
 out = self.relu(out)
 out = self.conv3(out)
 out = self.bn3(out)
 if self.downsample is not None:
residual = self.downsample(x)
 out = self.se_module(out)+ residual
out = self.relu(out)
 return out
class SEBottleneck(Bottleneck):

 expansion = 4
def __init__(self, inplanes, planes, groups, reduction, stride=1,
downsample=None):
super(SEBottleneck, self ).__init__()
self.conv1 = nn.Conv2d(inplanes, planes * 2, kernel_size=1, bias=False)
 self.bn1 = nn.BatchNorm2d(planes * 2)
 self.conv2 = nn.Conv2d(planes * 2, planes * 4, kernel_size=3,
stride=stride, padding=1, groups=groups,
bias=False)
 self.bn2 = nn.BatchNorm2d(planes * 4)
 self.conv3 = nn.Conv2d(planes * 4, planes * 4, kernel_size=1,
bias=False)
 self.bn3 = nn.BatchNorm2d(planes * 4)
 self.relu = nn.ReLU(inplace=True)
 self.se_module = SEModule(planes * 4, reduction=reduction)
 self.downsample = downsample
self.stride = stride
class SEResNetBottleneck(Bottleneck):

 expansion = 4
def __init__(self, inplanes, planes, groups, reduction, stride=1,
downsample=None):
super(SEResNetBottleneck, self ).__init__()
self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=1, bias=False,
stride=stride)
 self.bn1 = nn.BatchNorm2d(planes)
 self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, padding=1,
groups=groups, bias=False)
 self.bn2 = nn.BatchNorm2d(planes)
 self.conv3 = nn.Conv2d(planes, planes * 4, kernel_size=1, bias=False)
 self.bn3 = nn.BatchNorm2d(planes * 4)
 self.relu = nn.ReLU(inplace=True)
 self.se_module = SEModule(planes * 4, reduction=reduction)
 self.downsample = downsample
self.stride = stride
class SEResNeXtBottleneck(Bottleneck):

 expansion = 4
def __init__(self, inplanes, planes, groups, reduction, stride=1,
downsample=None, base_width=4):
super(SEResNeXtBottleneck, self ).__init__()
width = math.floor(planes *(base_width / 64)) * groups
self.conv1 = nn.Conv2d(inplanes, width, kernel_size=1, bias=False,
stride=1)
 self.bn1 = nn.BatchNorm2d(width)
 self.conv2 = nn.Conv2d(width, width, kernel_size=3, stride=stride,
padding=1, groups=groups, bias=False)
 self.bn2 = nn.BatchNorm2d(width)
 self.conv3 = nn.Conv2d(width, planes * 4, kernel_size=1, bias=False)
 self.bn3 = nn.BatchNorm2d(planes * 4)
 self.relu = nn.ReLU(inplace=True)
 self.se_module = SEModule(planes * 4, reduction=reduction)
 self.downsample = downsample
self.stride = stride
class SENet(nn.Module):
def __init__(self, block, layers, groups, reduction, dropout_p=0.2,
inplanes=128, input_3x3=True, downsample_kernel_size=3,
downsample_padding=1, num_classes=1000):

 super(SENet, self ).__init__()
self.inplanes = inplanes
if input_3x3:
layer0_modules = [ 
('conv1', nn.Conv2d(3, 64, 3, stride=2, padding=1,
bias=False)) , 
('bn1', nn.BatchNorm2d(64)) , 
('relu1', nn.ReLU(inplace=True)) , 
('conv2', nn.Conv2d(64, 64, 3, stride=1, padding=1,
bias=False)) , 
('bn2', nn.BatchNorm2d(64)) , 
('relu2', nn.ReLU(inplace=True)) , 
('conv3', nn.Conv2d(64, inplanes, 3, stride=1, padding=1,
bias=False)) , 
('bn3', nn.BatchNorm2d(inplanes)) , 
('relu3', nn.ReLU(inplace=True)) ,
]
else:
layer0_modules = [ 
('conv1', nn.Conv2d(3, inplanes, kernel_size=7, stride=2,
padding=3, bias=False)) , 
('bn1', nn.BatchNorm2d(inplanes)) , 
('relu1', nn.ReLU(inplace=True)) ,
]
layer0_modules.append(( 'pool', nn.MaxPool2d(3, stride=2,
ceil_mode=True)))
 self.layer0 = nn.Sequential(OrderedDict(layer0_modules))
self.layer1 = self._make_layer(
 block,
planes=64,
blocks=layers[0],
groups=groups,
reduction=reduction,
downsample_kernel_size=1,
downsample_padding=0 
)
 self.layer2 = self._make_layer(
 block,
planes=128,
blocks=layers[1],
stride=2,
groups=groups,
reduction=reduction,
downsample_kernel_size=downsample_kernel_size,
downsample_padding=downsample_padding 
)
 self.layer3 = self._make_layer(
 block,
planes=256,
blocks=layers[2],
stride=2,
groups=groups,
reduction=reduction,
downsample_kernel_size=downsample_kernel_size,
downsample_padding=downsample_padding 
)
 self.layer4 = self._make_layer(
 block,
planes=512,
blocks=layers[3],
stride=2,
groups=groups,
reduction=reduction,
downsample_kernel_size=downsample_kernel_size,
downsample_padding=downsample_padding 
)
 self.avg_pool = nn.AvgPool2d(7, stride=1)
 self.dropout = nn.Dropout(dropout_p)if dropout_p is not None else None
self.last_linear = nn.Linear(512 * block.expansion, num_classes)
 def _make_layer(self, block, planes, blocks, groups, reduction, stride=1,
downsample_kernel_size=1, downsample_padding=0):
downsample = None
if stride != 1 or self.inplanes != planes * block.expansion:
downsample = nn.Sequential(
 nn.Conv2d(self.inplanes, planes * block.expansion,
kernel_size=downsample_kernel_size, stride=stride,
padding=downsample_padding, bias=False),
nn.BatchNorm2d(planes * block.expansion), 
)
 layers = []
layers.append(block(self.inplanes, planes, groups, reduction, stride,
downsample))
self.inplanes = planes * block.expansion
for i in range(1, blocks):
layers.append(block(self.inplanes, planes, groups, reduction))
return nn.Sequential(*layers)
 def features(self, x):
x = self.layer0(x)
 x = self.layer1(x)
 x = self.layer2(x)
 x = self.layer3(x)
 x = self.layer4(x)
 return x
def logits(self, x):
x = self.avg_pool(x)
 if self.dropout is not None:
x = self.dropout(x)
 x = x.view(x.size(0), -1)
 x = self.last_linear(x)
 return x
def forward(self, x):
x = self.features(x)
 x = self.logits(x)
 return x
def initialize_pretrained_model(model, num_classes, settings):
assert num_classes == settings['num_classes'], \
'num_classes should be {}, but is {}'.format(
 settings['num_classes'], num_classes)
 model.load_state_dict(model_zoo.load_url(settings['url']))
model.input_space = settings['input_space']
model.input_size = settings['input_size']
model.input_range = settings['input_range']
model.mean = settings['mean']
model.std = settings['std']
def se_resnext101(num_classes=1000, pretrained='imagenet'):
model = SENet(SEResNeXtBottleneck, [3, 4, 23, 3], groups=32, reduction=16,
dropout_p=None, inplanes=64, input_3x3=False,
downsample_kernel_size=1, downsample_padding=0,
num_classes=num_classes)
 if pretrained is not None:
settings = pretrained_settings['se_resnext101_32x4d'][pretrained]
initialize_pretrained_model(model, num_classes, settings)
 return model
def se_resnext101_pretrain(model, optimizer, pretrained='checkpoint.pth'):
checkpoint = torch.load(pretrained)
 start_epoch = checkpoint['epoch']
model.load_state_dict(checkpoint['state_dict'])
 optimizer.load_state_dict(checkpoint['optimizer'])
 return model, optimizer, start_epoch
def save_checkpoint(state, is_best, fpath='checkpoint.pth'):
torch.save(state, fpath)
 if is_best:
torch.save(state, 'best_model.pth' )
submission.to_csv('submission.csv', index=False)
 !rm -r videos<import_modules>
model = se_resnext101()
!pip install lap
Lambda, MaxPooling2D, Reshape
%matplotlib inline<load_from_csv>
model.last_linear = nn.Linear(model.last_linear.in_features, NCLASSES )
df = pd.read_csv('.. /input/humpback-whale-identification/train.csv')
 df.head()<load_from_csv>
model = model.cuda()
criterion = nn.BCEWithLogitsLoss()
optimizer = optim.Adam(model.parameters() , lr=0.0005 )
TRAIN_DF = '.. /input/humpback-whale-identification/train.csv'
SUB_Df = '.. /input/humpback-whale-identification/sample_submission.csv'
TRAIN = '.. /input/humpback-whale-identification/train/'
TEST = '.. /input/humpback-whale-identification/test/'
P2H = '.. /input/metadata/p2h.pickle'
P2SIZE = '.. /input/metadata/p2size.pickle'
BB_DF = ".. /input/metadata/bounding_boxes.csv"
tagged = dict([(p, w)for _, p, w in read_csv(TRAIN_DF ).to_records() ])
 submit = [p for _, p, _ in read_csv(SUB_Df ).to_records() ]
join = list(tagged.keys())+ submit<load_pretrained>
model, optimizer, start_epoch = se_resnext101_pretrain(model, optimizer, best_model_path )
def expand_path(p):
if isfile(TRAIN + p):
return TRAIN + p
if isfile(TEST + p):
return TEST + p
return p
if isfile(P2SIZE):
print("P2SIZE exists.")
 with open(P2SIZE, 'rb')as f:
p2size = pickle.load(f)
 else:
p2size = {}
for p in tqdm(join):
size = pil_image.open(expand_path(p)).size
p2size[p] = size<compute_test_metric>
scheduler = lr_scheduler.StepLR(optimizer, step_size=3, gamma=0.1 )
def match(h1, h2):
for p1 in h2ps[h1]:
for p2 in h2ps[h2]:
i1 = pil_image.open(expand_path(p1))
i2 = pil_image.open(expand_path(p2))
if i1.mode != i2.mode or i1.size != i2.size: return False
a1 = np.array(i1)
 a1 = a1 - a1.mean()
a1 = a1 / sqrt(( a1 ** 2 ).mean())
 a2 = np.array(i2)
 a2 = a2 - a2.mean()
a2 = a2 / sqrt(( a2 ** 2 ).mean())
 a =(( a1 - a2)** 2 ).mean()
if a > 0.1: return False
return True
if isfile(P2H):
print("P2H exists.")
 with open(P2H, 'rb')as f:
p2h = pickle.load(f)
 else:
p2h = {}
for p in tqdm(join):
img = pil_image.open(expand_path(p))
h = phash(img)
 p2h[p] = h
h2ps = {}
for p, h in p2h.items() :
if h not in h2ps: h2ps[h] = []
if p not in h2ps[h]: h2ps[h].append(p)
 hs = list(h2ps.keys())
 h2h = {}
for i, h1 in enumerate(tqdm(hs)) :
for h2 in hs[:i]:
if h1 - h2 <= 6 and match(h1, h2):
s1 = str(h1)
 s2 = str(h2)
 if s1 < s2: s1, s2 = s2, s1
h2h[s1] = s2
for p, h in p2h.items() :
h = str(h)
 if h in h2h: h = h2h[h]
p2h[p] = h
h2ps = {}
for p, h in p2h.items() :
if h not in h2ps: h2ps[h] = []
if p not in h2ps[h]: h2ps[h].append(p )<categorify>
n_epochs = 13
mean_losss = 99
is_best = False
for epoch in range(1, n_epochs+1):
train_loss = []
for batch_i,(data, target)in tqdm(enumerate(train_loader), total = len(train_loader)) :
data, target = data.cuda() , target.cuda()
optimizer.zero_grad()
output = model(data)
 loss = criterion(output, target.float())
 train_loss.append(loss.item())
 loss.backward()
optimizer.step()
scheduler.step()
if mean_losss > np.mean(train_loss):
is_best = True
mean_losss = np.mean(train_loss)
 else:
is_best = False
save_checkpoint({'epoch': epoch,
'state_dict': model.state_dict() ,
'optimizer' : optimizer.state_dict() ,
}, is_best)
 print(f'Epoch {epoch}, train loss: {np.mean(train_loss):.4f}' )
<set_options><EOS> 
model.eval()
for(data, target, name)in tqdm(test_loader):
data = data.cuda()
output = model(data)
 output = output.cpu().detach().numpy()
for i,(e, n)in enumerate(list(zip(output, name))):
sub.loc[sub['Image'] == n, 'Id'] = ' '.join(label_encoder.inverse_transform(e.argsort() [-5:][::-1]))
sub.to_csv('submission.csv', index=False )