Kaggle competition: Abstraction and Reasoning Challenge
<SOS> metric: MeanBestErrorAtK Kaggle data source: abstraction-and-reasoning-challenge<train_model>
import numpy as np
import pandas as pd
from tqdm import tqdm
History = model.fit(train, labels,
batch_size = BATCH_SIZE,
epochs = 100,
verbose = 1 )<prepare_output>
def load_data(path):
tasks = pd.Series()
for file_path in os.listdir(path):
task_file = path_join(path, file_path)
 with open(task_file, 'r')as f:
task = json.load(f)
 tasks[file_path[:-5]] = task
return tasks
results = model.predict(SUBMIT)
 results = np.argmax(results,axis = 1)
 data_out = pd.DataFrame({'id': range(len(SUBMIT)) , 'label': results} )<save_to_csv>
train_tasks = load_data('.. /input/abstraction-and-reasoning-challenge/training/')
 evaluation_tasks = load_data('.. /input/abstraction-and-reasoning-challenge/evaluation/')
 test_tasks = load_data('.. /input/abstraction-and-reasoning-challenge/test/')
 train_tasks.head()
data_out.to_csv('submission.csv', index = None )<set_options>
class CAModel(nn.Module):
def __init__(self, num_states):
super(CAModel, self ).__init__()
self.simple_conv = nn.Sequential(
 nn.Conv2d(num_states, 32, kernel_size=3, padding=1),
nn.ReLU() 
)
 self.conv1 = nn.Conv2d(32, num_states, kernel_size=1)
 self.conv2 = nn.Conv2d(32, num_states+1, kernel_size=1)
 self.conv3 = nn.Conv2d(32, 1, kernel_size=1)
 self.conv4 = nn.Conv2d(32, 1, kernel_size=1)
 self.conv5 = nn.Conv2d(32, 1, kernel_size=1)
 self.soft = nn.Softmax(dim=1)
 def forward(self, x, steps = 1):
for step in range(steps):
x = self.simple_conv(x)
 y1 = self.conv1(x)
 y2 = self.conv2(x)
 y3 = self.conv3(x)
 y3 = torch.flatten(y3, start_dim=1)
 y3 = self.soft(y3)
 y4 = self.conv4(x)
 y4 = torch.flatten(y4, start_dim=1)
 y4 = self.soft(y4)
 y5 = self.conv5(x)
 y5 = torch.flatten(y5, start_dim=1)
 y5 = self.soft(y5)
 x = self.soft(y1)
 return y1, y2, y3, y4, y5
%reload_ext autoreload
%autoreload 2
%matplotlib inline<import_modules>
def get_matching_shapes_helper(img, template):
matches = []
for i in range(img.shape[0]-3):
for j in range(img.shape[1]-3):
match = True
for ti in range(3):
for tj in range(3):
if img[i+ti,j+tj] != template[ti,tj]:
match = False
if match:
matches.append(( i,j))
print(matches)
 def get_matching_shapes(inp):
inp = np.array(inp)
 print(inp.shape)
 for j in range(inp.shape[1]-3):
for i in range(inp.shape[0]-3):
template = np.zeros(( 3,3))
template = inp[i:i+3,j:j+3]
if np.sum(template)!= 0:
plot_pictures([inp, template],['inp', 'template'])
 get_matching_shapes_helper(inp, template)
 def generate_copies_to_right(inp_img, object_coords, anchor_coords, spacing=1):
inp_img = np.array(inp_img)
 img_xlen = inp_img.shape[0]
img_ylen = inp_img.shape[1]
object_left_x = object_coords[0]%img_ylen
object_up_y = object_coords[0]//img_ylen
object_rite_x = object_coords[1]%img_ylen
object_low_y = object_coords[1]//img_ylen
object_width = object_rite_x - object_left_x
object_height = object_up_y - object_low_y
anchor_x = anchor_coords%img_ylen
anchor_y = anchor_coords//img_ylen
object_img = inp_img[object_left_x:object_rite_x,object_low_y:object_up_y]
if object_width <= 0 or object_height <= 0:
return inp_img
elif anchor_x+object_width > img_xlen or anchor_y+object_height > img_ylen:
return inp_img
elif object_left_x < 0 or object_rite_x > img_xlen or object_low_y < 0 or object_up_y > img_ylen:
return inp_img
for i in range(img_xlen):
for j in range(img_ylen):
if i == anchor_x and j == anchor_y:
for ti in range(object_width):
for tj in range(object_height):
copy_value = object_img[ti,tj]
inp_img[i+ti,j+tj]= copy_value
return inp_img
def my_weird_loss(trg_img, copy_img):
trg_img = np.array(trg_img)
 loss = 0
for i in range(trg_img.shape[0]):
for j in range(trg_img.shape[1]):
if trg_img[i,j] != copy_img[i,j]:
loss += -1
return loss
from fastai import *
from fastai.vision import *
import imageio<load_from_csv>
get_matching_shapes(sample_out )
path = Path('.. /input/Kannada-MNIST')
 train = pd.read_csv('.. /input/Kannada-MNIST/train.csv')
 test = pd.read_csv('.. /input/Kannada-MNIST/test.csv' )<train_model>
def inp2img(inp):
inp = np.array(inp)
 img = np.full(( 10, inp.shape[0], inp.shape[1]), 0, dtype=np.uint8)
 for i in range(10):
img[i] =(inp==i)
 return img
def target_maker(samin, samout):
target = np.full(( len(samin), len(samin[0])) , 0, dtype=np.uint8)
 for i in range(len(samin)) :
for j in range(len(samin[0])) :
if samin[i][j]==samout[i][j]:
target[i,j] = 10
else:
target[i,j] = samout[i][j]
return target
def pred_maker(inp, pred, pred_grade):
inp = np.asarray(inp)
 final_pred = np.full(( inp.shape[0], inp.shape[1]), 0, dtype=np.uint8)
 grade_avg = np.mean(pred_grade)
 threshold = 0.66
for i in range(pred.shape[0]):
for j in range(pred.shape[1]):
if pred[i,j] == 10 or pred_grade[i, j]/grade_avg < threshold:
final_pred[i,j] = inp[i,j]
else:
final_pred[i,j] = pred[i,j]
return final_pred
class TaskSolver:
def train(self, task_train, n_epoch=200, max_steps=2):

 self.net = CAModel(10)
 criterion = CrossEntropyLoss()
optimizer = Adam(self.net.parameters() , lr = 0.01)
 for epoch in range(n_epoch):
optimizer.zero_grad()
for sample in task_train:
target = target_maker(sample['input'],sample['output'])
 inputs = FloatTensor(inp2img(sample['input'])).unsqueeze(dim=0)
 labels1 = LongTensor(sample['output'] ).unsqueeze(dim=0)
 labels2 = LongTensor(target ).unsqueeze(dim=0)
 outputs1 = self.net(inputs)[0]
outputs2 = self.net(inputs)[1]
loss = criterion(outputs1, labels1)
 loss.backward()
loss = criterion(outputs2, labels2)
 loss.backward()
object_upl = self.net(inputs)[2]
object_upleft = object_upl.squeeze(dim=0 ).cpu().detach().numpy().argmax(0)
 object_lowr = self.net(inputs)[3]
object_lowrite = object_lowr.squeeze(dim=0 ).cpu().detach().numpy().argmax(0)
 anchor_point = self.net(inputs)[4]
anchor_point = anchor_point.squeeze(dim=0 ).cpu().detach().numpy().argmax(0)
 object_coords =(object_upleft, object_lowrite)
 copied_object_img = generate_copies_to_right(sample['input'], object_coords, anchor_point)
 loss = my_weird_loss(sample['output'],copied_object_img)*torch.mean(object_upl)
 loss.backward()
optimizer.step()
plot_pictures([sample['input'], sample['output'], copied_object_img ], ['Input', 'Label', 'Copies'])
 return self
def predict(self, task_test):
predictions = []
pred_grades = []
with torch.no_grad() :
for sample in task_test:
inputs = FloatTensor(inp2img(sample['input'])).unsqueeze(dim=0)
 outputs = self.net(inputs)[0]
pred = outputs.squeeze(dim=0 ).cpu().numpy().argmax(0)
 final_pred = pred
predictions.append(final_pred)
 return predictions
def to_img_shape(data_X, data_y=[]):
data_X = np.array(data_X ).reshape(-1,28,28)
 data_X = np.stack(( data_X,)*3, axis=-1)
 data_y = np.array(data_y)
 return data_X,data_y<split>
def input_output_shape_is_same(task):
return all([np.array(el['input'] ).shape == np.array(el['output'] ).shape for el in task['train']])
 def calk_score(task_test, predict):
return [int(np.equal(sample['output'], pred ).all())for sample, pred in zip(task_test, predict)]
data_X, data_y = train.loc[:,'pixel0':'pixel783'], train['label']
train_X, val_X, train_y, val_y = train_test_split(data_X, data_y, test_size=0.1,random_state=42,stratify=data_y)
 test_X = test.loc[:,'pixel0':'pixel783']<categorify>
def evaluate(tasks):
ts = TaskSolver()
result = []
predictions = []
for task in tqdm(tasks):
if input_output_shape_is_same(task):
ts.train(task['train'])
 pred = ts.predict(task['test'])
 score = calk_score(task['test'], pred)
 else:
pred = [el['input'] for el in task['test']]
score = [0]*len(task['test'])
 predictions.append(pred)
 result.append(score)
 return result, predictions
train_X,train_y = to_img_shape(train_X, train_y)
 val_X,val_y = to_img_shape(val_X,val_y)
 test_X, _ = to_img_shape(test_X )<categorify>
train_result, train_predictions = evaluate(train_tasks)
 train_solved = [any(score)for score in train_result]
total = sum([len(score)for score in train_result])
 print(f"solved : {sum(train_solved)} from {total}({sum(train_solved)/total})" )
tfms = get_transforms(do_flip=False, max_rotate=10, max_zoom=1.1, max_warp=0.0, max_lighting=0.1)
 data =(ImageList.from_folder('/data/')
.split_by_folder() 
.label_from_folder() 
.add_test_folder() 
.transform(tfms, size=64)
.databunch() )<define_variables>
evaluation_result, evaluation_predictions = evaluate(evaluation_tasks)
 evaluation_solved = [any(score)for score in evaluation_result]
total = sum([len(score)for score in evaluation_result])
 print(f"solved : {sum(evaluation_solved)} from {total}({sum(evaluation_solved)/total})" )
data.show_batch(3,figsize=(6,6))<define_variables>
def flattener(pred):
str_pred = str([row for row in pred])
 str_pred = str_pred.replace(', ', '')
 str_pred = str_pred.replace('[[', '|')
 str_pred = str_pred.replace('][', '|')
 str_pred = str_pred.replace(']]', '|')
 return str_pred
def make_pediction(tasks):
ts = TaskSolver()
result = pd.Series()
for idx, task in tqdm(test_tasks.iteritems()):
if input_output_shape_is_same(task):
ts.train(task['train'])
 pred = ts.predict(task['test'])
 else:
pred = [el['input'] for el in task['test']]
for i, p in enumerate(pred):
result[f'{idx}_{i}'] = flattener(np.array(p ).tolist())
 return result
data.show_batch(3,figsize=(6,6), ds=DatasetType.Test )<choose_model_class>
submission = make_pediction(test_tasks)
 submission.head()
<train_model><EOS> 
submission = submission.reset_index()
submission.columns = ['output_id', 'output']
submission.to_csv('submission.csv', index=False)
 submission