Kaggle competition: Global Wheat Detection
<SOS> metric: custom metric Kaggle data source: global-wheat-detection<feature_engineering>
DIR_INPUT = '/kaggle/input'
DIR_TRAIN = f'{DIR_INPUT}/global-wheat-detection/train'
DIR_TEST = f'{DIR_INPUT}/global-wheat-detection/test'
data_augmentation = keras.models.Sequential([
keras.layers.experimental.preprocessing.Rescaling(1./255, input_shape=(28, 28, 1)) ,
keras.layers.experimental.preprocessing.RandomRotation(0.1),
keras.layers.experimental.preprocessing.RandomZoom(0.1),
keras.layers.experimental.preprocessing.RandomTranslation(0.1, 0.1)
 ] )<choose_model_class>
train_df = pd.read_csv(f'{DIR_INPUT}/global-wheat-detection/train.csv')
 train_df.shape
train_df['x'] = -1
train_df['y'] = -1
train_df['w'] = -1
train_df['h'] = -1
def expand_bbox(x):
r = np.array(re.findall("([0-9]+[.]?[0-9]*)", x))
if len(r)== 0:
r = [-1, -1, -1, -1]
return r
train_df[['x', 'y', 'w', 'h']] = np.stack(train_df['bbox'].apply(lambda x: expand_bbox(x)))
 train_df.drop(columns=['bbox'], inplace=True)
 train_df['x'] = train_df['x'].astype(np.float)
 train_df['y'] = train_df['y'].astype(np.float)
 train_df['w'] = train_df['w'].astype(np.float)
 train_df['h'] = train_df['h'].astype(np.float)
 image_ids = train_df['image_id'].unique()
valid_ids = image_ids[-1:]
train_ids = image_ids
valid_df = train_df[train_df['image_id'].isin(valid_ids)]
train_df = train_df[train_df['image_id'].isin(train_ids)]
DefaultConv2D = partial(keras.layers.Conv2D, kernel_size=3, activation='relu', padding='same')
 model = keras.models.Sequential([
data_augmentation,
DefaultConv2D(filters=32),
DefaultConv2D(filters=32),
keras.layers.MaxPool2D() ,
DefaultConv2D(filters=64),
DefaultConv2D(filters=64),
keras.layers.MaxPool2D() ,
DefaultConv2D(filters=128),
DefaultConv2D(filters=128),
keras.layers.MaxPool2D() ,
keras.layers.Dropout(0.2),
keras.layers.Flatten() ,
keras.layers.Dense(128, activation='relu'),
keras.layers.Dropout(0.5),
keras.layers.Dense(256, activation='relu'),
keras.layers.Dropout(0.5),
keras.layers.Dense(10, activation='softmax')
 ])
 model.compile(optimizer=keras.optimizers.Adam() ,
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
 n_epochs=20
lr_schedule = keras.callbacks.LearningRateScheduler(lambda epoch: 1e-6 * 10 **(epoch / n_epochs * 5))
history = model.fit(train_set, epochs=n_epochs, callbacks=[lr_schedule] )<choose_model_class>
def load_image(self, index):
image_id = self.image_ids[index]
imgpath = f'{DIR_INPUT}/global-wheat-detection/train'
img = cv2.imread(f'{imgpath}/{image_id}.jpg', cv2.IMREAD_COLOR)
 assert img is not None, 'Image Not Found ' + imgpath
h0, w0 = img.shape[:2]
return img,(h0, w0), img.shape[:2]
DefaultConv2D = partial(keras.layers.Conv2D, kernel_size=3, activation='relu', padding='same')
 model = keras.models.Sequential([
data_augmentation,
DefaultConv2D(filters=32),
DefaultConv2D(filters=32),
keras.layers.MaxPool2D() ,
DefaultConv2D(filters=64),
DefaultConv2D(filters=64),
keras.layers.MaxPool2D() ,
DefaultConv2D(filters=128),
DefaultConv2D(filters=128),
keras.layers.MaxPool2D() ,
keras.layers.Dropout(0.2),
keras.layers.Flatten() ,
keras.layers.Dense(128, activation='relu'),
keras.layers.Dropout(0.5),
keras.layers.Dense(256, activation='relu'),
keras.layers.Dropout(0.5),
keras.layers.Dense(10, activation='softmax')
 ])
 model.compile(optimizer=keras.optimizers.Adam(1e-3),
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
 n_epochs=200
history = model.fit(train_set,validation_data=val_set,
epochs=n_epochs,
callbacks=[keras.callbacks.EarlyStopping(patience=10, restore_best_weights=True),
keras.callbacks.ReduceLROnPlateau(patience=5, factor=0.5, min_lr=1e-4)] )<load_from_csv>
def load_mosaic(self, index):
labels4 = []
s = self.img_size
xc, yc = [int(random.uniform(s * 0.5, s * 1.5)) for _ in range(2)]
indices = [index] + [random.randint(0, len(self.labels)- 1)for _ in range(3)]
for i, index in enumerate(indices):
img, _,(h, w)= load_image(self, index)
 if i == 0:
img4 = np.full(( s * 2, s * 2, img.shape[2]), 114, dtype=np.uint8)
 x1a, y1a, x2a, y2a = max(xc - w, 0), max(yc - h, 0), xc, yc
x1b, y1b, x2b, y2b = w -(x2a - x1a), h -(y2a - y1a), w, h
elif i == 1:
x1a, y1a, x2a, y2a = xc, max(yc - h, 0), min(xc + w, s * 2), yc
x1b, y1b, x2b, y2b = 0, h -(y2a - y1a), min(w, x2a - x1a), h
elif i == 2:
x1a, y1a, x2a, y2a = max(xc - w, 0), yc, xc, min(s * 2, yc + h)
 x1b, y1b, x2b, y2b = w -(x2a - x1a), 0, max(xc, w), min(y2a - y1a, h)
 elif i == 3:
x1a, y1a, x2a, y2a = xc, yc, min(xc + w, s * 2), min(s * 2, yc + h)
 x1b, y1b, x2b, y2b = 0, 0, min(w, x2a - x1a), min(y2a - y1a, h)
 img4[y1a:y2a, x1a:x2a] = img[y1b:y2b, x1b:x2b]
padw = x1a - x1b
padh = y1a - y1b
x = self.labels[index]
labels = x.copy()
if x.size > 0:
labels[:, 1] = w *(x[:, 1] - x[:, 3] / 2)+ padw
labels[:, 2] = h *(x[:, 2] - x[:, 4] / 2)+ padh
labels[:, 3] = w *(x[:, 1] + x[:, 3] / 2)+ padw
labels[:, 4] = h *(x[:, 2] + x[:, 4] / 2)+ padh
labels4.append(labels)
 if len(labels4):
labels4 = np.concatenate(labels4, 0)
 np.clip(labels4[:, 1:], 0, 2 * s, out=labels4[:, 1:])
 img4, labels4 = random_affine(img4, labels4,
degrees=1.98 * 2,
translate=0.05 * 2,
scale=0.05 * 2,
shear=0.641 * 2,
border=-s // 2)
 return img4, labels4
with open("/kaggle/input/digit-recognizer/test.csv")as f:
reader = csv.reader(f, delimiter=',')
 next(reader)
 dataset = [row for row in reader]
test_imgs = np.array(dataset, dtype='float32' ).reshape(( len(dataset), 28, 28)) [..., np.newaxis]<prepare_output>
def augment_hsv(img, hgain=0.5, sgain=0.5, vgain=0.5):
r = np.random.uniform(-1, 1, 3)* [hgain, sgain, vgain] + 1
hue, sat, val = cv2.split(cv2.cvtColor(img, cv2.COLOR_BGR2HSV))
dtype = img.dtype
x = np.arange(0, 256, dtype=np.int16)
 lut_hue =(( x * r[0])% 180 ).astype(dtype)
 lut_sat = np.clip(x * r[1], 0, 255 ).astype(dtype)
 lut_val = np.clip(x * r[2], 0, 255 ).astype(dtype)
 img_hsv = cv2.merge(( cv2.LUT(hue, lut_hue), cv2.LUT(sat, lut_sat), cv2.LUT(val, lut_val)) ).astype(dtype)
 cv2.cvtColor(img_hsv, cv2.COLOR_HSV2BGR, dst=img )
predictions = [np.argmax(p)for p in model.predict(test_imgs)]
ids = np.arange(len(dataset)) + 1
submission_df = pd.DataFrame({'ImageId':ids, 'label':predictions})
 submission_df.head()<save_to_csv>
def letterbox(img, new_shape=(416, 416), color=(114, 114, 114), auto=True, scaleFill=False, scaleup=True):
shape = img.shape[:2]
if isinstance(new_shape, int):
new_shape =(new_shape, new_shape)
 r = min(new_shape[0] / shape[0], new_shape[1] / shape[1])
 if not scaleup:
r = min(r, 1.0)
 ratio = r, r
new_unpad = int(round(shape[1] * r)) , int(round(shape[0] * r))
dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1]
if auto:
dw, dh = np.mod(dw, 64), np.mod(dh, 64)
 elif scaleFill:
dw, dh = 0.0, 0.0
new_unpad = new_shape
ratio = new_shape[0] / shape[1], new_shape[1] / shape[0]
dw /= 2
dh /= 2
if shape[::-1] != new_unpad:
img = cv2.resize(img, new_unpad, interpolation=cv2.INTER_LINEAR)
 top, bottom = int(round(dh - 0.1)) , int(round(dh + 0.1))
left, right = int(round(dw - 0.1)) , int(round(dw + 0.1))
img = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color)
 return img, ratio,(dw, dh )
submission_df.to_csv("submission.csv", index=False )<set_options>
device = torch.device('cuda')if torch.cuda.is_available() else torch.device('cpu' )
plt.style.use('seaborn-white')
 sns.set_style("white")
 %matplotlib inline 
<define_variables>
def get_train_transform() :
return A.Compose([
ToTensorV2(p=1.0)
 ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})
 def get_valid_transform() :
return A.Compose([
ToTensorV2(p=1.0)
 ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})
 def collate_fn(batch):
return tuple(zip(*batch))
train_dataset = WheatDataset(train_df, DIR_TRAIN, get_train_transform())
 valid_dataset = WheatDataset(valid_df, DIR_TRAIN, get_valid_transform())
 indices = torch.randperm(len(train_dataset)).tolist()
train_data_loader = DataLoader(
 train_dataset,
batch_size=16,
shuffle=True,
num_workers=4,
collate_fn=collate_fn 
)
 valid_data_loader = DataLoader(
 valid_dataset,
batch_size=4,
shuffle=False,
num_workers=4,
collate_fn=collate_fn 
)
 fig, ax = plt.subplots(15, 1, figsize=(160, 80))
images, targets = next(iter(train_data_loader))
for i in range(15):
boxes = targets[i]
sample = images[i]
for box in boxes:
cv2.rectangle(sample, 
(int(box[1]), int(box[2])) , 
(int(box[3]), int(box[4])) ,
220, 3)
 ax[i].imshow(sample)
 plt.show()
img_size_ori = 101
img_size_target = 101
im_width = 101
im_height = 101
im_chan = 1
basicpath = '.. /input/'
path_train = basicpath + 'train/'
path_test = basicpath + 'test/'
path_train_images = path_train + 'images/'
path_train_masks = path_train + 'masks/'
path_test_images = path_test + 'images/' 
<load_from_csv>
WEIGHTS_FILE = '/kaggle/input/yoloaugment/yoloaug_transfer_crmaug_epoch_9.pth'
test_df = pd.read_csv(f'{DIR_INPUT}/global-wheat-detection/sample_submission.csv' )
train_df = pd.read_csv(".. /input/train.csv", index_col="id", usecols=[0])
 depths_df = pd.read_csv(".. /input/depths.csv", index_col="id")
 train_df = train_df.join(depths_df)
 test_df = depths_df[~depths_df.index.isin(train_df.index)]
len(train_df )<feature_engineering>
class WheatTestDataset(Dataset):
def __init__(self, dataframe, image_dir, transforms=None):
super().__init__()
self.image_ids = dataframe['image_id'].unique()
self.df = dataframe
self.image_dir = image_dir
self.transforms = transforms
def __getitem__(self, index: int):
image_id = self.image_ids[index]
records = self.df[self.df['image_id'] == image_id]
image = cv2.imread(f'{self.image_dir}/{image_id}.jpg', cv2.IMREAD_COLOR)
 image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB ).astype(np.float32)
 image /= 255.0
if self.transforms:
sample = {
'image': image,
}
sample = self.transforms(**sample)
 image = sample['image']
return image, image_id
def __len__(self)-> int:
return self.image_ids.shape[0]
train_df["images"] = [np.array(load_img(".. /input/train/images/{}.png".format(idx), grayscale=True)) / 255 for idx in tqdm_notebook(train_df.index)]<feature_engineering>
def get_test_transform() :
return A.Compose([
ToTensorV2(p=1.0)
 ] )
train_df["masks"] = [np.array(load_img(".. /input/train/masks/{}.png".format(idx), grayscale=True)) / 255 for idx in tqdm_notebook(train_df.index)]<categorify>
model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=False, pretrained_backbone=False)
 num_classes = 2
in_features = model.roi_heads.box_predictor.cls_score.in_features
model.roi_heads.box_predictor = FastRCNNPredictor(in_features, num_classes)
 model.load_state_dict(torch.load(WEIGHTS_FILE))
model.eval()
x = model.to(device )
train_df["coverage"] = train_df.masks.map(np.sum)/ pow(img_size_ori, 2)
 def cov_to_class(val):
for i in range(0, 11):
if val * 10 <= i :
return i
train_df["coverage_class"] = train_df.coverage.map(cov_to_class)
<split>
def collate_fn(batch):
return tuple(zip(*batch))
test_dataset = WheatTestDataset(test_df, DIR_TEST, get_test_transform())
 test_data_loader = DataLoader(
 test_dataset,
batch_size=4,
shuffle=False,
num_workers=4,
drop_last=False,
collate_fn=collate_fn 
)
 def format_prediction_string(boxes, scores):
pred_strings = []
for j in zip(scores, boxes):
pred_strings.append("{0:.4f} {1} {2} {3} {4}".format(j[0], j[1][0], j[1][1], j[1][2], j[1][3]))
return " ".join(pred_strings )
ids_train, ids_valid, x_train, x_valid, y_train, y_valid, cov_train, cov_test, depth_train, depth_test = train_test_split(
 train_df.index.values,
np.array(train_df.images.tolist() ).reshape(-1, img_size_target, img_size_target, 1),
np.array(train_df.masks.tolist() ).reshape(-1, img_size_target, img_size_target, 1),
train_df.coverage.values,
train_df.z.values,
test_size=0.2, stratify=train_df.coverage_class, random_state= 1234 )<define_search_model>
detection_threshold = 0.5
results = []
for images, image_ids in test_data_loader:
images = list(image.to(device)for image in images)
 outputs = model(images)
 for i, image in enumerate(images):
boxes = outputs[i]['boxes'].data.cpu().numpy()
scores = outputs[i]['scores'].data.cpu().numpy()
boxes = boxes[scores >= detection_threshold].astype(np.int32)
 scores = scores[scores >= detection_threshold]
image_id = image_ids[i]
boxes[:, 2] = boxes[:, 2] - boxes[:, 0]
boxes[:, 3] = boxes[:, 3] - boxes[:, 1]
result = {
'image_id': image_id,
'PredictionString': format_prediction_string(boxes, scores)
 }
results.append(result )
ACTIVATION = "prelu"
def convolution_block(x, filters, size, strides=(1,1), padding='same', activation=True, bn=True):
x = Conv2D(filters, size, strides=strides, padding=padding )(x)
 if bn == True:
x = BatchNormalization(momentum=0.95 )(x)
 if activation == True:
x = Activation(ACTIVATION )(x)
 return x
def residual_block(blockInput, num_filters=16):
x = BatchNormalization(momentum=0.95 )(blockInput)
 x = Activation(ACTIVATION )(x)
 x = convolution_block(x, num_filters,(3,3))
x = convolution_block(x, num_filters,(3,3), activation=False, bn=False)
 x = Add()([x, blockInput])
 return x 
<choose_model_class>
test_df = pd.DataFrame(results, columns=['image_id', 'PredictionString'])
 test_df.head()
<compute_train_metric><EOS> 
test_df.to_csv('submission.csv', index=False )