<jupyter_start><jupyter_text>Facial Keypoint Detection  Import FastAI<jupyter_code>from fastai.vision.all import *<jupyter_output><empty_output><jupyter_text>Download Dataset and extract data<jupyter_code>!kaggle competitions download -c facial-keypoints-detection
file_extract("facial-keypoints-detection.zip", dest="./facial-keypoints-ds")
path = Path.cwd()/"facial-keypoints-ds"
path, path.ls()
import glob
all_zips = glob.glob(f"{str(path)}/*.zip")
[file_extract(f"{zip}", dest=f"{str(path)}") for zip in all_zips]<jupyter_output><empty_output><jupyter_text>Verify missing values<jupyter_code>df = pd.read_csv(path/"training.csv")
df.info()<jupyter_output><class 'pandas.core.frame.DataFrame'>
RangeIndex: 7049 entries, 0 to 7048
Data columns (total 31 columns):
 #   Column                     Non-Null Count  Dtype  
---  ------                     --------------  -----  
 0   left_eye_center_x          7039 non-null   float64
 1   left_eye_center_y          7039 non-null   float64
 2   right_eye_center_x         7036 non-null   float64
 3   right_eye_center_y         7036 non-null   float64
 4   left_eye_inner_corner_x    2271 non-null   float64
 5   left_eye_inner_corner_y    2271 non-null   float64
 6   left_eye_outer_corner_x    2267 non-null   float64
 7   left_eye_outer_corner_y    2267 non-null   float64
 8   right_eye_inner_corner_x   2268 non-null   float64
 9   right_eye_inner_corner_y   2268 non-null   float64
 10  right_eye_outer_corner_x   2268 non-null   float64
 11  right_eye_outer_corner_y   2268 non-null   float64
 12  left_eyebrow_inner_end_x   2270 non-null   float64
 13  left_eyebrow_inner_end_y   2270 non-null   float[...]<jupyter_text>Preprocess the data  Drop missing valuesDripping missing values will results in huge reduction in data, so it is not viable option Fill missing data1. Forward fill ```ffill``` works better2. Fill with median values, results are similar to Forward fill3. Fill with mean values, doesn't works for smaller facesI have kept all the options, for experimentation. Feel free to do so!<jupyter_code>### Drop missing values
#df = df.dropna()

### Fill with median values or mean values
'''
for c in df.columns:
    if(df[c].dtype!='object'):
        #df[c].fillna(df[c].mean(), inplace=True)
        df[c].fillna((df[c].median()), inplace=True)
'''

### Forward fill
df = df.fillna(method='ffill')

### Other experimentation but not completed!!
#df['is_valid'] = df.isna().sum(axis=1).apply(lambda x: False if x==0 else True)
#df = df.fillna(-1)

df.info()<jupyter_output><class 'pandas.core.frame.DataFrame'>
RangeIndex: 7049 entries, 0 to 7048
Data columns (total 31 columns):
 #   Column                     Non-Null Count  Dtype  
---  ------                     --------------  -----  
 0   left_eye_center_x          7049 non-null   float64
 1   left_eye_center_y          7049 non-null   float64
 2   right_eye_center_x         7049 non-null   float64
 3   right_eye_center_y         7049 non-null   float64
 4   left_eye_inner_corner_x    7049 non-null   float64
 5   left_eye_inner_corner_y    7049 non-null   float64
 6   left_eye_outer_corner_x    7049 non-null   float64
 7   left_eye_outer_corner_y    7049 non-null   float64
 8   right_eye_inner_corner_x   7049 non-null   float64
 9   right_eye_inner_corner_y   7049 non-null   float64
 10  right_eye_outer_corner_x   7049 non-null   float64
 11  right_eye_outer_corner_y   7049 non-null   float64
 12  left_eyebrow_inner_end_x   7049 non-null   float64
 13  left_eyebrow_inner_end_y   7049 non-null   float[...]<jupyter_text>Create DataLoaders through DataBlock<jupyter_code>### Image construction from array values
def condtruct_image(row):
  return PILImage(Image.fromarray(np.fromstring(row['Image'], sep=' ').astype(np.float32).reshape(-1, 96)).convert("P"))

### Get keypoints
def get_keypoints(r):
  return torch.from_numpy(r.drop('Image').values.astype(np.float32).reshape(-1, 2))
db = DataBlock(
    blocks = (ImageBlock, PointBlock),
    get_x = condtruct_image,
    get_y = get_keypoints,
    splitter = RandomSplitter(valid_pct=0.10, seed=1234),
    batch_tfms = aug_transforms(do_flip=False, max_zoom=1.0),
)
dls = db.dataloaders(df)
dls.show_batch()<jupyter_output><empty_output><jupyter_text>Create Learner instance<jupyter_code>#learn = cnn_learner(dls, resnet50).to_fp16()
learn = cnn_learner(dls, resnet152).to_fp16()
learn.lr_find()
#learn.loss_func
learn.fit_one_cycle(6, 7e-3)<jupyter_output><empty_output><jupyter_text>Verify result<jupyter_code>learn.show_results()<jupyter_output><empty_output><jupyter_text>Unfreeze the model and train again<jupyter_code>learn.unfreeze()
learn.lr_find()
learn.fit_one_cycle(6, slice(3e-5, 3e-4))<jupyter_output><empty_output><jupyter_text>Verify the results<jupyter_code>learn.show_results()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10861889927310488, 'fraction_numerical': 0.05462097611630322, 'mean_word_length': 3.944558521560575, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '546930', 'license': 'MIT', 'n_tokens_mistral': 1935, 'n_tokens_neox': 1711, 'n_words': 371, 'path': 'Facial-Keypoints-Detection_FastAI2.ipynb', 'repo_name': 'gurucharanmk/Facial-Keypoints-Detection_FastAI', 'size': '4815'}