Dans l'article que j'ai lu auparavant, il y avait un article intéressant avec le titre ** Reproduction de symboles sonores par apprentissage automatique: Génération du Pokémon le plus fort **. Je l'ai arrangé moi-même en référence à cet article et je l'ai utilisé pour la présentation du séminaire, je vais donc le publier. Je l'ai fait avec un peu d'énergie, alors je l'ai posté parce que je voulais le lancer dans le monde extérieur.
Je m'occupe généralement de systèmes d'images, et comme le traitement du langage naturel est un premier article amateur, je pense qu'il y a beaucoup de points qui ne peuvent être atteints, mais pardonnez-moi s'il vous plaît. * Lien matériel utilisé dans la présentation du séminaire
Cette fois, en se référant aux idées des articles suivants, nous viserons à générer le Pokémon le plus fort par la même méthode tout en ajoutant l'accent de l'apprentissage profond (LSTM). Dans l'article, le questionnaire sujet a été utilisé pour quantifier l'impression de son, mais comme nous ne disposons pas de telles données, nous utiliserons la valeur de race à la place.
Reproduction de symboles sonores par apprentissage automatique: Génération du Pokémon le plus puissant Satoshi Miura ∗ 1 Masaki Murata ∗ 1 Sho Yasuda ∗ 2 Mai Miyabe ∗ 2 Eiji Aramaki ∗ 2 ∗ 1 École supérieure de l'Université Tottori * 2 Actes de la 18e réunion annuelle de la Société de traitement du langage de l'Université (mars 2012) http://luululu.com/paper/2012/C1-1.pdf
・ Prédisez la force de Pokémon par comparaison de paires avec 8 sujets (qui ne connaissent pas Pokémon). -Utilisez-les comme données d'entraînement pour générer un modèle avec SVM. -Utilisez le modèle, changez le nom du Pokémon et répétez le jugement de force pour générer le Pokémon le plus fort.
Les données utilisées cette fois sont les données de table de Pokémon jusqu'à la 7ème génération. Étant donné que le nom d'un Pokémon peut comporter jusqu'à 6 caractères, supprimez la valeur de Pokémon (Landros Beast, Jigarde 10%, etc.) avec un nom supérieur à cela. De plus, cette fois, la méga évolution Pokemon était également exclue.
Les données Pokémon sont empruntées au lien ci-dessous.
https://rikapoke.hatenablog.jp/entry/pokemon_datasheet_gne7
import pandas as pd
status = pd.read_csv("pokemon_status.csv", encoding="shift_jis")
status
Données CSV traitées cette fois ↓
Nous ajouterons un prétraitement à cela.
#Suppression de méga Pokémon supplémentaires
status = status[~status['Numéro du livre d'images'].str.contains('-')]
status
#Pokémon supprimé dont le nom est 7 ou plus
status['len'] = status['Nom du Pokémon'].map(lambda x: len(x))
de = status[status['len']>6]
status = status[status['len']<7]
de
#Pour les données uniquement les données utilisées
status = status.loc[:, ['Nom du Pokémon','total']]
status
Complétion des données utilisées cette fois!
De là, nous continuerons le prétraitement pour alimenter le LSTM.
#tokenize
def function(name):
n_gram = ''
for n in name:
n_gram = n_gram + n + ' '
return n_gram
status['Nom du Pokémon'] = status['Nom du Pokémon'].map(function)
status
#Normalisation de la valeur raciale& 0or1
from sklearn import preprocessing
def labeling(pred, p=0.5):
if pred < p:
pred_label = 0
else:
pred_label = 1
return pred_label
status['total'] = preprocessing.minmax_scale(status['total'])
status['total'] = status['total'].map(labeling)
status
Données après prétraitement ↓
Classez les données créées en train et val et enregistrez.
from sklearn.model_selection import train_test_split
train_df, val_df = train_test_split(status, random_state=1234, test_size=0.2)
train_df.to_csv("./train_df.tsv", sep='\t')
val_df.to_csv("./val_df.tsv", sep='\t')
Puisque je suis un partisan du pytorch, je vais construire un modèle avec une torche et présenter brièvement le code. Le code complet est disponible sur le lien ci-dessous, donc si vous êtes intéressé, veuillez vous y référer.
https://github.com/drop-ja/pokemon
from torchtext import data
import torchtext
batch_size = 4
max_len = 6
#méthode tokenize
tokenizer = lambda x: x.split()
#Informations sur les étiquettes, etc.
TEXT = data.Field(sequential=True, tokenize=tokenizer, include_lengths=True,
batch_first=True, fix_length=max_len)
LABEL = data.LabelField()
fields_train = [('id', None), ('name', TEXT), ('bs', LABEL)]
dataset_train, dataset_valid = data.TabularDataset.splits(
path = './',
format='TSV',
skip_header=True,
train="train_df.tsv",
validation="val_df.tsv",
fields=fields_train)
TEXT.build_vocab(dataset_train)
LABEL.build_vocab(dataset_train)
train_iter = data.BucketIterator(dataset=dataset_train, batch_size=batch_size,
sort_key=lambda x: len(x.name), repeat=False, shuffle=True)
val_iter = data.BucketIterator(dataset=dataset_valid, batch_size=1,
sort_key=lambda x: len(x.name), repeat=False, shuffle=False)
#Définition du modèle
import torch
import torch.nn as nn
import torch.nn.init as init
import torch.optim as optim
import torch.nn.functional as F
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
class LSTMPVClassifier(nn.Module):
def __init__(self, vocab_size, embedding_dim, lstm_hidden_size, mlp_hidden_size, output_size):
super(LSTMPVClassifier, self).__init__()
self.lstm_hidden_size = lstm_hidden_size
self.embed = nn.Embedding(vocab_size, embedding_dim, padding_idx=1)
self.lstm = nn.LSTM(embedding_dim, self.lstm_hidden_size, batch_first=True,
num_layers=1, bidirectional=False, dropout=0.0)
self.fc1 = nn.Linear(self.lstm_hidden_size, mlp_hidden_size)
self.fc2 = nn.Linear(mlp_hidden_size, output_size)
def forward(self, x):
b_size = x.size(0) #Taille du lot
seq_len = x.size(1) #Longueur du nom Pokemon
x = self.embed(x)
h0 = torch.zeros(1, b_size, self.lstm_hidden_size).to(device)
c0 = torch.zeros(1, b_size, self.lstm_hidden_size).to(device)
lstm_output_seq, (h_n, c_n) = self.lstm(x, (h0, c0))
out = torch.relu(self.fc1(lstm_output_seq))
out = torch.sigmoid(self.fc2(out))
return out
Voici le résultat de l'obtention de 10 Epoch avec le modèle ci-dessus. «Total» est l'étiquette de réponse correcte et «Valeur prédite» est le résultat prédit par le modèle.
Comment afficher la valeur F du résultat ci-dessus. Une valeur assez bonne est renvoyée pour un modèle approprié.
J'ai mis un nom et j'ai joué avec. J'ai mis les noms des membres du laboratoire et je les ai classés, et c'était assez excitant de jouer avec ça.
Code ci-dessous
#Base de données
#Vérifiez la valeur convertie
def to_dataset(list_obj, pri=True):
index = pd.DataFrame(list_obj)
index[0] = index[0].map(function)
index.to_csv('./test.tsv', sep='\t')
fields_test = [('id', None), ('name', TEXT)]
dataset_test = data.TabularDataset(path='./test.tsv',
format='TSV', skip_header=True, fields=fields_test)
test_iter = data.BucketIterator(dataset=dataset_test, batch_size=1,
sort_key=lambda x: len(x.name), repeat=False, shuffle=False)
batch = next(iter(test_iter))
if pri:
print(batch.name)
return test_iter
list_obj = ['Bouilloire Denshi', 'Gagigugego', 'four micro onde', 'Poêle à frire', 'Jisaboke', 'Pokémon']
test_iter = to_dataset(list_obj)
def result_show(test_iter, pri=True):
test_predicted = []
for batch in test_iter:
text = batch.name[0]
text = text.to(device)
outputs = eval_net(text)
outputs = outputs[:, -1]
tmp_pred_label = outputs.to('cpu').detach().numpy().copy()
test_predicted.extend(tmp_pred_label[0])
if pri:
print(test_predicted)
return test_predicted
result = result_show(test_iter)
df = pd.DataFrame(list_obj, columns=['Nom'])
df['Valeur prédite'] = result
df['0,1 étiquette'] = labeling(df['Valeur prédite'])
df
C'est enfin le sujet.
La méthode de génération de Pokémon la plus puissante suit le papier et est générée par la même méthode.
** Méthode papier ** --Sélectionnez un échantillon de manière appropriée --Remplacer un personnage au hasard
Dans l'article, il a été généré à partir de "Parasect" et "Nidoquin", donc je vais le suivre. Le code ci-dessous.
def generate_pokemon(string):
history = []
score = []
history.append(string)
for i in range(50):
changed_string = change_name(string, 1)
cd_result = result_show(to_dataset([string, changed_string], False), False)
#Ajouter seulement au début
if i ==0:
score.append(cd_result[0])
if cd_result[0] > cd_result[1]:
score.append(cd_result[0])
else:
string = changed_string
score.append(cd_result[1])
history.append(string)
cd_df = pd.DataFrame(history, columns=['Nom'])
cd_df['Valeur prédite'] = score
return string, cd_df
string = 'Parasect'
saikyou, port = generate_pokemon(string)
print('Nom le plus fort: ', saikyou)
pd.DataFrame(port)
Résultat de génération de parasect (processus 10/50)
Le résultat final est "Egineo". Comme les personnages sont échangés au hasard, il était intéressant que le résultat change à chaque fois que je l'ai tourné, et je l'ai tourné plusieurs fois. C'est amusant de bouger tout en vérifiant les résultats de cette façon.
Aussi, j'ai utilisé Pokemon cette fois, mais il semble intéressant de le faire avec le nom du magasin de ramen et l'évaluation du journal de consommation.
Recommended Posts