Le traitement du jugement d'image a été effectué à l'aide de Keras. En gros, je l'ai créé en détournant l'article auquel je faisais référence, donc je n'écrirai que les points que j'ai imaginés sous forme de mémo.
Création de la reconnaissance d'image CNN avec Python et Keras
Python:3.7.4 Keras:2.3.4 tensorflow:1.13.1
Cette fois, j'ai appris l'image d'un groupe d'idols appelé "// Necopla //".
Créer un dossier pour chaque membre sous le dossier img pour les images des membres et placer des images pour chaque membre.
J'ai eu l'image de chaque membre sur Twitter.
import json
import config
from urllib import request
from requests_oauthlib import OAuth1Session
from time import sleep
# Paramètre de clé API (défini dans un autre fichier config.py)
CK = config.CONSUMER_KEY
CS = config.CONSUMER_SECRET
AT = config.ACCESS_TOKEN
ATS = config.ACCESS_TOKEN_SECRET
# Processus d'authentification
twitter = OAuth1Session(CK, CS, AT, ATS)
# Point final d'acquisition de la chronologie
get_time_line_url = "https://api.twitter.com/1.1/statuses/user_timeline.json"
# Compte d'acquisition
necopla_menber = ['@yukino__NECOPLA', '@yurinaNECOPLA', '@riku_NECOPLA', '@miiNECOPLA', '@kaori_NECOPLA', '@sakuraNECOPLA', '@miriNECOPLA', '@renaNECOPLA']
necopla_name = {'@yukino__NECOPLA': 'yukino',
'@yurinaNECOPLA': 'yurina',
'@riku_NECOPLA': 'riku',
'@miiNECOPLA': 'mii',
'@kaori_NECOPLA': 'kaori',
'@sakuraNECOPLA': 'sakura',
'@miriNECOPLA': 'miri',
'@renaNECOPLA': 'rena'}
# Définition des paramètres
params = {'q': '-filter:retweets',
'max_id': 0, #ID pour commencer à obtenir
'count': 200}
for menber in necopla_menber:
print(menber)
del params ['max_id'] # Effacer l'ID pour démarrer l'acquisition
# Obtenez les 200 derniers tweets / Obtenez des tweets plus anciens que l'ID défini dans les paramètres ['max_id'] à partir de la deuxième fois
index = 1
for j in range(100):
params['screen_name'] = menber
res = twitter.get(get_time_line_url, params=params)
print(params)
print(res.status_code)
if res.status_code == 200:
#API compte restant
limit = res.headers['x-rate-limit-remaining']
print("API remain: " + limit)
if limit == 1:
sleep(60*15)
n = 0
tweets = json.loads(res.text)
# Quittez la boucle si vous ne pouvez pas obtenir de tweets du compte que vous traitez
print(len(tweets))
if len(tweets) == 0:
break
# Processus par tweet
for tweet in tweets:
if 'extended_entities' in tweet:
for media in tweet['extended_entities']['media']:
url = media['media_url']
if url != '':
request.urlretrieve(url, './img/' + necopla_name[menber] + '/' + necopla_name[menber] + '_' + str(index).zfill(5) + url[-4:] )
index += 1
if len(tweets) >= 1:
print('max_id set')
params['max_id'] = tweets[-1]['id']-1
Avec ce processus, les images sont acquises à partir de Twitter de chaque membre et enregistrées dans le dossier avec le nom de chaque membre.
La prochaine chose que j'ai faite a été de trier les images. J'ai eu 1200 pour de nombreux membres et environ 300 pour quelques membres. À partir de là, j'ai supprimé les annonces, la nourriture, les images à deux prises, etc., et je les ai réduites manuellement aux seules images affichées seules.
Nous avons en outre réduit les images de chaque membre à 250, selon le membre avec le plus petit nombre d'images après la réduction.
coding:utf-8
import keras
from keras.preprocessing.image import load_img, img_to_array
from keras.callbacks import LambdaCallback
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers.convolutional import Conv2D, MaxPooling2D
from keras.layers.core import Dense, Dropout, Activation, Flatten
import matplotlib.pyplot as plt
import numpy as np
from sklearn.model_selection import train_test_split
from keras.models import model_from_json
from PIL import Image
import glob
necopla_name = ['yukino', 'yurina', 'riku', 'mii', 'kaori', 'sakura', 'miri', 'rena']
member_color = ['black', 'blue', 'red', 'green', 'magenta', 'aqua', 'purple', 'yellow']
image_size = 50
epochs = 100
hw = {"height":image_size, "width":image_size}
print('Load images...')
X = []
Y = []
for index, name in enumerate(necopla_name):
dir = "./image/" + name
files = glob.glob(dir + "/*.jpg ")
for i, file in enumerate(files):
image = Image.open(file)
image = image.convert("RGB")
image = image.resize((image_size, image_size))
data = np.asarray(image)
X.append(data)
Y.append(index)
X = np.array(X)
Y = np.array(Y)
X = X.astype('float32')
X = X / 255.0
# Convertir le format d'étiquette correct
Y = np_utils.to_categorical(Y, 8)
print('Create test data...')
# Données d'entraînement et données de test
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.20)
print('Build model...')
# Construire CNN
model = Sequential()
model.add(Conv2D(32, (3, 3), padding='same',input_shape=X_train.shape[1:]))
model.add(Activation('relu'))
model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(64, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(8))
model.add(Activation('softmax'))
# compiler
model.compile(loss='categorical_crossentropy',optimizer='SGD',metrics=['accuracy'])
json_string = ''
passage_array = [[0] * epochs] * len(necopla_name)
passage_array = []
for i in range(len(necopla_name)):
passage_array.append([0] * epochs)
# Exécuter à la fin de l'apprentissage
def on_train_end(logs):
print('----- saving model...')
model.save_weights("necopla_image_model" + 'w.hdf5')
model.save("necopla_image_model.hdf5")
# Exécuter à la fin de l'époque
def on_epoch_end(epoch, logs):
print ('##' + str (epoch + 1) + 'th time')
print('## yurina.jpg evaluate...')
img = load_img('yurina.jpg', target_size=(hw["height"], hw["width"]))
TEST = img_to_array(img) / 255
pred = model.predict(np.array([TEST]), batch_size=1, verbose=0)
print (">> Résultat du calcul ↓ \ n" + str (pred))
print (">> Cette image est" "+ necopla_name [np.argmax (pred)] +" ".")
for i, p in enumerate(pred):
for j, pp in enumerate(p):
passage_array[j][epoch] = pp
print('## yukino.jpg evaluate...')
img = load_img('yukino.jpg', target_size=(hw["height"], hw["width"]))
TEST = img_to_array(img) / 255
pred = model.predict(np.array([TEST]), batch_size=1, verbose=0)
print (">> Résultat du calcul ↓ \ n" + str (pred))
print (">> Cette image est" "+ necopla_name [np.argmax (pred)] +" ".")
print_callback = LambdaCallback(on_epoch_end=on_epoch_end,on_train_end=on_train_end)
# Entraînement
history = model.fit(X_train, y_train, epochs=epochs, callbacks=[print_callback])
# Sortie des résultats d'évaluation et d'évaluation
print(model.evaluate(X_test, y_test))
print('Output picture...')
x_datas = range(1, epochs+1)
y_datas = [ i / 10 for i in range(0, 10) ]
plt.xlim(1, epochs + 1)
plt.ylim(0, 1)
fig = plt.figure(figsize=(6, 4), dpi=72, facecolor="black", edgecolor="black", linewidth=2)
ax = plt.subplot(1, 1, 1)
for i, passage in enumerate(passage_array):
ax.plot(passage, color=member_color[i], label=necopla_name[i])
fig.savefig("passege.png ", edgecolor="black")
plt.close()
Fondamentalement, la plupart des codes auxquels j'ai fait référence sont détournés.
Comme point que j'ai conçu, je voulais voir ce que serait le processus d'apprentissage, alors j'ai ajouté les deux points suivants.
・ Juger l'image à la fin de l'époque ・ Afficher le résultat du calcul pour chaque membre dans un graphique
Pour juger l'image, donnez les images de deux membres comme entrée et confirmez qui est jugé.
## Première fois
yurina.jpg evaluate...
>> Résultat du calcul ↓
[[0.12650199 0.12684263 0.12742536 0.12854463 0.11904926 0.1264687
0.1201202 0.12504727]]
>> Cette image est "mii".
yukino.jpg evaluate...
>> Résultat du calcul ↓
[[0.13068683 0.12408765 0.1275352 0.12792543 0.12050408 0.13144182
0.11644448 0.1213745 ]]
>> Cette image est "sakura".
Epoch 2/100
1600/1600 [==============================] - 12s 8ms/step - loss: 2.0785 - accuracy: 0.1456
## Deuxième fois
yurina.jpg evaluate...
>> Résultat du calcul ↓
[[0.12513563 0.12735145 0.12925902 0.12473622 0.12179873 0.12717892
0.11717195 0.12736808]]
>> Cette image est "riku".
yukino.jpg evaluate...
>> Résultat du calcul ↓
[[0.12863007 0.12423173 0.12936181 0.12356193 0.12369796 0.13277659
0.11367439 0.1240655 ]]
>> Cette image est "sakura".
(Omis)
## 100e fois
yurina.jpg evaluate...
>> Résultat du calcul ↓
[[4.8989324e-10 8.2380754e-01 7.1863423e-07 3.2110822e-03 1.7282969e-01
1.9806185e-08 3.1989657e-05 1.1890962e-04]]
>> Cette image est "yurina".
yukino.jpg evaluate...
>> Résultat du calcul ↓
[[6.1400205e-01 2.8108407e-03 4.0069546e-04 1.0979763e-03 3.1650570e-01
6.4887889e-02 8.5816224e-05 2.0912322e-04]]
>> Cette image est "yukino".
Le premier a renvoyé le mauvais résultat, mais quand il a atteint la centième fois, les deux sont venus pour porter un jugement correct.
Le graphique ci-dessous est un graphique des résultats des calculs à la fin de chaque époque. Le graphique ne représente que le résultat du jugement de l'image de "yurina".
Le bleu du graphique est "yurina" et le rose "kaori". En conséquence, je m'attendais à un graphique dans lequel la ligne bleue converge vers 1. En regardant ce résultat, nous pouvons voir qu'il est difficile de juger ces deux personnes avec les données d'entraînement actuelles.
C'est vraiment intéressant. Pour le moment, j'ai essayé de le mettre en œuvre en pensant à le faire pour étudier, mais j'essaierai d'en savoir plus en lisant des livres, etc. pour des idées pour améliorer la précision.
Recommended Posts