J'ai essayé de détecter les caractères en saisissant kana dans l'interface graphique et en utilisant un modèle créé par entraînement préalable par apprentissage automatique.
Tout d'abord, vérifiez la sensation et la précision de CNN avec MNIST, puis donnez les données kana réelles pour l'entraînement, et enfin liez-les à l'interface graphique.
La prochaine fois (2/3): https://qiita.com/tfull_tf/items/968bdb8f24f80d57617e Prochaine fois (3/3): https://qiita.com/tfull_tf/items/d9fe3ab6c1e47d1b2e1e
Le code complet peut être trouvé à l'adresse: https://github.com/tfull/character_recognition
Construisez votre propre modèle et exécutez le train, testez le populaire jeu de données numériques manuscrites MNIST pour voir à quel point il est précis.
Étant donné que MNIST contient des données en niveaux de gris 28x28, entrez-le sous la forme (canal, largeur, hauteur) = (1, 28, 28). Puisque les nombres vont de 0 à 9, il y a 10 destinations de classification et 10 probabilités sont sorties.
import torch.nn as nn
class Model(nn.Module):
def __init__(self):
super(Model, self).__init__()
self.conv1 = nn.Conv2d(1, 16, 3)
self.relu1 = nn.ReLU()
self.conv2 = nn.Conv2d(16, 32, 3)
self.relu2 = nn.ReLU()
self.pool = nn.MaxPool2d(2, 2)
self.dropout1 = nn.Dropout2d(0.3)
self.flatten = nn.Flatten()
self.linear1 = nn.Linear(12 * 12 * 32, 128)
self.relu3 = nn.ReLU()
self.dropout2 = nn.Dropout(0.3)
self.linear2 = nn.Linear(128, 10)
self.softmax = nn.Softmax(dim = 1)
def forward(self, x):
x = self.conv1(x)
x = self.relu1(x)
x = self.conv2(x)
x = self.relu2(x)
x = self.pool(x)
x = self.dropout1(x)
x = self.flatten(x)
x = self.linear1(x)
x = self.relu3(x)
x = self.dropout2(x)
x = self.linear2(x)
x = self.softmax(x)
return x
Il est converti en une dimension et passé à travers deux couches entièrement connectées via deux couches de pliage et une couche de regroupement ultérieure. La fonction d'activation est ReLU, et le contour du modèle consiste à insérer un calque de suppression pour éviter le surapprentissage au milieu.
import torchvision
download_flag = not os.path.exists(data_directory + "/mnist")
mnist_train = torchvision.datasets.MNIST(
data_directory + "/mnist",
train = True,
download = download_flag,
transform = torchvision.transforms.ToTensor()
)
mnist_test = torchvision.datasets.MNIST(
data_directory + "/mnist",
train = False,
download = download_flag,
transform = torchvision.transforms.ToTensor()
)
Enregistrez les données MNIST localement et utilisez-les. Définissez data_directory pour qu'il soit téléchargé s'il n'existe pas. Ce faisant, je me suis assuré de ne télécharger que la première fois.
import torch
import torch.optim as optim
train_loader = torch.utils.data.DataLoader(mnist_train, batch_size = 100, shuffle = True)
test_loader = torch.utils.data.DataLoader(mnist_test, batch_size = 1000, shuffle = False)
model = Model()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr = 0.001)
Utilisez DataLoader pour récupérer les données en séquence.
Définissez le modèle, la fonction d'erreur et l'algorithme d'optimisation. Nous avons adopté l'erreur d'entropie croisée, Adam.
n_epoch = 2
model.train()
for i_epoch in range(n_epoch):
for i_batch, (inputs, labels) in enumerate(train_loader):
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
print("epoch: {}, train: {}, loss: {}".format(i_epoch + 1, i_batch + 1, loss.item()))
Une série d'opérations d'apprentissage sont effectuées dans une boucle, dans laquelle des données d'image (entrées) sont fournies au modèle, la sortie (sortie) et les données de réponse correctes (étiquettes) sont comparées, l'erreur est calculée et la rétro-propagation est effectuée. Je vais.
Je pense que donner chaque donnée une fois n'est pas suffisant pour l'entraînement, alors j'ai mis le nombre d'époques (n_epoch) à 2 et donne à chaque donnée n_epoch fois pour l'entraînement. Le nombre d'époques est mon expérience, mais je pense qu'environ 2 à 3 est juste. Je pense que cela dépend du nombre de données.
correct_count = 0
record_count = 0
model.eval()
with torch.no_grad():
for inputs, labels in test_loader:
outputs = model(inputs)
_, prediction = torch.max(outputs.data, 1)
judge = prediction == labels
correct_count += int(judge.sum())
record_count += len(judge)
print("Accuracy: {:.2f}%".format(correct_count / record_count * 100))
Les données numériques (entrées) de l'image sont entrées dans le modèle, et la plus élevée des 10 probabilités qui apparaissent est utilisée comme prédiction. Il compare si elle correspond aux données de réponse correctes (étiquettes), renvoie Vrai / Faux et calcule le nombre de Vrai (compte_correct) par rapport au nombre total (compte_enregistrement) pour obtenir le taux de réponse correct.
Le résultat a été en moyenne plusieurs fois, environ 97%.
Je pense que la valeur du taux de réponse correcte est élevée, mais j'ai échoué 3 fois en 100 fois. Je pense que ce sera une autre question de savoir si les humains peuvent tolérer cela. Cependant, il y a des caractères sales dans les données d'image MNIST qui sont difficiles à distinguer pour les humains, donc dans ce sens, une erreur de 3% peut être inévitable.
MNIST a 10 choix de 0 à 9, mais comme il y en a plus de 100 en hiragana et katakana pour kana, il sera difficile de classer et vous devez être prêt à une nouvelle baisse du taux de réponse correcte.
Recommended Posts