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]
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.
Cette fois, c'est fini.
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.