[PYTHON] Effectuer la reconnaissance de caractères manuscrits à l'aide de Pylearn 2

La reconnaissance des caractères manuscrits est effectuée à l'aide de Pylearn2. J'omettrai la méthode d'installation de Pylearn2. Définissez la variable d'environnement PYLEARN2_VIEWER_COMMAND pour afficher l'image.

Le code source utilisé cette fois a été téléchargé sur Github. https://github.com/dsanno/pylearn2_mnist

Télécharger les données

Utilisez la base de données MNIST pour les données. Il contient l'ensemble de données suivant.

pylearn2 contient des scripts qui téléchargent et traitent certains ensembles de données. Pour télécharger la base de données MNIST, exécutez le fichier suivant inclus dans pylearn2. Les données téléchargées seront placées dans $ PYLEARN2_DATA_PATH / mnist. pylearn2/scripts/datasets/download_mnist.py

Vérifiez les données

Vérifions quel type de données est inclus.

Tout d'abord, créez un fichier yaml qui définit l'ensemble de données.

dataset.yaml


!obj:pylearn2.datasets.mnist.MNIST {
    which_set: 'train'
}

Ensuite, utilisez show_examples.py dans pylearn2 pour afficher un échantillon des données. Créez et exécutez le fichier suivant.

show_samples.py


import pylearn2.scripts.show_examples as show_examples

show_examples.show_examples('dataset.yaml', 20, 20)

Alternativement, il peut être affiché avec la commande suivante. pylearn2/scripts/show_examples.py dataset.yaml

L'image suivante s'affiche.

dataset_examples.png

Définir un modèle

Définissez un modèle de formation. Il existe un modèle d'apprentissage des données MNIST dans le répertoire stacked_autoencoders du didacticiel, alors modifiez-le et utilisez-le. pylearn2/scripts/tutorals/stacked_autoencoders/

Cette fois, nous définirons le modèle suivant.

1ère couche: 28 x 28 = Prend 784 valeurs d'entrée.

dae_l1.yaml


!obj:pylearn2.train.Train {
    dataset: &train !obj:pylearn2.datasets.mnist.MNIST {
        which_set: 'train',
        start: 0,
        stop: %(train_stop)i
    },
    model: !obj:pylearn2.models.autoencoder.DenoisingAutoencoder {
        nvis : 784,
        nhid : %(nhid)i,
        irange : 0.05,
        corruptor: !obj:pylearn2.corruption.BinomialCorruptor {
            corruption_level: .2,
        },
        act_enc: "tanh",
        act_dec: null,    # Linear activation on the decoder side.
    },
    algorithm: !obj:pylearn2.training_algorithms.sgd.SGD {
        learning_rate : 1e-3,
        batch_size : %(batch_size)i,
        monitoring_batches : %(monitoring_batches)i,
        monitoring_dataset : *train,
        cost : !obj:pylearn2.costs.autoencoder.MeanSquaredReconstructionError {},
        termination_criterion : !obj:pylearn2.termination_criteria.EpochCounter {
            max_epochs: %(max_epochs)i,
        },
    },
    save_path: "%(save_path)s/dae_l1.pkl",
    save_freq: 1
}

Deuxième couche: Pour l'ensemble de données, utilisez les données d'entraînement converties par la première couche.

dae_l2.yaml


!obj:pylearn2.train.Train {
    dataset: &train !obj:pylearn2.datasets.transformer_dataset.TransformerDataset {
        raw: !obj:pylearn2.datasets.mnist.MNIST {
            which_set: 'train',
            start: 0,
            stop: %(train_stop)i
        },
        transformer: !pkl: "%(save_path)s/dae_l1.pkl"
    },
    model: !obj:pylearn2.models.autoencoder.DenoisingAutoencoder {
        nvis : %(nvis)i,
        nhid : %(nhid)i,
        irange : 0.05,
        corruptor: !obj:pylearn2.corruption.BinomialCorruptor {
            corruption_level: .3,
        },
        act_enc: "tanh",
        act_dec: null,    # Linear activation on the decoder side.
    },
    algorithm: !obj:pylearn2.training_algorithms.sgd.SGD {
        learning_rate : 1e-3,
        batch_size : %(batch_size)i,
        monitoring_batches : %(monitoring_batches)i,
        monitoring_dataset : *train,
        cost : !obj:pylearn2.costs.autoencoder.MeanSquaredReconstructionError {},
        termination_criterion : !obj:pylearn2.termination_criteria.EpochCounter {
            max_epochs: %(max_epochs)i,
        },
    },
    save_path: "%(save_path)s/dae_l2.pkl",
    save_freq: 1
}

Troisième couche: Pour l'ensemble de données, utilisez les données d'entraînement converties par les première et deuxième couches.

!obj:pylearn2.train.Train {
    dataset: &train !obj:pylearn2.datasets.transformer_dataset.TransformerDataset {
        raw: !obj:pylearn2.datasets.mnist.MNIST {
            which_set: 'train',
            start: 0,
            stop: %(train_stop)i
        },
        transformer: !obj:pylearn2.blocks.StackedBlocks {
            layers: [!pkl: "dae_l1.pkl", !pkl: "dae_l2.pkl"]
        }
    },
    model: !obj:pylearn2.models.autoencoder.DenoisingAutoencoder {
        nvis : %(nvis)i,
        nhid : %(nhid)i,
        irange : 0.05,
        corruptor: !obj:pylearn2.corruption.BinomialCorruptor {
            corruption_level: .3,
        },
        act_enc: "tanh",
        act_dec: null,    # Linear activation on the decoder side.
    },
    algorithm: !obj:pylearn2.training_algorithms.sgd.SGD {
        learning_rate : 1e-3,
        batch_size : %(batch_size)i,
        monitoring_batches : %(monitoring_batches)i,
        monitoring_dataset : *train,
        cost : !obj:pylearn2.costs.autoencoder.MeanSquaredReconstructionError {},
        termination_criterion : !obj:pylearn2.termination_criteria.EpochCounter {
            max_epochs: %(max_epochs)i,
        },
    },
    save_path: "%(save_path)s/dae_l3.pkl",
    save_freq: 1
}

Enfin, définissez un modèle dans lequel chaque couche est concaténée pour un réglage fin. Il y a 10 unités dans la couche de sortie, et chaque valeur peut être considérée comme la probabilité de quel caractère de 0 à 9.

dae_mlp.yaml


!obj:pylearn2.train.Train {
    dataset: &train !obj:pylearn2.datasets.mnist.MNIST {
        which_set: 'train',
        start: 0,
        stop: %(train_stop)i
    },
    model: !obj:pylearn2.models.mlp.MLP {
        batch_size: %(batch_size)i,
        layers: [
                 !obj:pylearn2.models.mlp.PretrainedLayer {
                     layer_name: 'h1',
                     layer_content: !pkl: "%(save_path)s/dae_l1.pkl"
                 },
                 !obj:pylearn2.models.mlp.PretrainedLayer {
                     layer_name: 'h2',
                     layer_content: !pkl: "%(save_path)s/dae_l2.pkl"
                 },
                 !obj:pylearn2.models.mlp.PretrainedLayer {
                     layer_name: 'h3',
                     layer_content: !pkl: "%(save_path)s/dae_l3.pkl"
                 },
                 !obj:pylearn2.models.mlp.Softmax {
                     max_col_norm: 1.9365,
                     layer_name: 'y',
                     n_classes: 10,
                     irange: .005
                 }
                ],
        nvis: 784
    },
    algorithm: !obj:pylearn2.training_algorithms.sgd.SGD {
        learning_rate: .05,
        learning_rule: !obj:pylearn2.training_algorithms.learning_rule.Momentum {
            init_momentum: .5,
        },
        monitoring_dataset:
            {
                'valid' : !obj:pylearn2.datasets.mnist.MNIST {
                              which_set: 'train',
                              start: 0,
                              stop: %(valid_stop)i
                          },
            },
        cost: !obj:pylearn2.costs.mlp.Default {},
        termination_criterion: !obj:pylearn2.termination_criteria.And {
            criteria: [
                !obj:pylearn2.termination_criteria.MonitorBased {
                    channel_name: "valid_y_misclass",
                    prop_decrease: 0.,
                    N: 100
                },
                !obj:pylearn2.termination_criteria.EpochCounter {
                    max_epochs: %(max_epochs)i
                }
            ]
        },
        update_callbacks: !obj:pylearn2.training_algorithms.sgd.ExponentialDecay {
            decay_factor: 1.00004,
            min_lr: .000001
        }
    },
    extensions: [
        !obj:pylearn2.training_algorithms.learning_rule.MomentumAdjustor {
            start: 1,
            saturate: 250,
            final_momentum: .7
        }
    ],
    save_path: "%(save_path)s/dae_mlp.pkl",
    save_freq: 1
}

Apprenez

Modifiez et utilisez le script d'apprentissage inclus dans le didacticiel stacked_autoencoders. Les modifications suivantes ont été apportées.

Une fois exécutés, les fichiers correspondant à chaque modèle, dae_l1.pkl, dae_l2.pkl, dae_l3.pkl et dae_mlp.pkl, sont générés. Concernant le temps d'exécution, cela a pris environ 20 minutes dans mon environnement (Core i7-3770).

test_dae.py


import os

from pylearn2.testing import skip
from pylearn2.testing import no_debug_mode
from pylearn2.config import yaml_parse


@no_debug_mode
def train_yaml(yaml_file):

    train = yaml_parse.load(yaml_file)
    train.main_loop()


def train_layer1(yaml_file_path, save_path):

    yaml = open("{0}/dae_l1.yaml".format(yaml_file_path), 'r').read()
    hyper_params = {'train_stop': 60000,
                    'batch_size': 100,
                    'monitoring_batches': 1,
                    'nhid': 100,
                    'max_epochs': 100,
                    'save_path': save_path}
    yaml = yaml % (hyper_params)
    train_yaml(yaml)


def train_layer2(yaml_file_path, save_path):

    yaml = open("{0}/dae_l2.yaml".format(yaml_file_path), 'r').read()
    hyper_params = {'train_stop': 60000,
                    'batch_size': 100,
                    'monitoring_batches': 1,
                    'nvis': 100,
                    'nhid': 100,
                    'max_epochs': 100,
                    'save_path': save_path}
    yaml = yaml % (hyper_params)
    train_yaml(yaml)


def train_layer3(yaml_file_path, save_path):

    yaml = open("{0}/dae_l3.yaml".format(yaml_file_path), 'r').read()
    hyper_params = {'train_stop': 60000,
                    'batch_size': 100,
                    'monitoring_batches': 1,
                    'nvis': 100,
                    'nhid': 100,
                    'max_epochs': 100,
                    'save_path': save_path}
    yaml = yaml % (hyper_params)
    train_yaml(yaml)


def train_mlp(yaml_file_path, save_path):

    yaml = open("{0}/dae_mlp.yaml".format(yaml_file_path), 'r').read()
    hyper_params = {'train_stop': 60000,
                    'valid_stop': 60000,
                    'batch_size': 100,
                    'max_epochs': 100,
                    'save_path': save_path}
    yaml = yaml % (hyper_params)
    train_yaml(yaml)


def test_sda():

    skip.skip_if_no_data()

    yaml_file_path = '.';
    save_path = '.'

    train_layer1(yaml_file_path, save_path)
    train_layer2(yaml_file_path, save_path)
    train_layer3(yaml_file_path, save_path)
    train_mlp(yaml_file_path, save_path)

if __name__ == '__main__':
    test_sda()

Effectuer la reconnaissance de caractères à l'aide des données de test

La reconnaissance de caractères est effectuée à l'aide de données de test et le taux de reconnaissance est obtenu. J'obtiens les données de test avec pylearn2.datasets.mnist.MNIST (which_set = 'test') et j'utilise le fprop du modèle pour trouver la valeur de la couche de sortie. Le caractère correspondant à l'unité de sortie avec la plus grande valeur est utilisé comme valeur prédite. Dans mon environnement, 9814 sur 10000 étaient corrects.

test_result.py


import numpy as np
import pickle
import theano
import pylearn2.datasets.mnist as mnist


def simulate(inputs, model):
    return model.fprop(theano.shared(inputs)).eval()

def countCorrectResults(outputs, labels):
    correct = 0;
    for output, label in zip(outputs, labels):
        if np.argmax(output) == label:
            correct += 1
    return correct
 
def score(dataset, model):
    outputs = simulate(dataset.X, model)
    correct = countCorrectResults(outputs, dataset.y)

    return {
        'correct': correct,
        'total': len(dataset.X)
    }

model = pickle.load(open('dae_mlp.pkl'))
test_data = mnist.MNIST(which_set='test')
print '%(correct)d / %(total)d' % score(test_data, model)

Les références

Je me suis référé au site suivant. http://tanopy.blog79.fc2.com/blog-entry-118.html http://www.slideshare.net/yurieoka37/ss-28152060

Recommended Posts

Effectuer la reconnaissance de caractères manuscrits à l'aide de Pylearn 2
Reconnaissance de caractères manuscrits à l'aide de KNN en Python
Essayez d'utiliser la reconnaissance de caractères manuscrits (OCR) de GCP
Reconnaissance de l'âge à l'aide de l'API de Pepper
J'ai essayé la reconnaissance faciale avec Face ++
J'ai essayé la reconnaissance de caractères manuscrits des caractères runiques avec CNN en utilisant Keras
Reconnaissance faciale à l'aide de l'analyse des composants principaux
Reconnaissance faciale à l'aide de l'API de Pepper
Reconnaissance d'image des fruits avec VGG16
Reconnaissance d'objet circulaire à l'aide de la transformation de Huff