Dans cette compétition, pour chacune des 7049 données d'image de visage, les coordonnées x et y des 15 parties qui caractérisent le visage sont données comme données d'apprentissage. (Exemple: coordonnée x du centre de l'œil gauche, coordonnée y du centre de l'œil droit, etc.) Il apprend ces données et donne les coordonnées des parties qui caractérisent le visage aux images de l'ensemble de test.
Je vais commencer immédiatement.
Code d'exécution
import pandas as pd
import numpy as np
import zipfile
import tensorflow as tf
Décompressez le fichier zip et ouvrez-le.
Code d'exécution
with zipfile.ZipFile('training.zip') as existing_zip:
with existing_zip.open('training.csv') as traincsv:
train=pd.read_csv(traincsv)
train
left_eye_center_x | left_eye_center_y | right_eye_center_x | right_eye_center_y | ... | mouth_center_top_lip_y | mouth_center_bottom_lip_x | mouth_center_bottom_lip_y | Image | |
---|---|---|---|---|---|---|---|---|---|
0 | 6.033564 | 39.002274 | 30.227008 | 36.421678 | ... | 72.935459 | 43.130707 | 84.485774 | 238 236 237 238 240 240 239 241 241 243 240 23... |
1 | 64.332936 | 34.970077 | 29.949277 | 33.448715 | ... | 70.266553 | 45.467915 | 85.480170 | 219 215 204 196 204 211 212 200 180 168 178 19... |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
7047 | 70.965082 | 39.853666 | 30.543285 | 40.772339 | ... | NaN | 50.065186 | 79.586447 | 254 254 254 254 254 238 193 145 121 118 119 10... |
7048 | 66.938311 | 43.424510 | 31.096059 | 39.528604 | ... | NaN | 45.900480 | 82.773096 | 53 62 67 76 86 91 97 105 105 106 107 108 112 1... |
Il s'agit de données de 7049 × 31. La dernière colonne des données est les données d'image, et les autres colonnes sont les coordonnées x et y qui indiquent la partie avec la face. En outre, il semble y avoir des valeurs manquantes. Combien y en a-t-il?
Code d'exécution
train.isnull().sum()
output
left_eye_center_x 10
left_eye_center_y 10
right_eye_center_x 13
right_eye_center_y 13
left_eye_inner_corner_x 4778
left_eye_inner_corner_y 4778
left_eye_outer_corner_x 4782
left_eye_outer_corner_y 4782
right_eye_inner_corner_x 4781
right_eye_inner_corner_y 4781
right_eye_outer_corner_x 4781
right_eye_outer_corner_y 4781
left_eyebrow_inner_end_x 4779
left_eyebrow_inner_end_y 4779
left_eyebrow_outer_end_x 4824
left_eyebrow_outer_end_y 4824
right_eyebrow_inner_end_x 4779
right_eyebrow_inner_end_y 4779
right_eyebrow_outer_end_x 4813
right_eyebrow_outer_end_y 4813
nose_tip_x 0
nose_tip_y 0
mouth_left_corner_x 4780
mouth_left_corner_y 4780
mouth_right_corner_x 4779
mouth_right_corner_y 4779
mouth_center_top_lip_x 4774
mouth_center_top_lip_y 4774
mouth_center_bottom_lip_x 33
mouth_center_bottom_lip_y 33
Image 0
Il y a un désordre ...
Cela décompresse également le fichier zip et l'ouvre.
Code d'exécution
with zipfile.ZipFile('test.zip') as existing_zip:
with existing_zip.open('test.csv') as testcsv:
test=pd.read_csv(testcsv)
test
ImageId | Image | |
---|---|---|
0 | 1 | 182 183 182 182 180 180 176 169 156 137 124 10... |
1 | 2 | 76 87 81 72 65 59 64 76 69 42 31 38 49 58 58 4... |
2 | 3 | 177 176 174 170 169 169 168 166 166 166 161 14... |
3 | 4 | 176 174 174 175 174 174 176 176 175 171 165 15... |
... | ... | ... |
1780 | 1781 | 28 28 29 30 31 32 33 34 39 44 46 46 49 54 61 7... |
1781 | 1782 | 104 95 71 57 46 52 65 70 70 67 76 72 69 69 72 ... |
1782 | 1783 | 63 61 64 66 66 64 65 70 69 70 77 83 63 34 22 2... |
Il s'agit de 1783 données d'image.
Deux autres fichiers CSV sont donnés, mais ici le format du fichier à soumettre est indiqué.
Code d'exécution
df=pd.read_csv("IdLookupTable.csv")
sample=pd.read_csv("SampleSubmission.csv")
Code d'exécution
df
RowId | ImageId | FeatureName | Location | |
---|---|---|---|---|
0 | 1 | 1 | left_eye_center_x | NaN |
1 | 2 | 1 | left_eye_center_y | NaN |
2 | 3 | 1 | right_eye_center_x | NaN |
3 | 4 | 1 | right_eye_center_y | NaN |
4 | 5 | 1 | left_eye_inner_corner_x | NaN |
... | ... | ... | ... | ... |
27119 | 27120 | 1783 | right_eye_center_y | NaN |
27120 | 27121 | 1783 | nose_tip_x | NaN |
27121 | 27122 | 1783 | nose_tip_y | NaN |
27122 | 27123 | 1783 | mouth_center_bottom_lip_x | NaN |
27123 | 27124 | 1783 | mouth_center_bottom_lip_y | NaN |
IdLookupTable.csv montre les coordonnées que vous souhaitez présenter pour chacune des 1783 images. La partie délicate de cette compétition est que les données d'entraînement donnent les coordonnées de 30 parties du visage, mais vous n'avez pas nécessairement à prédire toutes les coordonnées de l'image dans les données de test.
Plus précisément, vérifiez le numéro de chaque coordonnée incluse dans le fichier soumis.
Code d'exécution
df["FeatureName"].value_counts()
output
nose_tip_y 1783
nose_tip_x 1783
left_eye_center_x 1782
right_eye_center_y 1782
left_eye_center_y 1782
right_eye_center_x 1782
mouth_center_bottom_lip_x 1778
mouth_center_bottom_lip_y 1778
mouth_left_corner_x 590
mouth_center_top_lip_y 590
mouth_left_corner_y 590
mouth_center_top_lip_x 590
left_eye_outer_corner_x 589
left_eye_outer_corner_y 589
right_eye_inner_corner_y 589
right_eye_inner_corner_x 589
left_eye_inner_corner_y 588
right_eye_outer_corner_x 588
right_eye_outer_corner_y 588
left_eye_inner_corner_x 588
mouth_right_corner_x 587
mouth_right_corner_y 587
left_eyebrow_inner_end_x 585
right_eyebrow_inner_end_x 585
left_eyebrow_inner_end_y 585
right_eyebrow_inner_end_y 585
left_eyebrow_outer_end_x 574
left_eyebrow_outer_end_y 574
right_eyebrow_outer_end_x 572
right_eyebrow_outer_end_y 572
De cette manière, les coordonnées requises varient de manière irrégulière.
Vient ensuite un exemple de fichier de soumission.
Code d'exécution
sample
RowId | Location | |
---|---|---|
0 | 1 | 0 |
1 | 2 | 0 |
2 | 3 | 0 |
3 | 4 | 0 |
4 | 5 | 0 |
... | ... | ... |
27119 | 27120 | 0 |
27120 | 27121 | 0 |
27121 | 27122 | 0 |
27122 | 27123 | 0 |
27123 | 27124 | 0 |
Les données à soumettre sont simplement le numéro de ligne et les valeurs de coordonnées 27124.
Inutile de dire que c'est la partie principale de la compétition. Tout d'abord, extrayez uniquement les données d'image de train.csv et test.csv et transformez-les en un tableau numpy. Lors de la conversion des données d'image extraites en un tableau numpy, il est recommandé de préparer un tableau vide et de le remplacer un par un.
Code d'exécution
x_train=np.empty((7049,96,96,1))
x_test=np.empty((1783,96,96,1))
Code d'exécution
for i in range(7049):
train0=train["Image"][i].split(" ") #Extraire le i-ème tableau d'image séparé par des espaces
train1=[int(x) for x in train0] #Convertir chacun en type int et stocker dans la liste
train2=np.array(train1,dtype="float") #Convertir la liste en tableau numpy
train3=train2.reshape(96,96,1) #Mouler la matrice en 96x96x1
x_train[i]=train3 #Assigné comme le i-ème élément d'un tableau numpy vide
for i in range(1783):
test0=test["Image"][i].split(" ")
test1=[int(x) for x in test0]
test2=np.array(test1,dtype="float")
test3=test2.reshape(96,96,1)
x_test[i]=test3
Code d'exécution
x_train =x_train / 255
x_test = x_test /255
Soit y_train celui dont la colonne Image a été supprimée de train.csv.
Code d'exécution
y_train=train.drop(['Image'],axis=1)
Gérez les valeurs manquantes que vous avez vues précédemment. Pour le moment, appliquez un remplissage qui complète la valeur de la ligne précédente.
Code d'exécution
y_train.fillna(method = 'ffill',inplace = True)
Vérifiez à nouveau la valeur manquante.
Code d'exécution
y_train.isnull().sum()
output
left_eye_center_x 0
left_eye_center_y 0
right_eye_center_x 0
right_eye_center_y 0
left_eye_inner_corner_x 0
left_eye_inner_corner_y 0
left_eye_outer_corner_x 0
left_eye_outer_corner_y 0
right_eye_inner_corner_x 0
right_eye_inner_corner_y 0
right_eye_outer_corner_x 0
right_eye_outer_corner_y 0
left_eyebrow_inner_end_x 0
left_eyebrow_inner_end_y 0
left_eyebrow_outer_end_x 0
left_eyebrow_outer_end_y 0
right_eyebrow_inner_end_x 0
right_eyebrow_inner_end_y 0
right_eyebrow_outer_end_x 0
right_eyebrow_outer_end_y 0
nose_tip_x 0
nose_tip_y 0
mouth_left_corner_x 0
mouth_left_corner_y 0
mouth_right_corner_x 0
mouth_right_corner_y 0
mouth_center_top_lip_x 0
mouth_center_top_lip_y 0
mouth_center_bottom_lip_x 0
mouth_center_bottom_lip_y 0
Image 0
Il a été confirmé qu'il n'y avait aucune valeur manquante.
Enfin, standardisez les données.
Code d'exécution
for columns in train_y.columns:
mean.append(train_y[columns].mean())
std.append(train_y[columns].std())
train_y[columns] = (train_y[columns] - train_y[columns].mean()) / train_y[columns].std()
Construisez le modèle.
Code d'exécution
model=tf.keras.models.Sequential([
tf.keras.layers.Conv2D(6,(3,3), activation = 'relu', input_shape=(96,96,1)),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Conv2D(12,(3,3), activation = 'relu'),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(512, activation = 'relu'),
tf.keras.layers.Dense(30,activation='relu')
])
model.summary()
output
Model: "sequential_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_2 (Conv2D) (None, 94, 94, 6) 60
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 47, 47, 6) 0
_________________________________________________________________
conv2d_3 (Conv2D) (None, 45, 45, 12) 660
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 22, 22, 12) 0
_________________________________________________________________
flatten_1 (Flatten) (None, 5808) 0
_________________________________________________________________
dense_2 (Dense) (None, 512) 2974208
_________________________________________________________________
dense_3 (Dense) (None, 30) 15390
=================================================================
Total params: 2,990,318
Trainable params: 2,990,318
Non-trainable params: 0
_________________________________________________________________
Code d'exécution
model.compile(optimizer='adam', loss='mean_squared_error', metrics=['accuracy'])
Laisse-moi apprendre.
Code d'exécution
model.fit(x_train, y_train, epochs = 10)
output
Train on 7049 samples
Epoch 1/10
7049/7049 [==============================] - 20s 3ms/sample - loss: 470.8903 - accuracy: 0.5540
Epoch 2/10
7049/7049 [==============================] - 19s 3ms/sample - loss: 283.7981 - accuracy: 0.6073
Epoch 3/10
7049/7049 [==============================] - 20s 3ms/sample - loss: 152.0215 - accuracy: 0.6493
Epoch 4/10
7049/7049 [==============================] - 20s 3ms/sample - loss: 151.0923 - accuracy: 0.6866
Epoch 5/10
7049/7049 [==============================] - 19s 3ms/sample - loss: 150.6215 - accuracy: 0.7188
Epoch 6/10
7049/7049 [==============================] - 20s 3ms/sample - loss: 149.9657 - accuracy: 0.7289
Epoch 7/10
7049/7049 [==============================] - 20s 3ms/sample - loss: 149.8715 - accuracy: 0.7371
Epoch 8/10
7049/7049 [==============================] - 19s 3ms/sample - loss: 149.7018 - accuracy: 0.7424
Epoch 9/10
7049/7049 [==============================] - 20s 3ms/sample - loss: 149.4364 - accuracy: 0.7451
Epoch 10/10
7049/7049 [==============================] - 19s 3ms/sample - loss: 149.3164 - accuracy: 0.7510
Faites des prédictions pour le modèle de test.
Code d'exécution
pred = model.predict(x_test)
C'est un peu ennuyeux à partir d'ici, mais il faut se référer au IdLookupTable.csv mentionné ci-dessus et extraire les coordonnées requises pour chaque image. Sans surprise, le pred se compose de 15 prédictions de coordonnées x et y des caractéristiques pour chacune des 1783 images. (1783 × 30)
En guise d'approche,
Code d'exécution
#1. IdLookupTable.Extrayez ImageId et le nom de la fonction de csv.
lookid_list = list(df['FeatureName'])
imageID = list(df['ImageId']-1)
pre_list = list(pred)
Code d'exécution
#2.Nom de la fonction 0~Encodez jusqu'à 29 index et stockez-les dans la liste.
feature = []
for f in looked_list:
feature.append(lookid_list.index(f))
Code d'exécution
#3.Celui correspondant à la combinaison de l'ID d'image et de l'index de nom de caractéristique est extrait du résultat de la prédiction.
#A ce moment, la valeur est obtenue en effectuant la conversion opposée à la normalisation.
preded = []
for x,y in zip(imageID,feature):
preded.append(pre_list[x][y] * std[y] + mean[y])
Enfin, créez un fichier de soumission.
Code d'exécution
rowid = pd.Series(df['RowId'],name = 'RowId')
loc = pd.Series(preded,name = 'Location')
Code d'exécution
submission = pd.concat([rowid,loc],axis = 1)
c'est tout. Cela vous donnera un score d'environ 3,8. Si vous appliquez Augmentation à l'image ou améliorez le modèle, le score augmentera du tout. Je souhaite publier à nouveau dès que j'y travaille. Je vous serais reconnaissant si vous pouviez signaler des erreurs. Merci beaucoup.