# #16 Solution

Hi all. I have been quite busy since the end of the competition so I couldn’t post my solution earlier, but I still want to share with you what I did. 
I hope it is not too late!
My solution was an ensemble of different architectures (Resnet34, Resnet50, EfficientNet-b4 and EfficientNet-b5), different preprocessing methods (Circle+GaussianBlur and CircleToSquare+GaussianBlur) and different input sizes (224, 380 and 456). All they were blended using a weighted average (I manually tuned the weights, which worked better for me than selecting the weights using hyperopt). I used TTA in some models, which improved the score a bit (it was required setting scale=1.0 for TTA to work well using fastai).
A key part of my solution was the preprocessing. At first I tried substracting both median blurred and gaussian blurred images, but I just kept using the latter because I saw much better correlation between CV and LB. The idea was to remove all information that could help the algorithm to recognize the different kind of images, in order to generalize better. However, substracting gaussian blurred image seemed not enough to remove all the original picture information, since the color in the limit of the eye was still a bit different for the different image types:
![Circle + Gaussian Blur](assets/28929d3c0981044307931800.png)
So the idea was removing the black part before substracting gaussian blurred images. For that purpose I found the
[squircle library](https://pypi.org/project/squircle/)
which has 3 methods to do it. This is how the images look after preprocessing:
![Circle to Square +  Gaussian Blur](assets/0065f5d8a093a45ac479c296.png)
My best single model was an EfficientNet-b5 based on this CircleToSquare+GaussianBlur preprocessing, input size 380 and the following augmentations parameters (fastai):  get_transforms(max_rotate=0, flip_vert=True, max_warp=0.0, max_zoom=0, max_lighting=0.35). It scored 0.814 in the public LB and 0.927 in the private LB.
I also used pseudolabeling, which helped me a bit, but not so much because of the way I applied it (using a classification model with a threshold of 0.9). I guess if I would have applied pseudolabeling using all test data the way top teams described it my model would have performed better. At least I learned something new ;)
Well, congrats to all winners and thanks to all people who shared in discussions and who shared great kernels. Special thanks to
[@ratthachat](/ratthachat)
for the many preprocessing ideas and to
[@hmendonca](/hmendonca)
for sharing a kernel showing how to apply EfficientNet using fastai.
All the best!