Tout d'abord, je l'ai utilisé comme référence. Merci beaucoup.
https://qiita.com/yottyann1221/items/a08300b572206075ee9f https://qiita.com/tomo_20180402/items/e8c55bdca648f4877188 https://qiita.com/mainvoidllll/items/db991dc30d3ddced6250 https://newtechnologylifestyle.net/keras_imagedatagenerator/
J'ai utilisé des images gratuites pour les images publiées. https://pixabay.com/ja/
Introduction à l'apprentissage automatique. Il semble que cela se passera comme ça après un tour rapide.
Cette fois, j'ai décidé de créer un programme de jugement discret avec reconnaissance d'image.
J'ai mis python3 en chocolat sur Windows 10. Construisez un environnement virtuel avec venv et mettez les bibliothèques nécessaires.
> mkdir -p e:\python\ml
> cd e:\python\ml
> python -m venv ml
> .\ml\Scripts\activate
(ml)> pip install requests
(ml)> pip install beautifulsoup4
#J'obtiens l'erreur suivante si je n'inclus pas lxml
# bs4.FeatureNotFound: Couldn't find a tree builder with the features you requested: lxml. Do you need to install a parser library?
(ml)> pip install lxml
(ml)> pip install pillow
#Mettez le dernier numpy et np.load()Ensuite, l'erreur suivante apparaîtra, alors spécifiez l'ancienne version
# ValueError: Object arrays cannot be loaded when allow_pickle=False
(ml)> pip install numpy==1.16.2
(ml)> pip install sklearn
(ml)> pip install tensorflow
(ml)> pip install keras
(ml)> pip install matplotlib
Je l'ai fait comme ça.
e:\python\ml
├─ml
└─src
├─data
│ ├─img
│ │ ├─original :Image originale obtenue par grattage
│ │ │ ├─ Shelty
│ │ │ ├─ Corgi
│ │ │ └─ Border Collie
│ │ ├─trimmed :Image laissée après avoir supprimé les images inutiles
│ │ │ ├─ Shelty
│ │ │ ├─ Corgi
│ │ │ └─ Border Collie
│ │ ├─excluded :Image inutile
│ │ │ ├─ Shelty
│ │ │ ├─ Corgi
│ │ │ └─ Border Collie
│ │ ├─extended :Image gonflée en traitant l'image restante
│ │ │ ├─ Shelty
│ │ │ ├─ Corgi
│ │ │ └─ Border Collie
│ │ └─test :Image pour vérifier le fonctionnement de l'IA
│ ├─train_test_data
│ │ └─data.npy :Données de l'enseignant / du test créées à l'aide d'images étendues
│ ├─model :Modèle créé
│ │ ├─Training_and_validation_accuracy.png
│ │ ├─Training_and_validation_loss.png
│ │ ├─model_predict.hdf5
│ │ └─model_predict.json
├─img_scraper :Grattage d'image
│ ├─google_search.py
│ └─main.py
├─img_trimmer :Suppression d'image
│ └─main.py
├─img_duplicator :Remplissage d'image
│ └─main.py
├─train_test_data_generator :Création de données enseignant / test
│ └─main.py
├─model_generator :Génération de modèle
│ └─main.py
└─ai :Jugement Shelty
└─main.py
Préparez d'abord une image. Cette fois, j'ai gratté 300 feuilles à la fois.
# -- coding: utf-8 --
import json
from urllib import parse
import requests
from bs4 import BeautifulSoup
class Google:
def __init__(self):
self.GOOGLE_SEARCH_URL = 'https://www.google.co.jp/search'
self.session = requests.session()
self.session.headers.update({
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:57.0) Gecko/20100101 Firefox/57.0'})
def Search(self, keyword, type='text', maximum=1000):
'''recherche Google'''
print('Google', type.capitalize(), 'Search :', keyword)
result, total = [], 0
query = self.query_gen(keyword, type)
while True:
#Chercher
html = self.session.get(next(query)).text
links = self.get_links(html, type)
#Ajouter des résultats de recherche
if not len(links):
print('-> No more links')
break
elif len(links) > maximum - total:
result += links[:maximum - total]
break
else:
result += links
total += len(links)
print('->résultat', str(len(result)), 'J'ai les liens de')
return result
def query_gen(self, keyword, type):
'''Générateur de requêtes de recherche'''
page = 0
while True:
if type == 'text':
params = parse.urlencode({
'q': keyword,
'num': '100',
'filter': '0',
'start': str(page * 100)})
elif type == 'image':
params = parse.urlencode({
'q': keyword,
'tbm': 'isch',
'filter': '0',
'ijn': str(page)})
yield self.GOOGLE_SEARCH_URL + '?' + params
page += 1
def get_links(self, html, type):
'''Obtenir le lien'''
soup = BeautifulSoup(html, 'lxml')
if type == 'text':
elements = soup.select('.rc > .r > a')
links = [e['href'] for e in elements]
elif type == 'image':
elements = soup.select('.rg_meta.notranslate')
jsons = [json.loads(e.get_text()) for e in elements]
links = [js['ou'] for js in jsons]
return links
# -- coding: utf-8 --
import os
import requests
import google_search
#Mot-clé de recherche
KEYWORDS = [u'Shelty', u'Corgi', u'Border collie']
#Nombre d'images à acquérir
IMG_CNT = 300
g = google_search.Google()
for keyword in KEYWORDS:
#Créer une destination de sauvegarde
img_dir = os.path.join('./../data/img/original', keyword)
os.makedirs(img_dir, exist_ok=True)
print(u'Destination: {}'.format(img_dir))
#Recherche d'image
img_urls = g.Search('{} filetype:jpg -Chien shiba-se sentait-Produit-jouet-Poupée en peluche-ornement-article-mascotte-Livre-Couverture-films-Dessin animé-charme-jpg -Rakuten-Une illustration-Autocollant-vente par correspondance-LINE -timbre-silhouette-conception-Agresser-Éleveur-Jimoty-Groupe-Troupeau-clou-grue-Freebie-Produit'.format(keyword), type='image', maximum=IMG_CNT)
#Enregistrer l'image
total_cnt = 0
for i,img_url in enumerate(img_urls):
try:
#Chemin de l'image
img_full_path = os.path.join(img_dir, (str(i) + '.jpg'))
print('{}: {} -> {}'.format(str(i), img_url, img_full_path))
re = requests.get(img_url, allow_redirects=False)
if len(re.content) <= 0:
print(u'{}:Ignorer car le contenu de la réponse est vide.'.format(str(i)))
continue
with open(img_full_path, 'wb') as f:
f.write(re.content)
total_cnt = total_cnt + 1
except requests.exceptions.ConnectionError:
continue
except UnicodeEncodeError:
continue
except UnicodeError:
continue
except IsADirectoryError:
continue
print(u'{}: {}J'ai l'image.'.format(keyword, total_cnt))
print(u'L'enregistrement est terminé.')
> cd e:\python\ml\src\img_scraper
> python main.py
Shelty:Nous avons acquis 270 images.
Corgi:Nous avons acquis 286 images.
Border collie:Nous avons acquis 281 images.
Il semble que certains d'entre eux n'ont pas pu enregistrer correctement l'image.
Supprimez les images qui ne peuvent pas être utilisées comme données d'enseignant. Par exemple, d'autres races de chiens sont affichées ensemble ou il y a beaucoup de texte dedans, alors notez le nombre de ces images. Après cela, utilisez Python pour trier les données utilisées pour les données des enseignants et la cible d'exclusion.
# -- coding: utf-8 --
import os, glob
import shutil
#Mot-clé de recherche
KEYWORDS = [u'Shelty', u'Corgi', u'Border collie']
targets = [
[19, 25, 34, 40, 41, 49, 54, 74, 77, 81, 86, 89, 91, 93, 102, 104, 108, 111, 118, 119, 124, 127, 130, 131, 132, 136, 152, 154, 158, 159, 161, 168, 169, 173, 178, 181, 183, 184, 192, 193, 198, 201, 202, 213, 218, 233, 235, 236, 238, 240, 243, 245, 246, 248, 249, 252, 255, 264, 265, 269, 271, 272, 280, 283, 284, 287, 294, 295],
[19, 29, 30, 40, 45, 67, 69, 73, 76, 78, 80, 100, 101, 105, 117, 120, 132, 136, 141, 143, 149, 151, 154, 158, 167, 170, 179, 180, 183, 186, 200, 201, 208, 213, 220, 224, 225, 228, 234, 235, 241, 243, 247, 248, 250, 253, 259, 262, 264, 266, 273, 277, 278, 279, 281, 282, 283, 285, 290, 293, 294, 298, 299],
[9, 21, 25, 37, 38, 40, 41, 42, 49, 52, 55, 61, 65, 66, 71, 72, 78, 80, 89, 93, 96, 103, 108, 110, 113, 114, 118, 122, 126, 127, 128, 145, 146, 152, 158, 160, 161, 164, 166, 167, 171, 174, 175, 176, 182, 183, 186, 187, 193, 194, 196, 197, 200, 202, 203, 206, 207, 222, 223, 224, 226, 228, 230, 232, 233, 234, 237, 238, 241, 243, 244, 257, 259, 260, 262, 263, 264, 265, 267, 268, 270, 273, 275, 276, 277, 278, 281, 282, 283, 287, 289, 292, 293, 295]
]
for idx, keyword in enumerate(KEYWORDS):
total_count = 0
#Original
img_dir = os.path.join('./../data/img/original', keyword)
#Copier
os.makedirs(os.path.join('./../data/img/trimmed', keyword), exist_ok=True)
os.makedirs(os.path.join('./../data/img/excluded', keyword), exist_ok=True)
files = glob.glob(os.path.join(img_dir, '*.jpg'))
for f in files:
if int(os.path.splitext(os.path.basename(f))[0]) in targets[idx]:
shutil.copy2(f, os.path.join('./../data/img/excluded', keyword))
print(u'{} :C'est une cible d'exclusion.'.format(f))
else:
shutil.copy2(f, os.path.join('./../data/img/trimmed', keyword))
print(u'{} :Utilisé pour les données des enseignants.'.format(f))
total_count = total_count + 1
print(u'{} :Le nombre de données pouvant être utilisées{}C'est une question.'.format(keyword, total_count))
print(u'L'enregistrement est terminé.')
> cd e:\python\ml\src\img_trimmer
> python main.py
Shelty:Le nombre de données utilisables est de 202.
Corgi:Le nombre de données utilisables est de 223.
Border collie:Le nombre de données utilisables est de 187.
Seuls 60 à 70% peuvent être utilisés comme données sur les enseignants.
Gonflez le nombre de données en dupliquant et en traitant l'image avec ImageDataGenerator de Keras.
# -- coding: utf-8 --
import os
import glob
import numpy as np
from keras.preprocessing.image import ImageDataGenerator, load_img, img_to_array, array_to_img
CATEGORIES = [u'Shelty', u'Corgi', u'Border collie']
#Taille de l'image
IMG_SIZE = 150
#Définir ImageDataGenerator
DATA_GENERATOR = ImageDataGenerator(horizontal_flip=0.3, zoom_range=0.1)
for idx, category in enumerate(CATEGORIES):
#Original
img_dir = os.path.join('./../data/img/trimmed', category)
#Copier
out_dir = os.path.join('./../data/img/extended', category)
os.makedirs(out_dir, exist_ok=True)
files = glob.glob(os.path.join(img_dir, '*.jpg'))
for i, file in enumerate(files):
img = load_img(file)
img = img.resize((IMG_SIZE, IMG_SIZE))
x = img_to_array(img)
x = np.expand_dims(x, axis=0)
g = DATA_GENERATOR.flow(x, batch_size=1, save_to_dir=out_dir, save_prefix='img', save_format='jpg')
for i in range(10):
batch = g.next()
print(u'{} :Le nombre de fichiers{}C'est une question.'.format(category, len(os.listdir(out_dir))))
> cd e:\python\ml\src\img_duplicator
> python main.py
Using TensorFlow backend.
Shelty:Le nombre de fichiers est de 1817.
Corgi:Le nombre de fichiers est de 1983.
Border collie:Le nombre de fichiers est de 1708.
Puisque nous avons préparé un grand nombre d'images, nous allons créer des données sur les enseignants. Je vais étiqueter l'image. Environ 20% de toutes les données sont utilisées pour les données de test. Enregistrez les données de l'enseignant / du test créées.
# -*- coding: utf-8 -*-
from PIL import Image
import os, glob
import numpy as np
import random, math
from sklearn.model_selection import train_test_split
from keras.utils import np_utils
#Le chemin du répertoire racine dans lequel l'image est stockée
IMG_ROOT_DIR = './../data/img/extended'
#Catégorie
CATEGORIES = [u'Shelty', u'Corgi', u'Border collie']
#densité
DENSE_SIZE = len(CATEGORIES)
#Taille de l'image
IMG_SIZE = 150
#données d'image
X = []
#Données de catégorie
Y = []
#Données des enseignants
X_TRAIN = []
Y_TRAIN = []
#données de test
X_TEST = []
Y_TEST = []
#Destination de stockage des données
TRAIN_TEST_DATA = './../data/train_test_data/data.npy'
#Processus par catégorie
for idx, category in enumerate(CATEGORIES):
#Répertoire d'images pour chaque étiquette
image_dir = os.path.join(IMG_ROOT_DIR, category)
files = glob.glob(os.path.join(image_dir, '*.jpg'))
for f in files:
#Redimensionner chaque image et la convertir en données
img = Image.open(f)
img = img.convert('RGB')
img = img.resize((IMG_SIZE, IMG_SIZE))
data = np.asarray(img)
X.append(data)
Y.append(idx)
X = np.array(X)
Y = np.array(Y)
#Normalisation
X = X.astype('float32') /255
Y = np_utils.to_categorical(Y, DENSE_SIZE)
#Séparez les données des enseignants et les données des tests
X_TRAIN, X_TEST, Y_TRAIN, Y_TEST = train_test_split(X, Y, test_size=0.20)
#Enregistrer les données de l'enseignant / du test
np.save(TRAIN_TEST_DATA, (X_TRAIN, X_TEST, Y_TRAIN, Y_TEST))
print(u'La création des données de l'enseignant / du test est terminée.: {}'.format(TRAIN_TEST_DATA))
> cd e:\python\ml\src\train_test_data_generator
> python main.py
Using TensorFlow backend.
La création des données de l'enseignant / du test est terminée.: ./../data/train_test_data/data.npy
Maintenant que les données de l'enseignant / du test sont prêtes, il est temps de créer le modèle. Enregistrez le modèle construit.
# -*- coding: utf-8 -*-
#Construire un modèle
from keras import layers, models
from keras import optimizers
import numpy as np
import matplotlib.pyplot as plt
import os
#Catégorie
CATEGORIES = [u'Shelty', u'Corgi', u'Border collie']
#densité
DENSE_SIZE = len(CATEGORIES)
#Taille de l'image
IMG_SIZE = 150
INPUT_SHAPE = (IMG_SIZE, IMG_SIZE,3)
#Données des enseignants
X_TRAIN = []
Y_TRAIN = []
#données de test
X_TEST = []
Y_TEST = []
#Destination de stockage des données
TRAIN_TEST_DATA = './../data/train_test_data/data.npy'
#Destination d'enregistrement du modèle
MODEL_ROOT_DIR = './../data/model/'
# -----Construction de modèles----- #
model = models.Sequential()
model.add(layers.Conv2D(32,(3,3),activation="relu",input_shape=INPUT_SHAPE))
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.Conv2D(64,(3,3),activation="relu"))
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.Conv2D(128,(3,3),activation="relu"))
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.Conv2D(128,(3,3),activation="relu"))
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.Flatten())
model.add(layers.Dropout(0.5))
model.add(layers.Dense(512,activation="relu"))
model.add(layers.Dense(DENSE_SIZE,activation="sigmoid"))
#Confirmation de la configuration du modèle
model.summary()
# ----- /Construction de modèles----- #
# -----Compilation de modèles----- #
model.compile(loss="binary_crossentropy",
optimizer=optimizers.RMSprop(lr=1e-4),
metrics=["acc"])
# ----- /Construction de modèles----- #
# -----Apprentissage de modèle----- #
#Lire les données des enseignants et les données des tests
X_TRAIN, X_TEST, Y_TRAIN, Y_TEST = np.load(TRAIN_TEST_DATA)
model = model.fit(X_TRAIN,
Y_TRAIN,
epochs=10,
batch_size=6,
validation_data=(X_TEST, Y_TEST))
# ----- /Apprentissage de modèle----- #
# -----Graphique des résultats d'apprentissage----- #
acc = model.history['acc']
val_acc = model.history['val_acc']
loss = model.history['loss']
val_loss = model.history['val_loss']
epochs = range(len(acc))
plt.plot(epochs, acc, 'bo', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='Validation acc')
plt.title('Training and validation accuracy')
plt.legend()
plt.savefig(os.path.join(MODEL_ROOT_DIR, 'Training_and_validation_accuracy.png'))
plt.figure()
plt.plot(epochs, loss, 'bo', label='Training loss')
plt.plot(epochs, val_loss, 'b', label='Validation loss')
plt.title('Training and validation loss')
plt.legend()
plt.savefig(os.path.join(MODEL_ROOT_DIR, 'Training_and_validation_loss.png'))
# ----- /Graphique des résultats d'apprentissage----- #
# -----Enregistrer le modèle----- #
#Enregistrer le modèle
json_string = model.model.to_json()
open(os.path.join(MODEL_ROOT_DIR, 'model_predict.json'), 'w').write(json_string)
#Stockage du poids
model.model.save_weights(os.path.join(MODEL_ROOT_DIR, 'model_predict.hdf5'))
# ----- /Enregistrer le modèle----- #
> cd e:\python\ml\src\model_generator
> python main.py
Using TensorFlow backend.
2019-11-15 17:02:03.400229: I tensorflow/core/platform/cpu_feature_guard.cc:142] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
Model: "sequential_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_1 (Conv2D) (None, 148, 148, 32) 896
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 74, 74, 32) 0
_________________________________________________________________
conv2d_2 (Conv2D) (None, 72, 72, 64) 18496
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 36, 36, 64) 0
_________________________________________________________________
conv2d_3 (Conv2D) (None, 34, 34, 128) 73856
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 17, 17, 128) 0
_________________________________________________________________
conv2d_4 (Conv2D) (None, 15, 15, 128) 147584
_________________________________________________________________
max_pooling2d_4 (MaxPooling2 (None, 7, 7, 128) 0
_________________________________________________________________
flatten_1 (Flatten) (None, 6272) 0
_________________________________________________________________
dropout_1 (Dropout) (None, 6272) 0
_________________________________________________________________
dense_1 (Dense) (None, 512) 3211776
_________________________________________________________________
dense_2 (Dense) (None, 3) 1539
=================================================================
Total params: 3,454,147
Trainable params: 3,454,147
Non-trainable params: 0
_________________________________________________________________
Train on 4396 samples, validate on 1100 samples
Epoch 1/10
4396/4396 [==============================] - 103s 23ms/step - loss: 0.5434 - acc: 0.7298 - val_loss: 0.5780 - val_acc: 0.7067
Epoch 2/10
4396/4396 [==============================] - 109s 25ms/step - loss: 0.4457 - acc: 0.7989 - val_loss: 0.4288 - val_acc: 0.8024
Epoch 3/10
4396/4396 [==============================] - 103s 23ms/step - loss: 0.3874 - acc: 0.8318 - val_loss: 0.3992 - val_acc: 0.8170
Epoch 4/10
4396/4396 [==============================] - 106s 24ms/step - loss: 0.3483 - acc: 0.8469 - val_loss: 0.3476 - val_acc: 0.8476
Epoch 5/10
4396/4396 [==============================] - 107s 24ms/step - loss: 0.3029 - acc: 0.8717 - val_loss: 0.3085 - val_acc: 0.8603
Epoch 6/10
4396/4396 [==============================] - 109s 25ms/step - loss: 0.2580 - acc: 0.8947 - val_loss: 0.2918 - val_acc: 0.8736
Epoch 7/10
4396/4396 [==============================] - 107s 24ms/step - loss: 0.2182 - acc: 0.9084 - val_loss: 0.2481 - val_acc: 0.8970
Epoch 8/10
4396/4396 [==============================] - 113s 26ms/step - loss: 0.1855 - acc: 0.9217 - val_loss: 0.1920 - val_acc: 0.9209
Epoch 9/10
4396/4396 [==============================] - 120s 27ms/step - loss: 0.1548 - acc: 0.9394 - val_loss: 0.1775 - val_acc: 0.9345
Epoch 10/10
4396/4396 [==============================] - 114s 26ms/step - loss: 0.1243 - acc: 0.9530 - val_loss: 0.1738 - val_acc: 0.9412
Il est enfin temps de préparer un programme de jugement sheltie. Il est temps de préparer une image pour confirmation.
# -*- coding: utf-8 -*-
from keras import models
from keras.models import model_from_json
from keras.preprocessing import image
import numpy as np
import sys
import os
from keras.preprocessing.image import ImageDataGenerator, load_img, img_to_array, array_to_img
#Destination d'enregistrement du modèle
MODEL_ROOT_DIR = './../data/model/'
MODEL_PATH = os.path.join(MODEL_ROOT_DIR, 'model_predict.json')
WEIGHT_PATH = os.path.join(MODEL_ROOT_DIR, 'model_predict.hdf5')
#Catégorie
CATEGORIES = [u'Shelty', u'Corgi', u'Border collie']
#Taille de l'image
IMG_SIZE = 150
INPUT_SHAPE = (IMG_SIZE, IMG_SIZE,3)
#Chargez le modèle
model = model_from_json(open(MODEL_PATH).read())
model.load_weights(WEIGHT_PATH)
#Lire l'image à partir de l'argument d'entrée
args = sys.argv
img = image.load_img(args[1], target_size=INPUT_SHAPE)
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
#Prédire avec un modèle
features = model.predict(x)
print(features)
if features[0, 0] == 1:
print(u'C'est Shelty.')
else:
for i in range(0, len(CATEGORIES)):
if features[0, i] == 1:
print(u'Cela ne semble pas être sheltie.{}est.'.format(CATEGORIES[i]))
(ml)> cd e:\python\ml\src\ai
(ml)> python .\main.py '..\data\img\test\sheltie_00.jpg'
Using TensorFlow backend.
2019-11-15 17:58:44.863437: I tensorflow/core/platform/cpu_feature_guard.cc:142] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
[[1. 0. 0.]]
C'est Shelty.
(ml)> python .\main.py '..\data\img\test\corgi_00.jpg'
Using TensorFlow backend.
2019-11-15 17:58:55.519838: I tensorflow/core/platform/cpu_feature_guard.cc:142] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
[[0. 1. 0.]]
Cela ne semble pas être sheltie. C'est Corgi.
(ml)> python .\main.py '..\data\img\test\bordercollie_00.jpg'
Using TensorFlow backend.
2019-11-15 17:59:06.457517: I tensorflow/core/platform/cpu_feature_guard.cc:142] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
[[0. 0. 1.]]
Cela ne semble pas être sheltie. C'est un border collie.
sheltie_00.jpg C'est Shelty.
cogy_00.jpg Cela ne semble pas être sheltie. C'est Corgi.
bordercolli_00.png Cela ne semble pas être sheltie. C'est un border collie.
J'ai pu le juger d'une bonne manière.
Comment Fran-chan, qui est également utilisé pour l'icône, sera-t-il jugé?
(ml)> python .\main.py '..\data\img\test\fran.jpg'
Using TensorFlow backend.
2019-11-15 17:59:28.118592: I tensorflow/core/platform/cpu_feature_guard.cc:142] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
[[0. 0. 1.]]
Cela ne semble pas être sheltie. C'est un border collie.
fran.png Cela ne semble pas être sheltie. C'est un border collie.
Pardon. .. .. Bien que mon Fran soit un sheltie, il a été jugé que "cela ne semble pas être un sheltie. C'est un border collie." La raison est probablement qu'il y avait peu de shelties noires dans les données des enseignants. J'étais parfaitement conscient de l'importance des données sur les enseignants.
J'ai changé l'image et je me suis vengé.
(ml)> python .\main.py '..\data\img\test\fran_01.jpg'
Using TensorFlow backend.
2019-11-18 17:21:07.929836: I tensorflow/core/platform/cpu_feature_guard.cc:142] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
[[1. 0. 0.]]
C'est Shelty.
Notre Fran a été jugée comme un refuge.
--Ajoutez du noir aux données des enseignants et à la vengeance