Bonjour. J'ai toujours été intéressé par la reconnaissance d'images et j'avais de vagues connaissances, mais je n'ai pas encore écrit de code. Cette fois, j'aimerais écrire un article pour les débutants. Je vous remercie.
Tout d'abord, collectez les images des membres. Il existe des services de recherche d'images tels que Bing et Yahoo, mais dans cet article, nous collecterons des images en grattant les résultats de la recherche d'images Google. Vous pouvez obtenir le code d'origine depuis ici. Cependant, le code original ne peut pas être téléchargé (à partir d'avril 2020). Il existe un correctif pour ce problème en tant que requêtes Pull, donc cette fois, nous utiliserons le code.
Exemple d'utilisation de google_images_download.py
cd google_images_download/
python google_images_download.py -k "Asuka Saito"
python google_images_download.py -k "site:twitter.com Asuka Saito"
Vous ne pouvez télécharger que 100 copies à la fois avec ce programme. Si vous souhaitez collecter plus d'images, veuillez modifier le mot de recherche. Vous pouvez également utiliser le mot de recherche "site: url" pour télécharger uniquement les images qui correspondent à l'url.
Le téléchargement de l'image Google n'a pas fonctionné, il correspond donc
Ensuite, supprimez exactement les mêmes données d'image des images collectées en 1. Les algorithmes sont résumés dans la figure ci-dessous.
En 1., le vecteur 8 bits x 3 (RVB) est converti en 1 bit (noir et blanc). À ce stade, la conversion monochrome est effectuée à l'aide d'un algorithme appelé tramage Floyd-Steinberg. ([a](https://ja.wikipedia.org/wiki/%E3%83%95%E3%83%AD%E3%82%A4%E3%83%89-%E3%82%B9%E3 % 82% BF% E3% 82% A4% E3% 83% B3% E3% 83% 90% E3% 83% BC% E3% 82% B0% E3% 83% BB% E3% 83% 87% E3% 82 % A3% E3% 82% B6% E3% 83% AA% E3% 83% B3% E3% 82% B0), [b](https://pillow.readthedocs.io/en/stable/reference/Image. html), c)). Le code de conversion monochrome est indiqué ci-dessous. J'ai fait référence au code de ici.
def img2vec(filename):
img = Image.open(filename)
img = img.resize((200, 200), resample=Image.BILINEAR) #Rétrécir
img = img.convert('1') #Binarisation
#img.save(get_mono_filename(filename)) #Si vous voulez vérifier l'image
img = np.array(img)
#Convertir en une matrice de type int
int_img = img.astype(np.int)
return int_img
Puis calculez la norme.
def calnorm(vec):
norm = np.linalg.norm(vec)
return norm
Disposez les normes par ordre décroissant. Utilisez la fonction de tri pour trier les valeurs dans n'importe quelle colonne.
def fig_norm_list_cal(list_fig):
#Faites une liste qui résume chaque figue et norme
#Exemple
# fig_norm_list = [[fig, norm], [fig.A, 2], [fig.B, 3],...[figZ, 5]]
fig_norm_list = fig_norm_mat(list_fig)
#Organiser les magnitudes de la norme par ordre décroissant
#http://sota1235.com/blog/2015/04/23/python_sort_twodime.html
fig_norm_list = sorted(fig_norm_list, key = lambda x: x[1])
#nd.Convertir en type de tableau
fig_norm_list = np.array(fig_norm_list)
return fig_norm_list
Vérifiez les valeurs de norme une par une et supprimez celles de même valeur.
def del_fig_list_cal(fig_norm_list):
#Lister les fichiers à supprimer
del_fig_list = []
#La ligne du bas ne compte pas
for i in range(fig_norm_list.shape[0] - 1):
if (fig_norm_list[i, 1] == fig_norm_list[i+1, 1]):
del_fig_list.append(str(fig_norm_list[i, 0]))
return del_fig_list
Supprimez le fichier en utilisant les del_fig_list et os.remove () calculés ci-dessus.
Ce code détermine également l'extension en même temps.
#Remplacez le nom de l'image par un numéro de série
def fig_rename():
i = 1
j = 1
k = 1
list_fig = listfig()
for pre_filename in list_fig:
if ((".jpg " in pre_filename) == True ):
os.rename(pre_filename, path + "/fig_data/" + str(i) + '.jpg')
i += 1
elif ((".png " in pre_filename) == True):
os.rename(pre_filename, path + "/fig_data/" + str(j) + '.png')
j += 1
elif ((".jpeg " in pre_filename) == True):
os.rename(pre_filename, path + "/fig_data/" + str(k) + '.jpeg')
k += 1
else:
pass
return
Programme pour rechercher la même image
L'image peut contenir autre chose qu'un visage ou peut contenir plusieurs visages. Vous devez façonner cela en une image de visage uniquement que vous pouvez utiliser pour l'apprentissage. Ici, nous avons utilisé la détection de visage par Haar-Cascade, qui est installée en standard dans OpenCV.
import cv2
import os
import glob
path = os.getcwd()
def listfig():
#.Récupérer des fichiers autres que py
#https://qiita.com/AAAAisBraver/items/8d40d9c2d624ecee105d
filename = path + "/face_detect_test/" + "*[!.py]"
list_fig = glob.glob(filename)
return list_fig
def jud_ext(filename):
if ((".jpg " in filename) == True):
ext = '.jpg'
elif ((".png " in filename) == True):
ext = '.png'
elif ((".jpeg " in filename) == True):
ext = '.jpeg'
else:
ext = 'end'
return ext
def main():
face_cascade_path = '/home/usr/anaconda3/pkgs/libopencv-4.2.0-py36_2'\
'/share/opencv4/haarcascades/haarcascade_frontalface_default.xml'
face_cascade = cv2.CascadeClassifier(face_cascade_path)
#Création de liste d'images
fig_list = listfig()
#Extrait de la liste d'images avec instruction for
j = 1 #Numéroter les images avant de détecter les visages
k = 0 #Compter les images trop petites
for fig_name in fig_list:
#fig_Identifiez l'extension du nom
ext = jud_ext(fig_name)
#Si fin, fin
if (ext == 'end'):
break
#Chargement d'image
src = cv2.imread(fig_name)
src_gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(src_gray)
#Découpez la partie faces
i = 1 #S'il y a deux visages ou plus dans une image
for x, y, w, h in faces:
#cv2.rectangle(src, (x, y), (x + w, y + h), (255, 0, 0), 2)
#Couper uniquement la partie faciale de src
face = src[y: y + h, x: x + w]
#face_gray = src_gray[y: y + h, x: x + w]
#Assurez-vous qu'il y a au moins 64 pixels de chaque côté
if face.shape[0] < 64:
print('\ntoo small!!\n')
print('\n{}\n'.format(fig_name))
k += 1
continue
#Mise en garde: (64,64)N'est pas enregistré en dessous de 64x64 pixels
face = cv2.resize(face, (64, 64))
#Sauvegarde du visage
cv2.imwrite(path + '/face_detect_test/clip_face/' + 'face' + str(i) + str(j) + ext, face)
i += 1
j += 1
print("too small fig is {}".format(k))
if __name__ == '__main__':
main()
Je vais vous expliquer un extrait de code partiel. Tout d'abord, utilisez le code suivant pour déterminer l'extension de l'image.
def jud_ext(filename):
if ((".jpg " in filename) == True):
ext = '.jpg'
elif ((".png " in filename) == True):
ext = '.png'
elif ((".jpeg " in filename) == True):
ext = '.jpeg'
else:
ext = 'end'
return ext
L'image que j'ai utilisée n'avait que les formats jpg, png et jpeg, donc j'ai écrit le code pour juger ces trois. La raison de la détermination de l'extension de l'image est de sauvegarder l'image avec la même extension après avoir coupé l'image du visage.
Le code suivant est utilisé lors de la découpe du visage. À ce stade, la résolution est convertie en 64x64. Il s'agit d'une mesure pour réduire la taille des données. La fonction cv2.resize
n'enregistre pas les images inférieures à 64x64.
Cependant, comme je l'ai remarqué plus tard, il est extrêmement difficile de voir lors du jugement manuel de l'image du visage, donc je pense que vous pouvez l'enregistrer à 128 x 128.
def main():
face_cascade_path = '/home/usr/anaconda3/pkgs/libopencv-4.2.0-py36_2'\
'/share/opencv4/haarcascades/haarcascade_frontalface_default.xml'
face_cascade = cv2.CascadeClassifier(face_cascade_path)
#Création de liste d'images
fig_list = listfig()
#Extrait de la liste d'images avec instruction for
j = 1 #Numéroter les images avant de détecter les visages
k = 0 #Compter les images trop petites
for fig_name in fig_list:
#fig_Identifiez l'extension du nom
ext = jud_ext(fig_name)
#Si fin, fin
if (ext == 'end'):
break
#Chargement d'image
src = cv2.imread(fig_name)
src_gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(src_gray)
#Découpez la partie faces
i = 1 #S'il y a deux visages ou plus dans une image
for x, y, w, h in faces:
#cv2.rectangle(src, (x, y), (x + w, y + h), (255, 0, 0), 2)
#Couper uniquement la partie faciale de src
face = src[y: y + h, x: x + w]
#face_gray = src_gray[y: y + h, x: x + w]
#Assurez-vous qu'il y a au moins 64 pixels de chaque côté
if face.shape[0] < 64:
print('\ntoo small!!\n')
print('\n{}\n'.format(fig_name))
k += 1
continue
#Mise en garde: (64,64)N'est pas enregistré en dessous de 64x64 pixels
face = cv2.resize(face, (64, 64))
#Sauvegarde du visage
cv2.imwrite(path + '/face_detect_test/clip_face/' + 'face' + str(i) + str(j) + ext, face)
i += 1
j += 1
print("too small fig is {}".format(k))
Les photos de visage sont divisées en attribuant 80% des données des enseignants et 20% des données des tests. J'ai utilisé le code suivant.
import os
import random
import shutil
import glob
path = os.getcwd()
names = ["ikuta_face", "saito_asuka_face", "shiraishi_face"]
#Collectez les noms d'images dans une liste
def listfig(tar_dir):
#.Récupérer des fichiers autres que py
#https://qiita.com/AAAAisBraver/items/8d40d9c2d624ecee105d
filename = path + tar_dir + "*[!.py]"
list_fig = glob.glob(filename)
return list_fig
def main():
for name in names:
#Obtenir la liste des répertoires d'images
face_list = listfig("/dataset_face_fig/" + name + "/")
# face_Liste aléatoire
random.shuffle(face_list)
# face_Déplacer 20% du haut de la liste vers le répertoire de test
for i in range(len(face_list)//5):
shutil.move(str(face_list[i]), str(path + "/dataset_face_fig/test/" + name))
if __name__ == "__main__":
main()
Après avoir séparé les données d'image, vérifiez que les données sont correctes. S'il y a une erreur dans la recherche d'images Google, une image qui n'a rien à voir avec elle peut être enregistrée. Dans mon cas, il y a eu les cas suivants.
Comme je l'ai mentionné plus tôt, je luttais avec une image 64x64 tout en faisant ce travail.
Après avoir trié les images, l'étape suivante consiste à traiter les images pour augmenter les données de l'enseignant. Le code source est indiqué ci-dessous.
import os
import glob
import traceback
import cv2
from scipy import ndimage
path = os.getcwd()
#Collectez les noms d'images dans une liste
def listfig(tar_dir):
#.Récupérer des fichiers autres que py
#https://qiita.com/AAAAisBraver/items/8d40d9c2d624ecee105d
filename = path + tar_dir + "*[!.py]"
list_fig = glob.glob(filename)
return list_fig
#Faire pivoter l'image
def fig_rot(img, ang):
img_rot = ndimage.rotate(img,ang)
img_rot = cv2.resize(img_rot,(64,64))
return img_rot
#Jugement d'extension
def jud_ext(filename):
if ((".jpg " in filename) == True):
ext = '.jpg'
elif ((".png " in filename) == True):
ext = '.png'
elif ((".jpeg " in filename) == True):
ext = '.jpeg'
else:
ext = 'end'
try:
raise Exception
except:
traceback.print_exc()
return ext
def main():
#Spécifiez le répertoire contenant les données de l'enseignant à augmenter
names = ["ikuta_face", "saito_asuka_face", "shiraishi_face"]
for name in names:
# /dataset_face_fig/name/Récupère la liste d'images du répertoire
train_fig_list = listfig("/dataset_face_fig/" + "/" + name + "/")
i = 1 #Ne couvrez pas le nom de l'image
for train_fig in train_fig_list:
ext = jud_ext(train_fig)
#Chargement d'image
img = cv2.imread(train_fig)
#rotation
for ang in [-10, 0, 10]:
# j = 1 #Ne couvrez pas le nom de l'image
img_rot = fig_rot(img, ang)
#Enregistrer l'image
cv2.imwrite(path + '/dataset_face_fig/train/' + name + "/" + str(i) + '_' + str(ang) + ext, img_rot)
#Traitement des seuils
img_thr = cv2.threshold(img_rot, 100, 255, cv2.THRESH_TOZERO)[1]
cv2.imwrite(path + '/dataset_face_fig/train/' + name + "/" + str(i) + '_' + str(ang) + 'thr' + ext, img_thr)
#Traitement du flou
img_filter = cv2.GaussianBlur(img_rot, (5, 5), 0)
cv2.imwrite(path + '/dataset_face_fig/train/' + name + "/" + str(i) + '_' + str(ang) + 'fil' + ext, img_filter)
i += 1
return
if __name__ == "__main__":
main()
Faites pivoter une donnée d'image pour l'augmenter à trois. Après cela, un traitement de seuil et un traitement de flou sont effectués pour chaque image. Neuf images sont incluses en 3x3 pour une donnée d'image. Vous trouverez ci-dessous un extrait du code de base.
def main():
#Spécifiez le répertoire contenant les données de l'enseignant à augmenter
names = ["ikuta_face", "saito_asuka_face", "shiraishi_face"]
for name in names:
# /dataset_face_fig/name/Récupère la liste d'images du répertoire
train_fig_list = listfig("/dataset_face_fig/" + "/" + name + "/")
i = 1 #Ne couvrez pas le nom de l'image
for train_fig in train_fig_list:
ext = jud_ext(train_fig)
#Chargement d'image
img = cv2.imread(train_fig)
#rotation
for ang in [-10, 0, 10]:
# j = 1 #Ne couvrez pas le nom de l'image
img_rot = fig_rot(img, ang)
#Enregistrer l'image
cv2.imwrite(path + '/dataset_face_fig/train/' + name + "/" + str(i) + '_' + str(ang) + ext, img_rot)
#Traitement des seuils
img_thr = cv2.threshold(img_rot, 100, 255, cv2.THRESH_TOZERO)[1]
cv2.imwrite(path + '/dataset_face_fig/train/' + name + "/" + str(i) + '_' + str(ang) + 'thr' + ext, img_thr)
#Traitement du flou
img_filter = cv2.GaussianBlur(img_rot, (5, 5), 0)
cv2.imwrite(path + '/dataset_face_fig/train/' + name + "/" + str(i) + '_' + str(ang) + 'fil' + ext, img_filter)
i += 1
return
Après cela, vous devez 1. étiqueter les données d'image et 2. apprendre. À partir de là, je vais essayer d'utiliser Google Colaboratory (Colab). Colab fournit un processeur et un GPU haut de gamme, qui permettent des calculs à grande vitesse. Colab peut être utilisé par toute personne disposant d'un compte Google. Tout d'abord, exécutez le code suivant pour monter le lecteur Google. Cela vous donne accès aux données de Google Drive. L'exécution est «Maj + Entrée».
from google.colab import drive
drive.mount('/content/drive')
import tensorflow as tf
tf.test.gpu_device_name()
Ensuite, nous allons étiqueter et former les données d'image. Tout d'abord, le code source est indiqué ci-dessous.
#Tout faire, de l'étiquetage à l'apprentissage
#débogueur
%pdb off
import os
import glob
import cv2
import numpy as np
from keras.layers import Activation, Conv2D, Dense, Flatten, MaxPooling2D
from keras.models import Sequential
from keras.utils.np_utils import to_categorical
from tqdm import tqdm
import matplotlib.pyplot as plt
import pickle
import datetime
path = os.getcwd()
print(path)
%cd /content/drive/My\ Drive/dataset_face_fig
#Collectez les noms d'images dans une liste
def listfig(tar_dir):
#.Récupérer des fichiers autres que py
#.Récupérer des fichiers autres que py
#https://qiita.com/AAAAisBraver/items/8d40d9c2d624ecee105d
filename = tar_dir + "*[!.py]"
list_fig = glob.glob(filename)
return list_fig
#Jugement de la personne
def jud_hum(filename):
if (("ikuta" in filename) == True):
ext = 0
elif (("saito_asuka" in filename) == True):
ext = 1
elif (("shiraishi" in filename) == True):
ext = 2
else:
ext = 'end'
try:
raise Exception
except:
traceback.print_exc()
return ext
#Étiquetage des données des enseignants
def label_training(names):
#Étiquetage des données des enseignants
x_train = []
y_train = []
for name in tqdm(names):
face_fig_list = glob.glob("/content/drive/My Drive/dataset_face_fig/train/" + name + "/" + "*")
print(face_fig_list)
for face_fig_filename in tqdm(face_fig_list):
face_img = cv2.imread(face_fig_filename)
b,g,r = cv2.split(face_img)
face_img = cv2.merge([r,g,b])
x_train.append(face_img)
kind_hum = jud_hum(face_fig_filename)
y_train.append(kind_hum)
print(y_train)
print("y_train length")
print(len(y_train))
# x_train, y_sauver le train
f = open('x_train.txt', 'wb')
#Vider la liste en f
pickle.dump(x_train, f)
f = open('y_train.txt', 'wb')
#Vider la liste en f
pickle.dump(y_train, f)
return x_train, y_train
#Étiquetage des données de test
def label_test(names):
#Étiquetage des données de test
x_test = []
y_test = []
for name in tqdm(names):
# face_fig_list = listfig("/content/drive/My Drive/dataset_face_fig/" + name)
face_fig_list = glob.glob("/content/drive/My Drive/dataset_face_fig/test/" + name + "/" + "*")
# print("/content/drive/My Drive/dataset_face_fig/" + name)
print(face_fig_list)
for face_fig_filename in tqdm(face_fig_list):
face_img = cv2.imread(face_fig_filename)
b,g,r = cv2.split(face_img)
face_img = cv2.merge([r,g,b])
x_test.append(face_img)
kind_hum = jud_hum(face_fig_filename)
y_test.append(kind_hum)
# x_test, y_Enregistrer le test
f = open('x_test.txt', 'wb')
#Vider la liste en f
pickle.dump(x_test, f)
f = open('y_test.txt', 'wb')
#Vider la liste en f
pickle.dump(y_test, f)
print(y_test)
print("y_test length")
print(len(y_test))
return x_test, y_test
def cnn(x_train, y_train, x_test, y_test):
#Définition du modèle
model = Sequential()
model.add(Conv2D(input_shape=(64, 64, 3), filters=32,kernel_size=(3, 3),
strides=(1, 1), padding="same"))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(filters=32, kernel_size=(3, 3),
strides=(1, 1), padding="same"))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(filters=32, kernel_size=(3, 3),
strides=(1, 1), padding="same"))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(256))
model.add(Activation("sigmoid"))
model.add(Dense(128))
model.add(Activation('sigmoid'))
model.add(Dense(3))
model.add(Activation('softmax'))
#compiler
model.compile(optimizer='sgd',
loss='categorical_crossentropy',
metrics=['accuracy'])
#Apprentissage
history = model.fit(x_train, y_train, batch_size=32,
epochs=50, verbose=1, validation_data=(x_test, y_test))
#Évaluation et affichage du système de généralisation
score = model.evaluate(x_test, y_test, batch_size=32, verbose=0)
print('validation loss:{0[0]}\nvalidation accuracy:{0[1]}'.format(score))
model.save("my_model.h5")
type(history)
return history
def learn_monitor_plot(history):
#acc, val_tracé acc
plt.plot(history.history["accuracy"], label="acc", ls="-", marker="o")
plt.plot(history.history["val_accuracy"], label="val_acc", ls="-", marker="x")
plt.ylabel("accuracy")
plt.xlabel("epoch")
plt.legend(loc="best")
now = datetime.datetime.now()
plt.savefig("learning_cpu_" + now.strftime('%Y%m%d_%H%M%S') + '.png')
def main():
print("ok")
names = ["ikuta_face", "saito_asuka_face", "shiraishi_face"]
#Étiquetage des données des enseignants et des données de formation
x_train, y_train = label_training(names)
x_test, y_test = label_test(names)
#Mise en forme des données d'image
x_train = np.array(x_train)
x_test = np.array(x_test)
#Formatage des données d'étiquette
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)
#L'apprentissage en profondeur
learn_history = cnn(x_train, y_train, x_test, y_test)
#Graphique
learn_monitor_plot(learn_history)
main()
%cd /content
La pièce à étiqueter est indiquée ci-dessous.
#Jugement de la personne
def jud_hum(filename):
if (("ikuta" in filename) == True):
ext = 0
elif (("saito_asuka" in filename) == True):
ext = 1
elif (("shiraishi" in filename) == True):
ext = 2
else:
ext = 'end'
try:
raise Exception
except:
traceback.print_exc()
return ext
#Étiquetage des données des enseignants
def label_training(names):
#Étiquetage des données des enseignants
x_train = []
y_train = []
for name in tqdm(names):
face_fig_list = glob.glob("/content/drive/My Drive/dataset_face_fig/train/" + name + "/" + "*")
print(face_fig_list)
for face_fig_filename in tqdm(face_fig_list):
face_img = cv2.imread(face_fig_filename)
b,g,r = cv2.split(face_img)
face_img = cv2.merge([r,g,b])
x_train.append(face_img)
kind_hum = jud_hum(face_fig_filename)
y_train.append(kind_hum)
print(y_train)
print("y_train length")
print(len(y_train))
# x_train, y_sauver le train
f = open('x_train.txt', 'wb')
#Vider la liste en f
pickle.dump(x_train, f)
f = open('y_train.txt', 'wb')
#Vider la liste en f
pickle.dump(y_train, f)
return x_train, y_train
#Étiquetage des données de test
def label_test(names):
#Étiquetage des données de test
x_test = []
y_test = []
for name in tqdm(names):
# face_fig_list = listfig("/content/drive/My Drive/dataset_face_fig/" + name)
face_fig_list = glob.glob("/content/drive/My Drive/dataset_face_fig/test/" + name + "/" + "*")
# print("/content/drive/My Drive/dataset_face_fig/" + name)
print(face_fig_list)
for face_fig_filename in tqdm(face_fig_list):
face_img = cv2.imread(face_fig_filename)
b,g,r = cv2.split(face_img)
face_img = cv2.merge([r,g,b])
x_test.append(face_img)
kind_hum = jud_hum(face_fig_filename)
y_test.append(kind_hum)
# x_test, y_Enregistrer le test
f = open('x_test.txt', 'wb')
#Vider la liste en f
pickle.dump(x_test, f)
f = open('y_test.txt', 'wb')
#Vider la liste en f
pickle.dump(y_test, f)
print(y_test)
print("y_test length")
print(len(y_test))
return x_test, y_test
cv2.imread (données d'image)
convertit en type ndarray 3D. Par exemple, lorsqu'une image 64x64 pixels est chargée, le type de données est le suivant.
data = cv2.imread('filepath')
print(data.shape)
# (64, 64, 3)
Extraire 3 tableaux 2D de données avec cv2.split (données de type ndarray). Notez qu'à ce moment, le bleu, le vert et le rouge sont extraits dans cet ordre. Créez une liste avec cv2.merge ([r, g, b]) et ajoutez-la à x_train ou x_test avec append. Il a fallu du temps pour charger l'image lorsqu'elle était calculée avec le GPU, j'ai donc écrit le code pour enregistrer temporairement uniquement les données d'image dans Drive.
# x_test, y_Enregistrer le test
f = open('x_test.txt', 'wb')
#Vider la liste en f
pickle.dump(x_test, f)
f = open('y_test.txt', 'wb')
#Vider la liste en f
pickle.dump(y_test, f)
Il faut environ 5 secondes pour calculer 1 époque sur le processeur, mais cela prend moins d'une seconde sur le GPU. Essayez-le. Le résultat est le suivant.
La précision est d'environ 80%.
Pour la première fois, j'ai écrit un code à grande échelle et effectué une reconnaissance d'image. À l'avenir, j'aimerais étudier et utiliser un autre réseau. Nous attendons vos questions et commentaires avec impatience. Merci d'avoir lu jusqu'ici.
Classer le visage du membre Nogisaka par CNN
Recommended Posts