J'ai créé une application qui classe automatiquement les images des caractères recommandés dans des dossiers distinctifs.
Cette fois, nous utilisons une bibliothèque d'apprentissage automatique appelée pytorch et une API appelée tweepy qui peut apprendre des informations sur Twitter.
Il est difficile de voir toute la chronologie de Twitter, je souhaite donc enregistrer uniquement l'image du personnage recommandé Je voulais créer quelque chose en utilisant tweeypy et l'apprentissage automatique Le tutoriel d'apprentissage par transfert de pytorch était merveilleux, j'ai donc voulu l'utiliser. Je voulais faire l'expérience des problèmes qui se posent lors de la création d'une application d'apprentissage automatique.
Un modèle formé est préparé à l'avance dans Pytorch et il est facile à utiliser. Dans le didacticiel pytorch, je l'ai utilisé et modifié pour l'adapter à la tâche en fonction de la méthode d'apprentissage par transfert. Dans cette tâche, en supposant qu'il existe une image réelle et une image bidimensionnelle sur Twitter, et que l'image bidimensionnelle a une structure d'une image du personnage cible et une image qui ne l'est pas, d'abord l'animation et la réalité J'ai fait un modèle pour identifier l'image, puis j'ai fait un modèle pour identifier à nouveau l'image bidimensionnelle.
Plus précisément, la première méthode utilisée consistait à changer la couche entièrement connectée du res-net18 entraîné en une couche connectée d'une taille adaptée à la classe, et à donner au modèle une image de la tâche pour le recycler.
Dès le début, le taux de discrimination entre les images réelles et non réelles était très élevé, dépassant environ 95% ou plus, mais le taux de discrimination d'un caractère spécifique n'était pas aussi élevé que 70%, et nous avons essayé de l'améliorer par diverses méthodes.
La première chose que j'ai essayée a été de changer de modèle. Il existe des modèles entraînés dans pytorch, j'ai donc essayé d'utiliser alex-net parmi eux. Cependant, la précision ne s'est pas améliorée en la changeant simplement, alors je suis retourné à resnet.
Au début, nous nous entraînions avec SGD comme algorithme d'optimisation, mais nous avons changé cela et avons décidé d'utiliser Adam. Cependant, ce n'était pas du tout exact, et Adam a entendu dire que les hyperparamètres étaient importants, il a donc décidé d'utiliser optuma, une bibliothèque de recherche d'hyperparamètres.
optuna oputuna est une bibliothèque qui apporte des valeurs numériques de la distribution pour les hyper paramètres que vous souhaitez optimiser. La procédure spécifique consiste à définir d'abord la fonction objectif qui contient la valeur numérique et le para haut que vous souhaitez optimiser.
fonction objective
def objective(trial):
lr =trial.suggest_loguniform('lr', 1e-6, 1e-4)
beta1 =trial.suggest_uniform('beta1', 0.8, 0.95)
beta2 =trial.suggest_uniform('beta2', 0.9, 0.99)
eps =trial.suggest_loguniform('eps', 1e-9,1e-7)
gamma = trial.suggest_loguniform('gamma',0.05,0.2)
model_ft = models.resnet18(pretrained=True)
num_ftrs = model_ft.fc.in_features
model_ft.fc = nn.Linear(num_ftrs, 2)
model_ft = model_ft.to(device)
criterion = nn.CrossEntropyLoss()
optimizer_ft = optim.Adam(model_ft.parameters(), lr=lr, betas=(beta1, beta2), eps=eps, weight_decay=0, amsgrad=False)
exp_lr_scheduler = lr_scheduler.StepLR(optimizer_ft, step_size=7, gamma=gamma)
model_ft,best_loss,best_acc = train_model(model_ft, criterion, optimizer_ft, exp_lr_scheduler)
return 1 - best_acc
La mise en garde ici est que lorsque vous renvoyez le nombre que vous souhaitez optimiser, vous devez le définir comme un problème de minimisation. Cette fois, je veux maximiser la précision, donc je soustrais la précision de 1 et renvoie la valeur. Il semble qu'il existe diverses autres fonctions, mais cette fois j'ai appris facilement.
study
study = optuna.create_study()
study.optimize(objective, n_trials=2)
Après avoir défini la fonction objectif, créez un objet d'étude, transmettez-lui la fonction objectif et le nombre d'essais, et les hyper paramètres seront réglés automatiquement.
Lorsque j'ai réglé les hyper paramètres d'Adam ici, il y avait une bonne amélioration de la précision. 77% sur resnet Il y avait une amélioration de 75% sur alex-net.
Ici, j'ai décidé d'adopter une approche telle que l'augmentation de la quantité de données et la modification de la résolution.
Premièrement, lorsque nous avons doublé la quantité de données, la précision s'est améliorée à environ 83%. Après cela, lorsque j'ai amélioré la résolution, la précision était d'environ 90%.
Je n'entrerai pas dans les détails ici, mais en un mot, c'est une technologie qui visualise où CNN regarde et prend des décisions, en tenant compte de l'influence de chaque classe.
https://github.com/kazuto1011/grad-cam-pytorch Une méthode telle que gradcam est implémentée ici afin qu'elle puisse être utilisée avec pytorch, et je l'ai implémentée en référence à la démo de ceci.
image Image lors de l'évaluation comme F Image en jugeant comme T
tweepy Une bibliothèque qui englobe les API fournies par Twitter, où vous pouvez apprendre la chronologie et suivre les utilisateurs. Cependant, comme une mise en garde
Il est devenu. Le déroulement de ce processus consiste à apprendre d'abord les tweets sur la chronologie, puis à déterminer celui qui a l'image.
Processus pour déterminer si l'URL a une image
import tweepy
import keys
import classifierImage
def main():
auth = tweepy.OAuthHandler(keys.consumer_key,keys.consumer_secret)
auth.set_access_token(keys.access_token,keys.access_token_secret)
api = tweepy.API(auth)
public_tweets = api.home_timeline(count=200)
urls = []
for tweet in public_tweets:
if 'media' in tweet.entities:
for media in tweet.entities['media']:
#print(media['media_url'])
urls.append(media['media_url'])
classifierImage.downloadImage(urls)
if __name__=='__main__':
main()
Ensuite, appelez le modèle entraîné enregistré. Apprenez les données d'image à partir de l'URL de l'argument et convertissez les données binaires en objet Image PIL. Prétraitez-le avec Torchvision, jugez-le avec le modèle et décidez de la destination du téléchargement.
Un programme qui juge et enregistre les images
import urllib.request
import torch
import numpy as np
import io
from PIL import Image
import cv2
from torchvision import transforms,models
import torch.nn as nn
def downloadImage(imageUrls):
tgts=[]
for url in imageUrls:
filename = url.split('/')[-1]
tgt = urllib.request.urlopen(url).read()
tgts.append((tgt,filename))
toTe = transforms.ToTensor()
nor = transforms.Normalize([0.5,0.5,0.5],[0.5,0.5,0.5])
co = transforms.Compose([
transforms.Resize(512),
transforms.CenterCrop(448),
transforms.ToTensor(),
transforms.Normalize([0.5,0.5,0.5],[0.5,0.5,0.5])
])
#tensors = torch.cat(tgs,dim=0)
classfier_anime_model = models.resnet18(pretrained=True)
num_ftrs = classfier_anime_model.fc.in_features
classfier_anime_model.fc = nn.Linear(num_ftrs, 2)
classfier_anime_model.load_state_dict(torch.load('classfierAnime'))
classfier_anime_model.eval()
classfier_Koishi_model = models.resnet18(pretrained=True)
num_ftrs_k = classfier_Koishi_model.fc.in_features
classfier_Koishi_model.fc = nn.Linear(num_ftrs_k, 2)
classfier_Koishi_model.load_state_dict(torch.load('classfierKoishi1'))
classfier_Koishi_model.eval()
with torch.no_grad():
for i,tg in enumerate(tgts):
t = Image.open(io.BytesIO(tg[0])).convert('RGB')
print(t)
t = co(t)
t = t.unsqueeze(0)
out = classfier_anime_model(t)
_,preds = torch.max(out,1)
print(out)
if preds[0]==1:
out_k = classfier_Koishi_model(t)
_,preds_k = torch.max(out_k,1)
if preds_k[0]==0:
with open("img/"+tg[1], mode='wb') as f:
f.write(tg[0])
else:
with open("imgKoishi/"+tg[1], mode='wb') as f:
f.write(tg[0])
else:
with open("realImg/"+tg[1], mode='wb') as f:
f.write(tg[0])
Le taux d'identification pour savoir s'il s'agissait d'une image réelle était très bon et satisfaisant. Il n'y a pratiquement pas eu d'oubli pour déterminer s'il y avait un caractère spécifique, mais bon nombre des éléments jugés vrais ne remplissaient pas les conditions. (Le rappel coûte cher, mais Pressision l'est autant) Il est probable que la cause de ceci est que les images enregistrées sont biaisées et que l'identification des images qui ne remplissent pas les conditions qui n'ont pas été enregistrées n'a pas réussi. Un autre problème qui s'est produit était que l'image du personnage cible n'apparaissait pas sur la chronologie au début, donc j'étais confus parce que je ne pouvais pas juger s'il pouvait être identifié. Grâce à une telle opération réelle, il était bon de constater que des données non apprises empêchent l'identification.
――Je veux pouvoir l'enregistrer régulièrement, mais je ne peux pas laisser mon ordinateur personnel allumé, donc je veux pouvoir le traiter avec une tarte aux framboises. --Je souhaite pouvoir mettre à jour automatiquement le modèle à l'aide de l'image enregistrée.
https://www.slideshare.net/takahirokubo7792/ss-71453093 https://qiita.com/koki-sato/items/c16c8e3445287698b3a8 http://docs.tweepy.org/en/v3.5.0/index.html https://pytorch.org/tutorials/beginner/transfer_learning_tutorial.html https://qiita.com/enmaru/items/2770df602dd7778d4ce6
Recommended Posts