[PYTHON] Version Lua Apprentissage profond à partir de zéro Partie 6 [Traitement d'inférence de réseau neuronal]

Articles précédents

Lua version Deep Learning from scratch Part 1 [Implémentation de Perceptron] Lua version Deep Learning from scratch 2 [Fonction d'activation] Lua version Deep Learning from scratch Part 3 [Implémentation d'un réseau neuronal à 3 couches] [Version Lua Deep Learning from scratch 4 [Implémentation de la fonction softmax]] (http://qiita.com/Kazuki-Nakamae/items/20e53a02a8b759583d31) Lua version Deep Learning from scratch Part 5 [Afficher l'image MNIST] Lua version Deep Learning from scratch Part 5.5 [Rendre les fichiers pkl disponibles dans Lua Torch]

Traitement d'inférence de réseau neuronal

Cette fois, un traitement d'inférence NN des données d'image MNIST est effectué.   Dans le document original, le fichier pkl dont le poids et le biais ont été déterminés à l'avance est lu, donc cette fois, le même traitement a été effectué avec Torch en utilisant ce fichier pkl. Pour lire le fichier pkl, voir Deep Learning from scratch for Lua version 5.5 [Rendre le fichier pkl utilisable avec Lua Torch]. Se il vous plaît se référer.   Le script ressemble à ceci:

neuralnet_mnist.lua


require './activationFunc.lua'
require './softmax.lua'
require './exTorch.lua'
require 'image'
npy4th = require 'npy4th' --https://github.com/htwaijry/npy4th (Author:Hani Altwaijry)

---Fonction d'acquisition de données
--Obtenez des données MNIST.
-- @retourner l'image des données de test,Étiquette des données de test{Type:ByteTensor}
function get_data()
    --download
    local tar = 'http://torch7.s3-website-us-east-1.amazonaws.com/data/mnist.t7.tgz'
    if not paths.dirp('mnist.t7') then
    os.execute('wget ' .. tar)
    os.execute('tar xvf ' .. paths.basename(tar))
    end
    --get data
    local test_file = 'mnist.t7/test_32x32.t7'
    local testData = torch.load(test_file,'ascii')

    return testData['data'], testData['labels']
end

---Fonction de génération de réseau.
--Renvoie un NN à 3 couches avec des poids et des biais déterminés. Cette fois, nous utiliserons les poids décrits dans pkl
-- @retour 3 couche NN(Type:table)
function init_network()
    local network = npy4th.loadnpz('sample_weight.npz')

    return network
end

---Fonction de classification.
--Le calcul de classification est effectué en fonction du réseau.
-- @entrée réseau param(Type:torch.table)
-- @entrée param x
-- @sortie de retour(Type:torch.DoubleTensor)
function predict(network, x)
    local W1, W2, W3 = network['W1'], network['W2'], network['W3']
    local b1, b2, b3 = network['b1'], network['b2'], network['b3']

    --La première entrée rend le tenseur unidimensionnel pour s'adapter au format numpy
    local a1 = mulTensor(x:resize(1,W1:size()[1]), W1) + b1:double()
    local z1 = sigmoid(a1)
    local a2 = mulTensor(z1,W2) + b2:double()
    local z2 = sigmoid(a2)
    local a3 = mulTensor(z2,W3) + b3:double()
    local y = softmax(a3)

    return y

end

local x, t = get_data()
local network = init_network()

local accuracy_cnt = 0
for i = 1, x:size()[1] do
    scaledx = image.scale(x[i],28,28) --Réduisez 32x32 à 28x28
    local y = predict(network, scaledx)
    local value, indices = torch.max(y, 2) -- torch.max( , 2)Obtenez la valeur maximale dans le sens de la ligne avec
    local p = tensor2scalar(indices) --Puisqu'il s'agit d'un tenseur, il est converti en un scalaire
    if p == t[i] then
        accuracy_cnt = accuracy_cnt + 1
    end
end

print("Accuracy:"..(accuracy_cnt/x:size()[1]))

Dans le document d'origine, il s'agissait de données MMIST 28x28, mais l'image utilisée cette fois-ci est 32x32. Par conséquent, les données réduites telles que l'image.scale (données d'image, 28, 28) sont soumises à un traitement d'inférence. Veuillez noter que le résultat sera différent de l'original.   activationFunc.lua, softmax.lua prière de se référer à. exTorch.lua contient des fonctions auxiliaires définies pour améliorer la lisibilité.

exTorch.lua


---Fonction de calcul du produit entre tenseurs
--Effectuer le produit AB des tenseurs correspondant à chaque dimension.
-- @param A A (Type:Tensor)
-- @param B B (Type:Tensor)
-- @return AB (Type:torch.DoubleTensor)
function mulTensor(A, B)
    A = A:double()
    B = B:double()
    local AB = nil;
    if (A:dim() == 1 and B:dim() ~= 1) then
        --1Dvector ・ matrice
        AB = torch.mv(B:t(), A)
    else
        --others
        AB = A*B
    end
    return AB
end

---Fonction de conversion scalaire pour tenseur
--Convertit le tenseur 1x1 en scalaire.
-- @tenseur param tenseur 1x1(Type:Tensor)
-- @retour scalaire(Type:number)
function tensor2scalar(tensor)
    return tensor[1]
end

Exemple d'exécution


$ th neuralnet_mnist.lua
Accuracy:0.8616	

Puisqu'il est réduit, il est différent du résultat en python, mais il semble que l'inférence elle-même soit faite correctement.   Cette fois, de nombreux processus sont forcés de correspondre aux données python, mais sans cela, je pense que le processus d'inférence peut être effectué avec le même effort que l'original. La seule chose à noter est que la gestion des types peut être plus prudente que python. En python, la conversion de type implicite est utilisée à la place, mais la gestion des types par Lua est assez standard, donc s'ils sont différents, une erreur sera renvoyée.   Si vous savez que le type est un entier, utilisez un type entier tel que byte ou long, et si vous calculez avec des fractions, utilisez le type double. Fondamentalement, les calculs de fraction informatique sont toujours sujets aux erreurs, donc les types flottants doivent être évités autant que possible. Si vous ne savez pas, essayez le code ci-dessous.

cancellation.lua


local floatT = torch.Tensor(1):fill(0):float()
for i = 1, 1000000 do
    floatT = floatT + torch.Tensor(1):fill(0.000001):float()
end
local doubleT = torch.Tensor(1):fill(0):double()
for i = 1, 1000000 do
    doubleT = doubleT + torch.Tensor(1):fill(0.000001):double()
end
print("float : ")
print(floatT)
print("double : ")
print(doubleT)

Exemple d'exécution


$ th cancellation.lua
float : 	
 1.0090
[torch.FloatTensor of size 1]

double : 	
 1.0000
[torch.DoubleTensor of size 1]

À l'origine, le calcul correct est que les deux sont 1, mais le résultat sera différent en raison d'une erreur dans float. Double provoque également une telle erreur, mais il est plus sûr que float.

en conclusion

Cette fois, c'est fini.

La prochaine fois, j'essaierai d'implémenter le traitement par lots dans ce traitement d'inférence.   Merci beaucoup.   Postscript (24/06/2017)

Cela semble inconfortable de le faire avec le résultat réduit, alors extrayons également les données MMIST de python. Copiez le répertoire de l'ensemble de données des fichiers de l'annexe du document d'origine dans le répertoire actuel et exécutez le script suivant.

saveMMISTtest.py


# coding: utf-8
import sys, os
import numpy as np
import pickle
from dataset.mnist import load_mnist

(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, flatten=True, one_hot_label=False)

np.save("x_test",x_test)
np.save("t_test",t_test)

Exemple d'exécution


$ python3 saveMMISTtest.py

Puisque x_test.npy et t_test.npy sont affichés, lisez-les avec get_data ().

neuralnet_mnist2.lua


require './activationFunc.lua'
require './softmax.lua'
require './exTorch.lua'
npy4th = require 'npy4th' --https://github.com/htwaijry/npy4th (Author:Hani Altwaijry)

---Fonction d'acquisition de données
--Obtenez des données MNIST.
-- @retourner l'image des données de test,Étiquette des données de test{Type:ByteTensor}
function get_data()
    --données d'image
    local x_test = npy4th.loadnpy('x_test.npy')
    --Données d'étiquette
    local t_test = npy4th.loadnpy('t_test.npy')

    return x_test, t_test
end

---Fonction de génération de réseau.
--Renvoie un NN à 3 couches avec des poids et des biais déterminés. Cette fois, nous utiliserons les poids décrits dans pkl
-- @retour 3 couche NN(Type:table)
function init_network()
    local network = npy4th.loadnpz('sample_weight.npz')

    return network
end

---Fonction de classification.
--Le calcul de classification est effectué en fonction du réseau.
-- @entrée réseau param(Type:torch.table)
-- @entrée param x
-- @sortie de retour(Type:torch.DoubleTensor)
function predict(network, x)
    local W1, W2, W3 = network['W1'], network['W2'], network['W3']
    local b1, b2, b3 = network['b1'], network['b2'], network['b3']

    --La première entrée rend le tenseur unidimensionnel pour s'adapter au format numpy
    local a1 = mulTensor(x, W1) + b1:double()
    local z1 = sigmoid(a1)
    local a2 = mulTensor(z1,W2) + b2:double()
    local z2 = sigmoid(a2)
    local a3 = mulTensor(z2,W3) + b3:double()
    local y = softmax(a3)

    return y

end

local x, t = get_data()
local network = init_network()

local accuracy_cnt = 0
for i = 1, x:size()[1] do
    local y = predict(network, x[i])
    local value, indices = torch.max(y, 1) -- torch.max( , 1)Obtenez la valeur maximale dans la direction col avec
    local p = tensor2scalar(indices) -1 --Puisqu'il s'agit d'une sortie python, le début du tableau est 0, le tableau de Lua(type de table)Commence à partir de 1, alors décalez de 1
    if p == t[i] then
        accuracy_cnt = accuracy_cnt + 1
    end
end

print("Accuracy:"..(accuracy_cnt/x:size()[1]))

Exemple d'exécution


$ th neuralnet_mnist2.lua
Accuracy:0.9352

Avec cela, j'ai pu produire la même sortie que l'original.

Recommended Posts

Version Lua Apprentissage profond à partir de zéro Partie 6 [Traitement d'inférence de réseau neuronal]
Version Lua Deep Learning from scratch Part 5.5 [Rendre les fichiers pkl disponibles dans Lua Torch]
Mémo d'auto-apprentissage "Deep Learning from scratch" (partie 12) Deep learning
[Deep Learning from scratch] Implémentez le traitement de rétropropagation dans le réseau neuronal par la méthode de propagation de retour d'erreur
Apprentissage profond à partir de zéro
[Deep Learning from scratch] À propos des couches requises pour implémenter le traitement de rétropropagation dans un réseau neuronal
Apprentissage profond à partir de zéro 1 à 3 chapitres
Python vs Ruby "Deep Learning from scratch" Chapitre 3 Implémentation d'un réseau neuronal à 3 couches
[Deep Learning from scratch] Accélération du réseau de neurones J'ai expliqué le traitement de la propagation arrière
[Deep Learning] Exécuter la console de réseau neuronal SONY à partir de CUI
[Deep Learning from scratch] Valeur initiale du poids du réseau neuronal utilisant la fonction sigmoïde
[Deep Learning from scratch] Poids initial du réseau neuronal lors de l'utilisation de la fonction Relu
J'ai essayé d'implémenter Perceptron Part 1 [Deep Learning from scratch]
Apprentissage profond à partir de zéro (calcul des coûts)
Mémo d'apprentissage profond créé à partir de zéro
Chapitre 3 Réseau de neurones Ne découpez que les bons points de Deeplearning à partir de zéro
[Mémo d'apprentissage] Le Deep Learning fait de zéro [Chapitre 7]
Apprentissage profond à partir de zéro (propagation vers l'avant)
Apprentissage profond / Apprentissage profond à partir de zéro 2-Essayez de déplacer GRU
Deep learning / Deep learning made from scratch Chapitre 6 Mémo
[Mémo d'apprentissage] Deep Learning fait de zéro [Chapitre 5]
[Mémo d'apprentissage] Le Deep Learning fait de zéro [Chapitre 6]
"Deep Learning from scratch" avec Haskell (inachevé)
Deep learning / Deep learning made from scratch Chapitre 7 Mémo
[Windows 10] Construction de l'environnement "Deep Learning from scratch"
Enregistrement d'apprentissage de la lecture "Deep Learning from scratch"
[Deep Learning from scratch] À propos de l'optimisation des hyper paramètres
[Mémo d'apprentissage] Deep Learning fait de zéro [~ Chapitre 4]
Mémo d'auto-apprentissage "Deep Learning from scratch" (glossaire illisible)
"Deep Learning from scratch" Mémo d'auto-apprentissage (n ° 9) Classe MultiLayerNet
Deep Learning from scratch ① Chapitre 6 "Techniques liées à l'apprentissage"
GitHub du bon livre "Deep Learning from scratch"
Deep Learning from scratch Chapter 2 Perceptron (lecture du mémo)
[Mémo d'apprentissage] Apprentissage profond à partir de zéro ~ Mise en œuvre de l'abandon ~
Résumé Python vs Ruby "Deep Learning from scratch"
Mémo d'auto-apprentissage «Deep Learning from scratch» (10) Classe MultiLayerNet
Mémo d'auto-apprentissage «Deep Learning from scratch» (n ° 11) CNN
[Python] [Traitement du langage naturel] J'ai essayé le Deep Learning ❷ fait de toutes pièces en japonais ①
[Deep Learning from scratch] J'ai implémenté la couche Affine
Mémo d'auto-apprentissage «Deep Learning from scratch» (n ° 19) Augmentation des données
Application de Deep Learning 2 à partir de zéro Filtre anti-spam
Implémenter le réseau neuronal à partir de zéro
Deep Learning 2 from scratch 1.3 Traitement du langage naturel 1.3 Résumé
Apprendre en profondeur à partir des bases mathématiques Partie 2 (pendant la fréquentation)
Méthode d'étude pour apprendre le machine learning à partir de zéro (version mars 2020)
[Deep Learning from scratch] J'ai essayé d'expliquer le décrochage
Mémo d'auto-apprentissage "Deep Learning from scratch" (partie 8) J'ai dessiné le graphique du chapitre 6 avec matplotlib
[Deep Learning from scratch] Implémentation de la méthode Momentum et de la méthode AdaGrad
[Partie 4] Utilisez le Deep Learning pour prévoir la météo à partir d'images météorologiques
Un amateur a trébuché dans le Deep Learning à partir de zéro Note: Chapitre 1
[Partie 1] Utilisez le Deep Learning pour prévoir la météo à partir d'images météorologiques
[Partie 3] Utilisez le Deep Learning pour prévoir la météo à partir d'images météorologiques
Un amateur a trébuché dans le Deep Learning ❷ fait à partir de zéro Note: Chapitre 2
Créez un environnement pour "Deep Learning from scratch" avec Docker
Un amateur a trébuché dans le Deep Learning à partir de zéro Note: Chapitre 3
Un amateur a trébuché dans le Deep Learning à partir de zéro Note: Chapitre 7
Un amateur a trébuché dans le Deep Learning à partir de zéro Note: Chapitre 5
Un amateur a trébuché dans le Deep Learning ❷ fait de zéro Note: Chapitre 1