Framework Torch: klasifikace objektů na obrázcích z reálného světa

4. 1. 2018
Doba čtení: 22 minut

Sdílet

Ve dvanácté části seriálu o frameworku Torch se pokusíme vytvořit konvoluční neuronovou síť takovým způsobem, aby uspokojivě klasifikovala obrázky získané ze známé databáze CIFAR-10.

Obsah

1. Framework Torch: klasifikace objektů na obrázcích z reálného světa

2. Databáze CIFAR-10

3. Nový projekt určený pro trénink a validaci konvoluční neuronové sítě

4. Moduly umístěné v adresáři image_lib

   4.1. Modul image_writer

5. Moduly umístěné v adresáři nn

   5.1 Modul nn_constructor

   5.2 Modul nn_trainer

   5.3 Modul nn_validators

6. Moduly umístěné v adresáři utils

   6.1. Modul cifar_downloader

   6.2. Modul classification_classes

7. Hlavní modul celého projektu

8. Průběh tréningu konvoluční neuronové sítě

9. Validace neuronové sítě

10. Rozbor výsledků a zlepšení odhadu sítě

11. Repositář s demonstračním projektem

12. Odkazy na Internetu

1. Framework Torch: klasifikace objektů na obrázcích z reálného světa

V dnešním článku o frameworku Torch se již počtvrté budeme zabývat problematikou rozpoznávání a klasifikace (rastrových) obrázků, a to jak s využitím běžných neuronových sítí, tak i sítí konvolučních. Navážeme na část předchozí, v níž jsme si ukázali ucelený projekt použitelný pro rozpoznávání cifer (0–9), a to i v těch případech, kdy jsou obrázky podrobeny nějaké operaci zhoršující čitelnost (zašumění, jittering atd.).

Obrázek 1: Validační obrázky použité minule. Úroveň šumu (rozptyl) byl nastaven na hodnotu 100.

Námi vytvořená konvoluční neuronová síť neměla s klasifikací takových obrázků prakticky žádné větší problémy, a to ani ve chvíli, kdy byla úroveň šumu již velmi vysoká popř. když se ve větší míře použil jittering (roztřesení). Ostatně si můžete sami vyzkoušet provést například rozmazání validačních obrázků či aplikovat další „problematické“ operace. Zkusme se tedy zaměřit na složitější úkol, konkrétně na klasifikaci obrázků získaných z databáze CIFAR-10.

Obrázek 2: Testovací obrázky použité minule. Jittering (roztřesení) je nastaven na hodnotu 1.

2. Databáze CIFAR-10

Jménem CIFAR-10 se označuje databáze obrázků určených mj. i k testování (ne)kvality neuronových sítí, které mají tyto obrázky klasifikovat. Obrázky jsou rozděleny do dvou skupin, přičemž první skupinu tvoří 50 000 trénovacích obrázků a druhou skupinu pak 10 000 obrázků validačních či testovacích. Každý obrázek v databázi CIFAR-10 je reprezentován v prostoru RGB (tři barvové roviny) a má rozlišení 32×32 pixelů, což není mnoho, protože na každém obrázku se nachází více či méně rozpoznatelný objekt patřící do jedné z těchto kategorií:

# Kategorie
1 airplane
2 automobile
3 bird
4 cat
5 deer
6 dog
7 frog
8 horse
9 ship
10 truck

Poznámka: jména kategorií je asi zbytečné překládat, navíc jsou v databázi uloženy indexy každé kategorie, takže má význam dodržet původní (abecední) řazení anglických názvů.

Obrázek 3: Několik trénovacích obrázků s kočkami (kategorie cat). Obrázky mají skutečně velikost pouze 32×32 pixelů – nejedná se o ikony.

Celá databáze je dostupná na adrese http://www.cs.toronto.edu/~kriz/ci­far.html, my ovšem použijeme již připravené serializované tenzory připravené přímo pro použití ve frameworku Torch. Takto připravená databáze je dostupná na adrese https://s3.amazonaws.com/tor­ch7/data/cifar10torchsmall­.zip, ovšem nemusíte si ji stahovat ručně – to za nás provede projekt, který si v dalších kapitolách popíšeme.

Obrázek 4: Několik trénovacích obrázků s kamiony (kategorie truck).

3. Nový projekt určený pro trénink a validaci konvoluční neuronové sítě

První verze projektu pro klasifikaci obrázků z CIFAR-10 se vlastně principiálně nebude příliš odlišovat od předchozích projektů. Ostatně ani k tomu (alespoň prozatím) není důvod – máme sérii obrázků, z nichž každý obsahuje objekt spadající do jedné z deseti kategorií, takže základní požadavky jsou skutečně stejné (výsledky již budou horší, jak uvidíme dále).

Obrázek 5: Pro představu, jaký poměrně složitý úkol bude na naši neuronovou síť čekat – zvětšený trénovací obrázek s kočkou.

Pro klasifikaci obrázků z databáze CIFAR-10 si vytvoříme nový projekt, jehož některé části jsou odvozeny od projektu popsaného minule. Celý projekt je rozdělen do několika (konkrétně do sedmi) modulů, přičemž jednotlivé moduly jsou rozděleny do několika podadresářů. Celková struktura projektu vypadá následovně:

├── cifar_data_classificator.lua
├── image_lib
│   └── image_writer.lua
├── nn
│   ├── nn_constructor.lua
│   ├── nn_trainer.lua
│   └── nn_validators.lua
└── utils
    ├── cifar_downloader.lua
    └── classification_classes.lua

Kromě toho projekt obsahuje i několik pomocných skriptů.

Poznámka: tento projekt se záměrně podobá notebooku, který naleznete na adrese https://github.com/soumit­h/cvpr2015/blob/master/De­ep%20Learning%20with%20Tor­ch.ipynb, ovšem konfigurace neuronové sítě je naschvál odlišná (je prakticky kompletně převzata z předchozího příkladu), navíc prozatím (opět naschvál) neimplementujeme ani žádný preprocesing obrázků.

4. Moduly umístěné v adresáři image_lib

V této kapitole je stručně popsán jediný modul umístěný do adresáře image_lib. V minulé části tohoto seriálu byl popsán projekt, v němž byly v tomto adresáři umístěny hned čtyři moduly, ty ovšem sloužily pro přípravu trénovacích i validačních obrázků. My však již máme obrázky připraveny (tj. získány z databáze CIFAR-10), takže se nám celý modul značně zjednodušil.

4.1 Modul image_writer

Jedná se o pomocný modul, který využijeme ve chvíli, když budeme potřebovat zjistit, jak vlastně vypadají trénovací obrázky nebo který obrázek síť špatně určila. První funkce slouží pro export obrázku z trénovacích dat, přičemž převod tenzoru do rastrového obrázku uloženého ve formátu PNG za nás udělá samotný framework Torch:

function write_training_image(training_set, n)
    -- kontrola, jestli obrazek s danym indexem "n" skutecne existuje
    local size=training_set.data:size(1)
    if n < 1 or n > size then
        print("Training image " .. n .. " does not exist!")
        return
    end
 
    -- index popisky obrazku
    local label_index = training_set.label[n]
 
    -- vlastni (textovy) popisek obrazku
    local label = classification_classes[label_index]
 
    -- ulozeni obrazku
    store_image(training_set, n, label)
end
 
 
function store_image(training_set, n, label)
    -- konstrukce jmena souboru
    local filename = string.format("training_image_%05d_%s.png", n, label)
 
    -- zapis dat ve formatu PNG
    local img = training_set.data[n]
    image.save(filename, img)
end

Takto jednoduše je možné vyexportovat všechny trénovací obrázky obsahující objekt jednoho typu (například letadlo):

function write_training_images_with_label(training_set, label)
    -- celkovy pocet obrazku v trenovaci mnozine
    local size=training_set.data:size(1)
 
    -- index tridy obrazku
    local label_index = get_label_index(label)
 
    -- projit vsemi obrazky v sade
    for i = 1, size do
        -- filtrace obrazku
        if training_set.label[i] == label_index then
            store_image(training_set, i, label)
        end
    end
end

Poznámka: právě funkce write_training_images_with_label byla použita při tvorbě screenshotů 3 a 4.

5. Moduly umístěné v adresáři nn

V této kapitole je stručně popsána trojice modulů umístěná do adresáře nn.

5.1 Modul nn_constructor

Tento modul obsahuje především funkci construct_neural_network určenou pro vytvoření konvoluční neuronové sítě se specifikovanou konfigurací – rozlišením vstupních obrázků, počtem rovin (atributů), počtem skrytých neuronů ve druhé polovině sítě atd. S významem jednotlivých konfiguračních parametrů jsme se seznámili v předchozích dvou článcích:

function calculate_size_after_convolution(input_size, middle_planes, convolution_kernel_size, pooling_size)
    local size = input_size
    for i=1,#middle_planes do
        -- velikost po projiti konvolucni vrstvou
        size = size - convolution_kernel_size + 1
        -- velikost po projiti pooling vrstvou
        size = size / pooling_size
    end
    return size
end

Jednou z významných změn je to, že počet rovin na vstupu již nebude roven jedné, ale třem (monochromatické versus RGB obrázky). To se sice ve zdrojovém kódu neprojeví, ovšem hodnota argumentu input_planes se změní:

function construct_neural_network(width, height, input_planes, middle_planes,
                                  hidden_neurons, output_neurons,
                                  convolution_kernel_size, pooling_size, pooling_step)
    local network = nn.Sequential()
 
    local size_x = calculate_size_after_convolution(width, middle_planes, convolution_kernel_size, pooling_size)
    local size_y = calculate_size_after_convolution(height, middle_planes, convolution_kernel_size, pooling_size)
 
    print("Size x: " .. size_x)
    print("Size y: " .. size_y)
 
    -- prvni konvolucni vrstva ocekavajici na vstupu 3D tenzor
    -- o velikosti:
    -- INPUT_PLANES x vyska x sirka
    --
    -- vysledkem je 3D tenzor o velikosti:
    -- MIDDLE_PLANES_1 x (vyska - CONVOLUTION_KERNEL_SIZE + 1) x (sirka - CONVOLUTION_KERNEL_SIZE + 1) 
    network:add(nn.SpatialConvolution(input_planes, middle_planes[1], convolution_kernel_size, convolution_kernel_size))
 
    -- nyni mame mezivysledky MIDDLE_PLANES_1 x (vyska-5+1) x (sirka-5+1)
 
    -- nelinearni funkce
    network:add(nn.Tanh())
 
    -- hledani maxima v regionech o velikosti 2x2 pixely
    -- s krokem nastavenym na 2 pixely v horizontalnim i 2 pixely ve vertikalnim smeru
    network:add(nn.SpatialMaxPooling(pooling_size, pooling_size, pooling_step, pooling_step))
 
    -- druha konvolucni vrstva ocekavajici na vstupu 3D tenzor
    -- o velikosti MIDDLE_PLANES_1 x vyska x sirka
    network:add(nn.SpatialConvolution(middle_planes[1], middle_planes[2], convolution_kernel_size, convolution_kernel_size))
 
    -- nelinearni funkce
    network:add(nn.Tanh())
 
    -- opetovne hledani maxima v regionech o velikosti 2x2 pixely
    -- s krokem nastavenym na 2 pixely v horizontalnim i 2 pixely ve vertikalnim smeru
    network:add(nn.SpatialMaxPooling(pooling_size, pooling_size, pooling_step, pooling_step))
 
    -- zmena tvaru: z 3D tenzoru AxBxC na 1D tenzor s A*B*C elementy
    network:add(nn.View(middle_planes[2]*size_x*size_y))
 
    -- bezne vrstvy, jak je jiz zname
    network:add(nn.Linear(middle_planes[2]*size_x*size_y, hidden_neurons))
 
    -- pridana nelinearni funkce
    network:add(nn.ReLU())
 
    -- bezne vrstvy, jak je jiz zname
    network:add(nn.Linear(hidden_neurons, output_neurons))
 
    return network
end

5.2 Modul nn_trainer

V modulu nn_trainer nalezneme především funkci volanou pro vlastní trénink sítě (train_neural_network), ale taktéž funkci pojmenovanou prepare_training_data, která ze vstupní databáze CIFAR-10 vytvoří tabulku s tenzory určenými pro trénink sítě. Připomeňme si, že trénovací tenzory obsahují dvojice vstup:očekávaný-výstup, přičemž vstupem jsou jednotlivé obrázky (převedené na tenzory) a výstupem pak tenzor s váhou odhadu objektu, který síť na obrázku nalezla:

function train_neural_network(network, training_data, learning_rate, max_iteration)
    local criterion = nn.MSECriterion()
    local trainer = nn.StochasticGradient(network, criterion)
    trainer.learningRate = learning_rate
    trainer.maxIteration = max_iteration
    trainer:train(training_data)
end
 
 
function generate_expected_output(class)
    local result = torch.zeros(CLASSES)
    result[class] = 1
    return result
end

Funkce pro přípravu trénovacích dat vlastně „pouze“ provádí konverzi mezi vstupním tenzorem o rozměrech 10000×3×32×32 komponent na tabulku s dvojicemi tenzorů. Tuto problematiku je možné ve skutečnosti vykonat mnohem kratším kódem – změnou „operátoru“ indexování – ale prozatím nemusíme zdrojové kódy příliš komplikovat. V průběhu ladění neuronové sítě může být vhodné omezit maximální počet trénovacích obrázků, což je zajištěno existencí parametru max_size_of_training_set:

function prepare_training_data(training_set, max_size_of_training_set)
    -- celkovy pocet obrazku v trenovaci mnozine
    local input_training_set_size = training_set.data:size(1)
    local training_data_size = math.min(input_training_set_size, max_size_of_training_set)
 
    -- priprava tenzoru s trenovacimi daty
    local training_data = {}
    function training_data:size() return training_data_size end
 
    -- projit vsemi obrazky v sade
    for i = 1, training_data_size do
        -- tenzor s obrazkem ve formatu RGB
        local input = training_set.data[i]:double()
        local label_index = training_set.label[i]
        -- tenzor s desetiprvkovym vektorem obsahujicim jen hodnoty 0 a 1
        local output = generate_expected_output(label_index)
        training_data[i] = {input, output}
    end
 
    return training_data
end

Povšimněte si, že se logika tohoto kódu od minula vlastně příliš nezměnila, až na jednu maličkost – třída nalezených objektů je reprezentována číslem od 1 do 10, zatímco minule jsme používali přímo cifry 0 až 9.

5.3 Modul nn_validators

Tento modul obsahuje především funkci validate_neural_network provádějící validaci natrénované neuronové sítě a několik funkcí pomocných. Pro validaci používáme sadu obrázků získaných opět z databáze CIFAR-10. U obrázků se vypisuje přímo jméno objektu, který se zde nachází (expected) i jméno objektu odhadovaného neuronovou sítí:

function find_largest_item(tensor)
    local index = -1
    local value = -math.huge
    for i = 0, 9 do
        if tensor[i+1] > value then
            index = i
            value = tensor[i+1]
        end
    end
    return index+1, value
end
 
 
function plot_graph(filename, values)
    gnuplot.pngfigure(filename)
    gnuplot.imagesc(values, 'color')
    gnuplot.raw("set terminal pngcairo size 1280, 480")
    gnuplot.plotflush()
    gnuplot.close()
end
 
 
function validate_neural_network(network, validation_set)
    local errors = 0
    local count = 0
 
    -- celkovy pocet obrazku ve validacni mnozine
    local validation_set_size = validation_set.data:size(1)
    print(validation_set_size)
 
    for i = 1, validation_set_size do
        -- tenzor s obrazkem ve formatu RGB
        local input = validation_set.data[i]:double()
        local output = network:forward(input)
        local result, weight = find_largest_item(output)
        local expected = validation_set.label[i]
        if expected ~= result then
            errors = errors + 1
        end
        -- muzeme vypsat primo tridu objektu, nejen jeho cislo
        print(classification_classes[expected], classification_classes[result], expected==result, weight)
        count = count + 1
    end
    print("---------------------")
    print("Errors: " .. errors)
    print("Error rate: " .. 100.0*errors/count .. "%")
end

6. Moduly umístěné v adresáři utils

V podadresáři utils nalezneme dva pomocné moduly nazvané cifar_downloader a classification_classes. Podrobnější popis těchto modulů je uveden v navazujících podkapitolách.

6.1 Modul cifar_downloader

Pro stažení a rozbalení testovacích i trénovacích dat nám poslouží následující skript nazvaný jednoduše cifar_downloader, který bude volán z hlavního modulu. Tento skript pracuje velmi jednoduše: nejprve otestuje existenci archivu se všemi daty a pokud soubor s archivem neexistuje, stáhne ho z adresy https://s3.amazonaws.com/tor­ch7/data/cifar10torchsmall­.zip (pozor, jedná se o poměrně velký soubor o velikosti 55 MB!). Následně se tento archiv rozbalí, ale opět pouze tehdy, pokud nejsou nalezeny již rozbalené soubory (očekávají se dva soubory, jeden s testovacími daty, druhý s daty trénovacími):

original_data_address = "https://s3.amazonaws.com/torch7/data/cifar10torchsmall.zip"
 
function file_exists(filename)
    local fin = io.open(filename,"r")
    if fin then
        io.close(fin)
        return true
    else
        return false
    end
end
 
 
function download_file(address, filename)
    local command = "wget -v -O " .. filename .. " " .. address
    os.execute(command)
end
 
 
function unzip_file(filename)
    local command = "unzip " .. filename
    os.execute(command)
end
 
 
function setup(address, filename)
    if not file_exists(filename) then
        download_file(address, filename)
    end
    if not file_exists("cifar10-test.t7") or
       not file_exists("cifar10-train.t7") then
        unzip_file(filename)
    end
end
 
 
--setup(original_data_address, "cifar10torchsmall.zip")

Poznámka: poslední řádek je zakomentovaný schválně, protože stažení a rozbalení dat bude prováděno z hlavního modulu celého projektu.

6.2 Modul classification_classes

Tento modul nazvaný classification_classes je velmi jednoduchý, protože obsahuje pouze jedinou tabulku se jmény tříd obrázků (tato jména jsou použita při exportu obrázků ze vstupní množiny) a taktéž pomocnou funkci, která na základě jména třídy vrátí celé číslo v rozsahu 1..10. Právě toto číslo (neboli celočíselný index) je použito ve vstupní množině pro klasifikaci obrázků:

classification_classes = {
    'airplane',
    'automobile',
    'bird',
    'cat',
    'deer',
    'dog',
    'frog',
    'horse',
    'ship',
    'truck'
}
 
 
function get_label_index(label)
    for i, lbl in ipairs(classification_classes) do
        if lbl == label then
            return i
        end
    end
    return nil
end

7. Hlavní modul celého projektu

První verze hlavního modulu celého projektu, v níž jsou obsaženy všechny důležité konstanty, vypadá následovně:

require("nn")
require("image")
require("gnuplot")
 
require("image_lib/image_writer")
 
require("nn/nn_constructor")
require("nn/nn_trainer")
require("nn/nn_validators")
 
require("utils/cifar_downloader")
require("utils/classification_classes")
 
 
-- globalni nastaveni
CLASSES = 10
 
 
-- parametry obrazku
WIDTH = 32
HEIGHT = 32
 
 
-- parametry neuronove site
INPUT_PLANES = 3
 
MIDDLE_PLANES = {64, 64}
 
HIDDEN_NEURONS = 100
OUTPUT_NEURONS = 10
 
-- parametry konvolucni vrstvy
CONVOLUTION_KERNEL_SIZE = 5
 
-- parametry pooling vrstvy
POOLING_SIZE = 2
POOLING_STEP = 2
 
-- parametry pro uceni neuronove site
MAX_ITERATION = 20
LEARNING_RATE = 0.01
 
MAX_SIZE_OF_TRAINING_SET = 1000
 
 
 
network = construct_neural_network(WIDTH, HEIGHT, INPUT_PLANES, MIDDLE_PLANES,
                                   HIDDEN_NEURONS, OUTPUT_NEURONS,
                                   CONVOLUTION_KERNEL_SIZE, POOLING_SIZE, POOLING_STEP)
 
print("Struktura neuronove site")
print(network)
 
setup_cifar_dataset(original_data_address, zip_file_name)
 
input_training_set = torch.load('cifar10-train.t7')
 
print("Struktura vstupnich dat")
print(input_training_set.data:size())
 
training_data = prepare_training_data(input_training_set, MAX_SIZE_OF_TRAINING_SET)
 
train_neural_network(network, training_data, LEARNING_RATE, MAX_ITERATION)
 
validation_set = torch.load('cifar10-test.t7')
 
validate_neural_network(network, validation_set)

Od příkladu popsaného v předchozím článku se změnil především způsob získání trénovacích a validačních obrázků, ovšem zapomenout nesmíme ani na změněnou hodnotu INPUT_PLANES, který reflektuje fakt, že obrázky již nejsou monochromatické, ale jsou reprezentovány v barvovém prostoru RGB.

8. Průběh tréningu konvoluční neuronové sítě

Podívejme se na průběh tréningu (učení) námi vytvořené konvoluční neuronové sítě. Po spuštění hlavního modulu projektu skriptem run.sh se nejprve provede konstrukce sítě určené pro klasifikaci tenzorů 3×32×32 komponent. Struktura celé sítě se následně vypíše na konzoli:

Size x: 5
Size y: 5
Struktura neuronove site
nn.Sequential {
  [input -> (1) -> (2) -> (3) -> (4) -> (5) -> (6) -> (7) -> (8) -> (9) -> (10) -> output]
  (1): nn.SpatialConvolution(3 -> 64, 5x5)
  (2): nn.Tanh
  (3): nn.SpatialMaxPooling(2x2, 2,2)
  (4): nn.SpatialConvolution(64 -> 64, 5x5)
  (5): nn.Tanh
  (6): nn.SpatialMaxPooling(2x2, 2,2)
  (7): nn.View(1600)
  (8): nn.Linear(1600 -> 100)
  (9): nn.ReLU
  (10): nn.Linear(100 -> 10)
}

Následně dojde k načtení trénovacích dat (deserializaci tenzoru) a vypíše se jejich struktura. Povšimněte si, že k dispozici máme „jen“ 10×000 trénovacích obrázků, nikoli 50×000, jak je tomu v originální databázi:

Struktura vstupnich dat
 10000
     3
    32
    32
[torch.LongStorage of size 4]

Následuje vlastní učení sítě:

# StochasticGradient: training
# current error = 0.087419532316487
# current error = 0.08250235596666
# current error = 0.080230850680852
# current error = 0.077974234283241

povšimněte si, že může dojít ke kolísání chyby okolo nějaké chybové hodnoty (zde přibližně 0.009). To může značit fakt, že se síť při učení dostala do lokálního minima, ovšem pokud použijeme větší počet iterací, mělo by se toto úskalí překonat:

# current error = 0.010221119870583
# current error = 0.0088532006341434
# current error = 0.010162795768825
# current error = 0.0098526088304169
# current error = 0.01331067852011
# current error = 0.010431707186109
# current error = 0.0095516891939589

9. Validace neuronové sítě

Dalším krokem je pochopitelně validace neuronové sítě.

Obrázek 6: Sada testovacích obrázků s kočkami (kategorie cat).

Ukažme si jen několik posledních výsledků. V prvním sloupci je vypsána skutečná klasifikace obrázku získaná z testovacích dat, ve druhém sloupci pak objekt, který rozpoznala síť. Následuje příznak shody a také „jistota“, s jakou síť obrázek klasifikovala. Ideálně by se zde měla vyskytovat jednička či vyšší hodnota, naproti tomu odhady 0,5 a menší jsou příliš nejisté:

bitcoin_skoleni

truck       truck       true    0.52322672637698
airplane    dog         false   0.35518980035599
deer        deer        true    1.4037388636467
horse       horse       true    0.35070451362636
ship        ship        true    0.25252624795777
cat         dog         false   0.45795296167838
automobile  airplane    false   0.30874442469959
bird        dog         false   0.26461606217843
airplane    airplane    true    0.5877179917673
automobile  automobile  true    0.36849457038214
dog         cat         false   0.2006054691743
ship        ship        true    0.637623002454
deer        airplane    false   0.42689508867567
frog        cat         false   0.3862858463384
cat         bird        false   0.65612247517723
ship        bird        false   0.14112528584036
automobile  truck       false   0.68867536855129
cat         cat         true    0.63109539823786
ship        airplane    false   0.54685976158814
-------------------------------------------------
Errors: 584
Error rate: 58.4%

10. Rozbor výsledků a zlepšení odhadu sítě

Výsledky validace sítě, s nimiž jsme se seznámili v předchozí kapitole, nemusí na první pohled vypadat příliš povzbudivě. Musíme si ale uvědomit, že se neuronová síť přece jen „něco“ naučila, protože kdyby jen náhodně hádala, dosahovala by chyba 90 % a nikoli jen 58 %. Navíc jsou některé obrázky v databázi skutečně jen nesnadno rozeznatelné (například hned první obrázek), takže chyby 0 % nedosáhneme (pěkným výsledkem může být 10 %). Některé další možnosti vylepšení si popíšeme příště. Jedná se především o tyto oblasti:

  1. Až na několik nepatrných úprav používáme neuronovou síť určenou pro rozpoznávání mnohem jednodušších objektů (teoreticky stačilo rozpoznat pozadí od popředí). Jednou z oblastí vylepšení bude přidání další vrstvy či vrstev, a to buď do konvoluční části sítě, nebo do části s běžně propojenými neurony.
  2. Díky zvětšení kapacity sítě v předchozím bodu bude praktické pro trénink použít celou množinu trénovacích obrázků a nikoli jen prvních 1000 (pro každou třídu jsme vlastně měli k dispozici zhruba 100 obrázků, což není mnoho).
  3. Prozatím jsme také neprováděli žádný preprocesing obrázků, což u rozpoznávání monochromatických číslic příliš nevadilo, ale u plnobarevných obrázků to již může být užitečné.
  4. Užitečný může být i převod obrázků do jiného barvového prostoru, například HSV, HSL, YCbCr atd., neboť se tím může snížit velká závislost odhadu sítě na barvě objektu.

11. Repositář s demonstračním projektem

Demonstrační projekt, který jsme si popsali v předchozích kapitolách, najdete v GIT repositáři dostupném na adrese https://github.com/tisnik/torch-examples.git. Následují odkazy na zdrojové kódy jednotlivých souborů projektu:

12. Odkazy na Internetu

  1. CIFAR-10 Dataset
    http://www.cs.toronto.edu/~kriz/ci­far.html
  2. CIFAR-10, CIFAR-100 dataset introduction
    http://corochann.com/cifar-10-cifar-100-dataset-introduction-1258.html
  3. Deep Learning with Torch
    https://github.com/soumit­h/cvpr2015/blob/master/De­ep%20Learning%20with%20Tor­ch.ipynb
  4. THE MNIST DATABASE of handwritten digits
    http://yann.lecun.com/exdb/mnist/
  5. MNIST database (Wikipedia)
    https://en.wikipedia.org/wi­ki/MNIST_database
  6. MNIST For ML Beginners
    https://www.tensorflow.or­g/get_started/mnist/begin­ners
  7. Stránka projektu Torch
    http://torch.ch/
  8. Torch: Serialization
    https://github.com/torch/tor­ch7/blob/master/doc/seria­lization.md
  9. Torch: modul image
    https://github.com/torch/i­mage/blob/master/README.md
  10. Data pro neuronové sítě
    http://archive.ics.uci.edu/ml/in­dex.php
  11. LED Display Domain Data Set
    http://archive.ics.uci.edu/ml/da­tasets/LED+Display+Domain
  12. Torch na GitHubu (několik repositářů)
    https://github.com/torch
  13. Torch (machine learning), Wikipedia
    https://en.wikipedia.org/wi­ki/Torch_%28machine_learnin­g%29
  14. Torch Package Reference Manual
    https://github.com/torch/tor­ch7/blob/master/README.md
  15. Torch Cheatsheet
    https://github.com/torch/tor­ch7/wiki/Cheatsheet
  16. Neural network containres (Torch)
    https://github.com/torch/nn/blob/mas­ter/doc/containers.md
  17. Simple layers
    https://github.com/torch/nn/blob/mas­ter/doc/simple.md#nn.Line­ar
  18. Transfer Function Layers
    https://github.com/torch/nn/blob/mas­ter/doc/transfer.md#nn.tran­sfer.dok
  19. Feedforward neural network
    https://en.wikipedia.org/wi­ki/Feedforward_neural_net­work
  20. Biologické algoritmy (4) – Neuronové sítě
    https://www.root.cz/clanky/biologicke-algoritmy-4-neuronove-site/
  21. Biologické algoritmy (5) – Neuronové sítě
    https://www.root.cz/clanky/biologicke-algoritmy-5-neuronove-site/
  22. Umělá neuronová síť (Wikipedia)
    https://cs.wikipedia.org/wi­ki/Um%C4%9Bl%C3%A1_neuronov%C3%A1_s%C3%AD%C5%A5
  23. Učení s učitelem (Wikipedia)
    https://cs.wikipedia.org/wi­ki/U%C4%8Den%C3%AD_s_u%C4%8Di­telem
  24. Plotting with Torch7
    http://www.lighting-torch.com/2015/08/24/plotting-with-torch7/
  25. Plotting Package Manual with Gnuplot
    https://github.com/torch/gnu­plot/blob/master/README.md
  26. An Introduction to Tensors
    https://math.stackexchange­.com/questions/10282/an-introduction-to-tensors
  27. Gaussian filter
    https://en.wikipedia.org/wi­ki/Gaussian_filter
  28. Gaussian function
    https://en.wikipedia.org/wi­ki/Gaussian_function
  29. Laplacian/Laplacian of Gaussian
    http://homepages.inf.ed.ac­.uk/rbf/HIPR2/log.htm
  30. Odstranění šumu
    https://cs.wikipedia.org/wi­ki/Odstran%C4%9Bn%C3%AD_%C5%A­1umu
  31. Binary image
    https://en.wikipedia.org/wi­ki/Binary_image
  32. Erosion (morphology)
    https://en.wikipedia.org/wi­ki/Erosion_%28morphology%29
  33. Dilation (morphology)
    https://en.wikipedia.org/wi­ki/Dilation_%28morphology%29
  34. Mathematical morphology
    https://en.wikipedia.org/wi­ki/Mathematical_morphology
  35. Cvičení 10 – Morfologické operace
    http://midas.uamt.feec.vut­br.cz/ZVS/Exercise10/conten­t_cz.php
  36. Differences between a matrix and a tensor
    https://math.stackexchange­.com/questions/412423/dif­ferences-between-a-matrix-and-a-tensor
  37. Qualitatively, what is the difference between a matrix and a tensor?
    https://math.stackexchange­.com/questions/1444412/qu­alitatively-what-is-the-difference-between-a-matrix-and-a-tensor?
  38. BLAS (Basic Linear Algebra Subprograms)
    http://www.netlib.org/blas/
  39. Basic Linear Algebra Subprograms (Wikipedia)
    https://en.wikipedia.org/wi­ki/Basic_Linear_Algebra_Sub­programs
  40. Comparison of deep learning software
    https://en.wikipedia.org/wi­ki/Comparison_of_deep_lear­ning_software
  41. TensorFlow
    https://www.tensorflow.org/
  42. Caffe2 (A New Lightweight, Modular, and Scalable Deep Learning Framework)
    https://caffe2.ai/
  43. PyTorch
    http://pytorch.org/
  44. Seriál o programovacím jazyku Lua
    http://www.root.cz/serialy/pro­gramovaci-jazyk-lua/
  45. LuaJIT – Just in Time překladač pro programovací jazyk Lua
    http://www.root.cz/clanky/luajit-just-in-time-prekladac-pro-programovaci-jazyk-lua/
  46. LuaJIT – Just in Time překladač pro programovací jazyk Lua (2)
    http://www.root.cz/clanky/luajit-just-in-time-prekladac-pro-programovaci-jazyk-lua-2/
  47. LuaJIT – Just in Time překladač pro programovací jazyk Lua (3)
    http://www.root.cz/clanky/luajit-just-in-time-prekladac-pro-programovaci-jazyk-lua-3/
  48. LuaJIT – Just in Time překladač pro programovací jazyk Lua (4)
    http://www.root.cz/clanky/luajit-just-in-time-prekladac-pro-programovaci-jazyk-lua-4/
  49. LuaJIT – Just in Time překladač pro programovací jazyk Lua (5 – tabulky a pole)
    http://www.root.cz/clanky/luajit-just-in-time-prekladac-pro-programovaci-jazyk-lua-5-tabulky-a-pole/
  50. LuaJIT – Just in Time překladač pro programovací jazyk Lua (6 – překlad programových smyček do mezijazyka LuaJITu)
    http://www.root.cz/clanky/luajit-just-in-time-prekladac-pro-programovaci-jazyk-lua-6-preklad-programovych-smycek-do-mezijazyka-luajitu/
  51. LuaJIT – Just in Time překladač pro programovací jazyk Lua (7 – dokončení popisu mezijazyka LuaJITu)
    http://www.root.cz/clanky/luajit-just-in-time-prekladac-pro-programovaci-jazyk-lua-7-dokonceni-popisu-mezijazyka-luajitu/
  52. LuaJIT – Just in Time překladač pro programovací jazyk Lua (8 – základní vlastnosti trasovacího JITu)
    http://www.root.cz/clanky/luajit-just-in-time-prekladac-pro-programovaci-jazyk-lua-8-zakladni-vlastnosti-trasovaciho-jitu/
  53. LuaJIT – Just in Time překladač pro programovací jazyk Lua (9 – další vlastnosti trasovacího JITu)
    http://www.root.cz/clanky/luajit-just-in-time-prekladac-pro-programovaci-jazyk-lua-9-dalsi-vlastnosti-trasovaciho-jitu/
  54. LuaJIT – Just in Time překladač pro programovací jazyk Lua (10 – JIT překlad do nativního kódu)
    http://www.root.cz/clanky/luajit-just-in-time-prekladac-pro-programovaci-jazyk-lua-10-jit-preklad-do-nativniho-kodu/
  55. LuaJIT – Just in Time překladač pro programovací jazyk Lua (11 – JIT překlad do nativního kódu procesorů s architekturami x86 a ARM)
    http://www.root.cz/clanky/luajit-just-in-time-prekladac-pro-programovaci-jazyk-lua-11-jit-preklad-do-nativniho-kodu-procesoru-s-architekturami-x86-a-arm/
  56. LuaJIT – Just in Time překladač pro programovací jazyk Lua (12 – překlad operací s reálnými čísly)
    http://www.root.cz/clanky/luajit-just-in-time-prekladac-pro-programovaci-jazyk-lua-12-preklad-operaci-s-realnymi-cisly/
  57. Lua Profiler (GitHub)
    https://github.com/luafor­ge/luaprofiler
  58. Lua Profiler (LuaForge)
    http://luaforge.net/projec­ts/luaprofiler/
  59. ctrace
    http://webserver2.tecgraf.puc-rio.br/~lhf/ftp/lua/
  60. The Lua VM, on the Web
    https://kripken.github.io/lu­a.vm.js/lua.vm.js.html
  61. Lua.vm.js REPL
    https://kripken.github.io/lu­a.vm.js/repl.html
  62. lua2js
    https://www.npmjs.com/package/lua2js
  63. lua2js na GitHubu
    https://github.com/basicer/lua2js-dist
  64. Lua (programming language)
    http://en.wikipedia.org/wi­ki/Lua_(programming_langu­age)
  65. LuaJIT 2.0 SSA IR
    http://wiki.luajit.org/SSA-IR-2.0
  66. The LuaJIT Project
    http://luajit.org/index.html
  67. LuaJIT FAQ
    http://luajit.org/faq.html
  68. LuaJIT Performance Comparison
    http://luajit.org/performance.html
  69. LuaJIT 2.0 intellectual property disclosure and research opportunities
    http://article.gmane.org/gma­ne.comp.lang.lua.general/58908
  70. LuaJIT Wiki
    http://wiki.luajit.org/Home
  71. LuaJIT 2.0 Bytecode Instructions
    http://wiki.luajit.org/Bytecode-2.0
  72. Programming in Lua (first edition)
    http://www.lua.org/pil/contents.html
  73. Lua 5.2 sources
    http://www.lua.org/source/5.2/
  74. REPL
    https://en.wikipedia.org/wi­ki/Read%E2%80%93eval%E2%80%93prin­t_loop
  75. The LLVM Compiler Infrastructure
    http://llvm.org/ProjectsWithLLVM/
  76. clang: a C language family frontend for LLVM
    http://clang.llvm.org/
  77. LLVM Backend („Fastcomp“)
    http://kripken.github.io/emscripten-site/docs/building_from_source/LLVM-Backend.html#llvm-backend
  78. Lambda the Ultimate: Coroutines in Lua,
    http://lambda-the-ultimate.org/node/438
  79. Coroutines Tutorial,
    http://lua-users.org/wiki/CoroutinesTutorial
  80. Lua Coroutines Versus Python Generators,
    http://lua-users.org/wiki/LuaCorouti­nesVersusPythonGenerators

Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.