Kaggle competition: ALASKA2 Image Steganalysis
<SOS> metric: WeightedAUC Kaggle data source: alaska2-image-steganalysis<feature_engineering>
!pip install -q catalyst > /dev/null
!pip install -q lycon > /dev/null
!git clone https://github.com/NVIDIA/apex
!pip install -v --no-cache-dir --global-option="--cuda_ext"./apex/
!free -g
!nvidia-smi
test['release_month'] = test['release_month'].fillna(9.0)
 test['release_year'] = test['release_year'].fillna(2014.0)
 test['release_week'] = test['release_week'].fillna(36.0 )<data_type_conversions>
SEED = 42
EPS = 1e-8
REBUILD_16X16_DCT_SUMS = False
REBUILD_16X16_PXL_SUMS = False
REBUILD_JPEG_CACHE = False
def seed_everything(seed):
random.seed(seed)
 os.environ['PYTHONHASHSEED'] = str(seed)
 np.random.seed(seed)
 torch.manual_seed(seed)
 torch.cuda.manual_seed(seed)
 torch.backends.cudnn.deterministic = True
torch.backends.cudnn.benchmark = True
seed_everything(SEED )
train['bool_homepage'] =(train['homepage'].notnull() ).astype(int)
 test['bool_homepage'] =(test['homepage'].notnull() ).astype(int )<feature_engineering>
DATA_ROOT_PATH = '.. /input/alaska2-image-steganalysis'
train['production_companies_len'] = train['production_companies'].str.len()
test['production_companies_len'] = test['production_companies'].str.len()<feature_engineering>
def get_valid_transforms() :
return A.Compose([
A.Normalize(always_apply=True),
ToTensorV2(p=1.0),
], p=1.0 )
train['production_countries_len'] = train['production_countries'].str.len()
test['production_countries_len'] = test['production_countries'].str.len()<feature_engineering>

 GlobalParams = collections.namedtuple('GlobalParams', [
'batch_norm_momentum', 'batch_norm_epsilon', 'dropout_rate',
'num_classes', 'width_coefficient', 'depth_coefficient',
'depth_divisor', 'min_depth', 'drop_connect_rate', 'image_size'])
 BlockArgs = collections.namedtuple('BlockArgs', [
'kernel_size', 'num_repeat', 'input_filters', 'output_filters',
'expand_ratio', 'id_skip', 'stride', 'se_ratio'])
 GlobalParams.__new__.__defaults__ =(None,)* len(GlobalParams._fields)
 BlockArgs.__new__.__defaults__ =(None,)* len(BlockArgs._fields)
 class SwishImplementation(torch.autograd.Function):
@staticmethod
def forward(ctx, i):
result = i * torch.sigmoid(i)
 ctx.save_for_backward(i)
 return result
@staticmethod
def backward(ctx, grad_output):
i = ctx.saved_variables[0]
sigmoid_i = torch.sigmoid(i)
 return grad_output *(sigmoid_i *(1 + i *(1 - sigmoid_i)))
 class MemoryEfficientSwish(nn.Module):
def forward(self, x):
return SwishImplementation.apply(x)
 class Swish(nn.Module):
def forward(self, x):
return x * torch.sigmoid(x)
 def round_filters(filters, global_params):

 multiplier = global_params.width_coefficient
if not multiplier:
return filters
divisor = global_params.depth_divisor
min_depth = global_params.min_depth
filters *= multiplier
min_depth = min_depth or divisor
new_filters = max(min_depth, int(filters + divisor / 2)// divisor * divisor)
 if new_filters < 0.9 * filters:
new_filters += divisor
return int(new_filters)
 def round_repeats(repeats, global_params):

 multiplier = global_params.depth_coefficient
if not multiplier:
return repeats
return int(math.ceil(multiplier * repeats))
def drop_connect(inputs, p, training):

 if not training: return inputs
batch_size = inputs.shape[0]
keep_prob = 1 - p
random_tensor = keep_prob
random_tensor += torch.rand([batch_size, 1, 1, 1], dtype=inputs.dtype, device=inputs.device)
 binary_tensor = torch.floor(random_tensor)
 output = inputs / keep_prob * binary_tensor
return output
def get_same_padding_conv2d(image_size=None):

 if image_size is None:
return Conv2dDynamicSamePadding
else:
return partial(Conv2dStaticSamePadding, image_size=image_size)
 class Conv2dDynamicSamePadding(nn.Conv2d):

 def __init__(self, in_channels, out_channels, kernel_size, stride=1, dilation=1, groups=1, bias=True):
super().__init__(in_channels, out_channels, kernel_size, stride, 0, dilation, groups, bias)
 self.stride = self.stride if len(self.stride)== 2 else [self.stride[0]] * 2
def forward(self, x):
ih, iw = x.size() [-2:]
kh, kw = self.weight.size() [-2:]
sh, sw = self.stride
oh, ow = math.ceil(ih / sh), math.ceil(iw / sw)
 pad_h = max(( oh - 1)* self.stride[0] +(kh - 1)* self.dilation[0] + 1 - ih, 0)
 pad_w = max(( ow - 1)* self.stride[1] +(kw - 1)* self.dilation[1] + 1 - iw, 0)
 if pad_h > 0 or pad_w > 0:
x = F.pad(x, [pad_w // 2, pad_w - pad_w // 2, pad_h // 2, pad_h - pad_h // 2])
 return F.conv2d(x, self.weight, self.bias, self.stride, self.padding, self.dilation, self.groups)
 class Conv2dStaticSamePadding(nn.Conv2d):

 def __init__(self, in_channels, out_channels, kernel_size, image_size=None, **kwargs):
super().__init__(in_channels, out_channels, kernel_size, **kwargs)
 self.stride = self.stride if len(self.stride)== 2 else [self.stride[0]] * 2
assert image_size is not None
ih, iw = image_size if type(image_size)== list else [image_size, image_size]
kh, kw = self.weight.size() [-2:]
sh, sw = self.stride
oh, ow = math.ceil(ih / sh), math.ceil(iw / sw)
 pad_h = max(( oh - 1)* self.stride[0] +(kh - 1)* self.dilation[0] + 1 - ih, 0)
 pad_w = max(( ow - 1)* self.stride[1] +(kw - 1)* self.dilation[1] + 1 - iw, 0)
 if pad_h > 0 or pad_w > 0:
self.static_padding = nn.ZeroPad2d(( pad_w // 2, pad_w - pad_w // 2, pad_h // 2, pad_h - pad_h // 2))
else:
self.static_padding = Identity()
def forward(self, x):
x = self.static_padding(x)
 x = F.conv2d(x, self.weight, self.bias, self.stride, self.padding, self.dilation, self.groups)
 return x
class Identity(nn.Module):
def __init__(self,):
super(Identity, self ).__init__()
def forward(self, input):
return input
def efficientnet_params(model_name):

 params_dict = {
'efficientnet-b0':(1.0, 1.0, 224, 0.2),
'efficientnet-b1':(1.0, 1.1, 240, 0.2),
'efficientnet-b2':(1.1, 1.2, 260, 0.3),
'efficientnet-b3':(1.2, 1.4, 300, 0.3),
'efficientnet-b4':(1.4, 1.8, 380, 0.4),
'efficientnet-b5':(1.6, 2.2, 456, 0.4),
'efficientnet-b6':(1.8, 2.6, 528, 0.5),
'efficientnet-b7':(2.0, 3.1, 600, 0.5),
'efficientnet-b8':(2.2, 3.6, 672, 0.5),
'efficientnet-l2':(4.3, 5.3, 800, 0.5),
}
return params_dict[model_name]
class BlockDecoder(object):

 @staticmethod
def _decode_block_string(block_string):

 assert isinstance(block_string, str)
 ops = block_string.split('_')
 options = {}
for op in ops:
splits = re.split(r'(\d.*)', op)
 if len(splits)>= 2:
key, value = splits[:2]
options[key] = value
assert(( 's' in options and len(options['s'])== 1)or 
(len(options['s'])== 2 and options['s'][0] == options['s'][1]))
return BlockArgs(
 kernel_size=int(options['k']),
num_repeat=int(options['r']),
input_filters=int(options['i']),
output_filters=int(options['o']),
expand_ratio=int(options['e']),
id_skip=('noskip' not in block_string),
se_ratio=float(options['se'])if 'se' in options else None,
stride=[int(options['s'][0])])
 @staticmethod
def _encode_block_string(block):

 args = [
'r%d' % block.num_repeat,
'k%d' % block.kernel_size,
's%d%d' %(block.strides[0], block.strides[1]),
'e%s' % block.expand_ratio,
'i%d' % block.input_filters,
'o%d' % block.output_filters
]
if 0 < block.se_ratio <= 1:
args.append('se%s' % block.se_ratio)
 if block.id_skip is False:
args.append('noskip')
 return '_'.join(args)
 @staticmethod
def decode(string_list):

 assert isinstance(string_list, list)
 blocks_args = []
for block_string in string_list:
blocks_args.append(BlockDecoder._decode_block_string(block_string))
return blocks_args
@staticmethod
def encode(blocks_args):

 block_strings = []
for block in blocks_args:
block_strings.append(BlockDecoder._encode_block_string(block))
return block_strings
def efficientnet(width_coefficient=None, depth_coefficient=None, dropout_rate=0.2,
drop_connect_rate=0.2, image_size=None, num_classes=1000):

 blocks_args = [
'r1_k3_s11_e1_i32_o16_se0.25', 'r2_k3_s22_e6_i16_o24_se0.25',
'r2_k5_s22_e6_i24_o40_se0.25', 'r3_k3_s22_e6_i40_o80_se0.25',
'r3_k5_s11_e6_i80_o112_se0.25', 'r4_k5_s22_e6_i112_o192_se0.25',
'r1_k3_s11_e6_i192_o320_se0.25',
]
blocks_args = BlockDecoder.decode(blocks_args)
 global_params = GlobalParams(
 batch_norm_momentum=0.99,
batch_norm_epsilon=1e-3,
dropout_rate=dropout_rate,
drop_connect_rate=drop_connect_rate,
num_classes=num_classes,
width_coefficient=width_coefficient,
depth_coefficient=depth_coefficient,
depth_divisor=8,
min_depth=None,
image_size=image_size, 
)
 return blocks_args, global_params
def get_model_params(model_name, override_params):

 if model_name.startswith('efficientnet'):
w, d, s, p = efficientnet_params(model_name)
 blocks_args, global_params = efficientnet(
 width_coefficient=w, depth_coefficient=d, dropout_rate=p, image_size=s)
 else:
raise NotImplementedError('model name is not pre-defined: %s' % model_name)
 if override_params:
global_params = global_params._replace(**override_params)
 return blocks_args, global_params
url_map = {
'efficientnet-b0': '.. /input/noisy-student-efficientnet-b0.pth',
'efficientnet-b1': '.. /input/noisy-student-efficientnet-b1.pth',
'efficientnet-b2': '.. /input/noisy-student-efficientnet-b2.pth',
'efficientnet-b3': '.. /input/noisy-student-efficientnet-b3.pth',
'efficientnet-b4': '.. /input/noisy-student-efficientnet-b4.pth',
'efficientnet-b5': '.. /input/noisy-student-efficientnet-b5.pth',
'efficientnet-b6': '.. /input/noisy-student-efficientnet-b6.pth',
'efficientnet-b7': '.. /input/noisy-student-efficientnet-b7.pth',
}
url_map_advprop = {
'efficientnet-b0': 'https://github.com/lukemelas/EfficientNet-PyTorch/releases/download/1.0/adv-efficientnet-b0-b64d5a18.pth',
'efficientnet-b1': 'https://github.com/lukemelas/EfficientNet-PyTorch/releases/download/1.0/adv-efficientnet-b1-0f3ce85a.pth',
'efficientnet-b2': 'https://github.com/lukemelas/EfficientNet-PyTorch/releases/download/1.0/adv-efficientnet-b2-6e9d97e5.pth',
'efficientnet-b3': 'https://github.com/lukemelas/EfficientNet-PyTorch/releases/download/1.0/adv-efficientnet-b3-cdd7c0f4.pth',
'efficientnet-b4': 'https://github.com/lukemelas/EfficientNet-PyTorch/releases/download/1.0/adv-efficientnet-b4-44fb3a87.pth',
'efficientnet-b5': 'https://github.com/lukemelas/EfficientNet-PyTorch/releases/download/1.0/adv-efficientnet-b5-86493f6b.pth',
'efficientnet-b6': 'https://github.com/lukemelas/EfficientNet-PyTorch/releases/download/1.0/adv-efficientnet-b6-ac80338e.pth',
'efficientnet-b7': 'https://github.com/lukemelas/EfficientNet-PyTorch/releases/download/1.0/adv-efficientnet-b7-4652b6dd.pth',
'efficientnet-b8': 'https://github.com/lukemelas/EfficientNet-PyTorch/releases/download/1.0/adv-efficientnet-b8-22a8fe65.pth',
}
def load_pretrained_weights(model, model_name, load_fc=True, advprop=False):

 url_map_ = url_map_advprop if advprop else url_map
state_dict = torch.load(url_map_[model_name])
 if load_fc:
model.load_state_dict(state_dict)
 else:
state_dict.pop('_fc.weight')
 state_dict.pop('_fc.bias')
 res = model.load_state_dict(state_dict, strict=False)
 print(res)
 print('Loaded pretrained weights for {}'.format(model_name))
train['Keywords_len'] = train['Keywords'].str.len()
test['Keywords_len'] = test['Keywords'].str.len()<feature_engineering>
def DCT_Basis() :
N = 8
basis = []
for u in range(8):
for v in range(8):
z = np.zeros(( N,N))
for i in range(N):
for j in range(N):
z[i,j] = np.cos(np.pi*(2*i+1)*u /(2*N)) * np.cos(np.pi*(2*j+1)*v /(2*N))
basis.append(z)
 return torch.Tensor([basis,basis,basis] ).permute(( 1,0,2,3))
def gem(x, p=3, eps=1e-6):
x = x.double()
x = F.avg_pool2d(x.clamp(min=eps ).pow(p),(x.size(-2), x.size(-1)) ).pow(1./p)
 return x.half()
class GeM(nn.Module):
def __init__(self, p=3, eps=1e-6):
super(GeM,self ).__init__()
self.p = nn.Parameter(torch.ones(1)*p)
 self.eps = eps
def forward(self, x):
return gem(x, self.p, self.eps)
 def __repr__(self):
return self.__class__.__name__ + '(' + 'p=' + '{:.4f}'.format(self.p.data.tolist() [0])+ ', ' + 'eps=' + str(self.eps)+ ')'
class MBConvBlock(nn.Module):

 def __init__(self, block_args, global_params):
super().__init__()
self._block_args = block_args
self._bn_mom = 1 - global_params.batch_norm_momentum
self._bn_eps = global_params.batch_norm_epsilon
self.has_se =(self._block_args.se_ratio is not None)and(0 < self._block_args.se_ratio <= 1)
 self.id_skip = block_args.id_skip
Conv2d = get_same_padding_conv2d(image_size=global_params.image_size)
 inp = self._block_args.input_filters
oup = self._block_args.input_filters * self._block_args.expand_ratio
if self._block_args.expand_ratio != 1:
self._expand_conv = Conv2d(in_channels=inp, out_channels=oup, kernel_size=1, bias=False)
 self._bn0 = nn.BatchNorm2d(num_features=oup, momentum=self._bn_mom, eps=self._bn_eps)
 k = self._block_args.kernel_size
s = self._block_args.stride
self._depthwise_conv = Conv2d(
 in_channels=oup, out_channels=oup, groups=oup,
kernel_size=k, stride=s, bias=False)
 self._bn1 = nn.BatchNorm2d(num_features=oup, momentum=self._bn_mom, eps=self._bn_eps)
 if self.has_se:
num_squeezed_channels = max(1, int(self._block_args.input_filters * self._block_args.se_ratio))
self._se_reduce = Conv2d(in_channels=oup, out_channels=num_squeezed_channels, kernel_size=1)
 self._se_expand = Conv2d(in_channels=num_squeezed_channels, out_channels=oup, kernel_size=1)
 final_oup = self._block_args.output_filters
self._project_conv = Conv2d(in_channels=oup, out_channels=final_oup, kernel_size=1, bias=False)
 self._bn2 = nn.BatchNorm2d(num_features=final_oup, momentum=self._bn_mom, eps=self._bn_eps)
 self._swish = MemoryEfficientSwish()
def set_trainable(self, trainable):
self._expand_conv.requires_grad_(trainable)
 self._bn0.requires_grad_(trainable)
 self._depthwise_conv.requires_grad_(trainable)
 self._bn1.requires_grad_(trainable)
 self._se_reduce.requires_grad_(trainable)
 self._se_expand.requires_grad_(trainable)
 self._project_conv.requires_grad_(trainable)
 self._bn2.requires_grad_(trainable)
 def forward(self, inputs, drop_connect_rate=None):

 x = inputs
if self._block_args.expand_ratio != 1:
x = self._swish(self._bn0(self._expand_conv(inputs)))
 x = self._swish(self._bn1(self._depthwise_conv(x)))
 if self.has_se:
x_squeezed = F.adaptive_avg_pool2d(x, 1)
 x_squeezed = self._se_expand(self._swish(self._se_reduce(x_squeezed)))
 x = torch.sigmoid(x_squeezed)* x
x = self._bn2(self._project_conv(x))
input_filters, output_filters = self._block_args.input_filters, self._block_args.output_filters
if self.id_skip and self._block_args.stride == 1 and input_filters == output_filters:
if drop_connect_rate:
x = drop_connect(x, p=drop_connect_rate, training=self.training)
 x = x + inputs
return x
def set_swish(self, memory_efficient=True):

 self._swish = MemoryEfficientSwish() if memory_efficient else Swish()
class EfficientNet(nn.Module):

 def __init__(self, blocks_args=None, global_params=None):
super().__init__()
assert isinstance(blocks_args, list), 'blocks_args should be a list'
assert len(blocks_args)> 0, 'block args must be greater than 0'
self._global_params = global_params
self._blocks_args = blocks_args
Conv2d = get_same_padding_conv2d(image_size=global_params.image_size)
 bn_mom = 1 - self._global_params.batch_norm_momentum
bn_eps = self._global_params.batch_norm_epsilon
in_channels = 3
out_channels = round_filters(32, self._global_params)
 self._conv_stem = Conv2d(in_channels, out_channels, kernel_size=3, stride=2, bias=False)
 self._bn0 = nn.BatchNorm2d(num_features=out_channels, momentum=bn_mom, eps=bn_eps)
 self._blocks = nn.ModuleList([])
 for block_args in self._blocks_args:
block_args = block_args._replace(
 input_filters=round_filters(block_args.input_filters, self._global_params),
output_filters=round_filters(block_args.output_filters, self._global_params),
num_repeat=round_repeats(block_args.num_repeat, self._global_params)
)
 self._blocks.append(MBConvBlock(block_args, self._global_params))
if block_args.num_repeat > 1:
block_args = block_args._replace(input_filters=block_args.output_filters, stride=1)
 for _ in range(block_args.num_repeat - 1):
self._blocks.append(MBConvBlock(block_args, self._global_params))
in_channels = block_args.output_filters
out_channels = round_filters(1280, self._global_params)
 self._conv_head = Conv2d(in_channels, out_channels, kernel_size=1, bias=False)
 self._bn1 = nn.BatchNorm2d(num_features=out_channels, momentum=bn_mom, eps=bn_eps)
 self._pxls = nn.Conv2d(out_channels, 1, 1)
 self._dropout = nn.Dropout(self._global_params.dropout_rate)
 self._fc = nn.Linear(out_channels, self._global_params.num_classes)
 self._fc_aux = nn.Linear(out_channels, 2)
 self._swish = MemoryEfficientSwish()
def set_swish(self, memory_efficient=True):

 self._swish = MemoryEfficientSwish() if memory_efficient else Swish()
for block in self._blocks:
block.set_swish(memory_efficient)
 def extract_features(self, inputs):

 x = self._swish(self._bn0(self._conv_stem(inputs)))
 for idx, block in enumerate(self._blocks):
drop_connect_rate = self._global_params.drop_connect_rate
if drop_connect_rate:
drop_connect_rate *= float(idx)/ len(self._blocks)
 x = block(x, drop_connect_rate=drop_connect_rate)
 x = self._swish(self._bn1(self._conv_head(x)))
 return x
def forward(self, inputs):

 bs = inputs.size(0)
 x = self.extract_features(inputs)
 pxls = self._pxls(x)
 x = F.adaptive_avg_pool2d(x, 1)
 x = x.view(bs, -1)
 x = self._dropout(x)
 aux = self._fc_aux(x)
 x = self._fc(x)
 return x, aux, pxls
@classmethod
def from_name(cls, model_name, override_params=None):
cls._check_model_name_is_valid(model_name)
 blocks_args, global_params = get_model_params(model_name, override_params)
 return cls(blocks_args, global_params)
 @classmethod
def from_pretrained(cls, model_name, advprop=False, num_classes=1000, in_channels=3):
model = cls.from_name(model_name, override_params={'num_classes': num_classes})
 load_pretrained_weights(model, model_name, load_fc=(num_classes == 1000), advprop=advprop)
 if in_channels != 3:
Conv2d = get_same_padding_conv2d(image_size = model._global_params.image_size)
 out_channels = round_filters(32, model._global_params)
 model._conv_stem = Conv2d(in_channels, out_channels, kernel_size=3, stride=2, bias=False)
 return model
@classmethod
def get_image_size(cls, model_name):
cls._check_model_name_is_valid(model_name)
 _, _, res, _ = efficientnet_params(model_name)
 return res
@classmethod
def _check_model_name_is_valid(cls, model_name):

 valid_models = ['efficientnet-b'+str(i)for i in range(9)]
if model_name not in valid_models:
raise ValueError('model_name should be one of: ' + ', '.join(valid_models))
train['title_len'] = train['title'].str.len()
test['title_len'] = test['title'].str.len()<feature_engineering>
checkpoint = torch.load('.. /input/alaska25/best-checkpoint-040epoch.bin')['model_state_dict']
for key in list(checkpoint.keys()):
nkey = key[len('module.'):]
checkpoint[nkey] = checkpoint[key]
del checkpoint[key]
train['genres_len'] = train['genres'].str.len()
test['genres_len'] = test['genres'].str.len()<feature_engineering>
net.load_state_dict(checkpoint)
 net.eval()
net = net.cuda()
net = amp.initialize(net, opt_level='O1')
 net = torch.nn.DataParallel(net, device_ids=[0] )
train['cast_crew_len'] = train['cast'].str.len() + train['crew'].str.len()
test['cast_crew_len'] = test['cast'].str.len() + test['crew'].str.len()<feature_engineering>
def get_test_transforms(mode):
if mode == 0:
return A.Compose([
A.Normalize(always_apply=True),
ToTensorV2(p=1.0),
], p=1.0)
 elif mode == 1:
return A.Compose([
A.HorizontalFlip(p=1),
A.Normalize(always_apply=True),
ToTensorV2(p=1.0),
], p=1.0)
 elif mode == 2:
return A.Compose([
A.VerticalFlip(p=1),
A.Normalize(always_apply=True),
ToTensorV2(p=1.0),
], p=1.0)
 elif mode == 3:
return A.Compose([
A.InvertImg(p=1),
A.Normalize(always_apply=True),
ToTensorV2(p=1.0),
], p=1.0)
 else:
return A.Compose([
A.HorizontalFlip(p=1),
A.VerticalFlip(p=1),
A.Normalize(always_apply=True),
ToTensorV2(p=1.0),
], p=1.0 )
train.loc[(train['release_year']>2019),'release_year']=train['release_year'].median()<feature_engineering>
class DatasetSubmissionRetriever(Dataset):
def __init__(self, kinds, image_names, transforms=None):
super().__init__()
self.kinds = kinds
self.image_names = image_names
self.transforms = transforms
def __getitem__(self, index: int):
image_name = self.image_names[index]
image_kind = self.kinds[index]
image = lycon.load(f'{DATA_ROOT_PATH}/{image_kind}/{image_name}')
 if self.transforms:
sample = {'image': image}
sample = self.transforms(**sample)
 image = sample['image']
return image_name, image
def __len__(self)-> int:
return self.image_names.shape[0]
train['month_into_year'] = train['release_month']*train['release_year']<feature_engineering>
del data_loader
del images
gc.collect()
torch.cuda.empty_cache()
!nvidia-smi
test.loc[(test['release_year']>2019),'release_year']=test['release_year'].median()<data_type_conversions>
torch.cuda.empty_cache()
vcast_crew_len = test['cast_crew_len'].median()
test['cast_crew_len'].fillna(vcast_crew_len, inplace=True)
 test['runtime'].fillna(test['runtime'].median() ,inplace=True)
 test['release_month'].fillna(test['release_month'].median() ,inplace=True)
 test['title_len'].fillna(test['title_len'].median() ,inplace=True)
 test['release_year'].fillna(test['release_year'].median() ,inplace=True)
 test['release_day_of_week'].fillna(test['release_day_of_week'].median() ,inplace=True)
 test['release_dayofyear'].fillna(test['release_dayofyear'].median() ,inplace=True)
 test['genres_len'].fillna(test['genres_len'].median() ,inplace=True)
 test['production_companies_len'].fillna(test['production_companies_len'].median() ,inplace=True)
 test['production_countries_len'].fillna(test['production_countries_len'].median() ,inplace=True)
 test['Keywords_len'].fillna(test['Keywords_len'].median() ,inplace=True )<feature_engineering>
results = []
test_imgs = glob('.. /input/alaska2-image-steganalysis/Test/*.jpg')
 for mode in range(0, 5):
dataset = DatasetSubmissionRetriever(
 image_names=np.array([path.split('/')[-1] for path in test_imgs]),
kinds=['Test']*len(test_imgs),
transforms=get_test_transforms(mode), 
)
 data_loader = DataLoader(
 dataset,
batch_size=26,
shuffle=False,
num_workers=4,
drop_last=False, 
)
 result = {'Id': [], 'Label': []}
for step,(image_names, images)in enumerate(data_loader):
torch.cuda.empty_cache()
print(step, end='\r')
 y_pred = net(images.cuda())[0]
y_pred = 1 - nn.functional.softmax(y_pred, dim=1 ).data.cpu().numpy() [:,0]
result['Id'].extend(image_names)
 result['Label'].extend(y_pred)
 results.append(result)
 print('done with mode', mode )
test['month_into_year'] = test['release_month']*test['release_year']<define_variables>
submissions = []
for mode in range(0,5):
submission = pd.DataFrame(results[mode])
 submissions.append(submission)
 submissions[mode].to_csv(f'submission_{mode}.csv', index=False )
<feature_engineering><EOS> 
submissions[0]['Label'] =(
 submissions[0]['Label'] /3 +
submissions[1]['Label'] /6 +
submissions[2]['Label'] /6 +
submissions[4]['Label'] /6 +
submissions[3]['Label'] /12 
)
 submissions[0].to_csv(f'submission.csv', index=False)
 submissions[0]['Label'].hist(bins=100)
 plt.show()
submissions[0].head()