Tentokrát se ještě vrátíme k metodám umělé inteligence, o kterých byl i minulý článek s názvem “Pusťme na data umělou inteligenci!” . Dnes si ukážeme, jak si můžete jednoduše vyzkoušet optimalizaci pomocí diferenciální evoluce, tedy jedné z metod umělé inteligence. Jde o implementaci v jazyku R, a tak abyste si mohli vše vyzkoušet budete k tomu potřebovat mít nainstalovanou podporu jazyka R, R studio a package DEoptim. To je vše. A teď už si pojďme ukázat, jak diferenciální evoluci použít.
Po spuštění R studia je nejprve nutné zavést knihovnu DEoptim.
library(“DEoptim”)
Následně potřebujeme definovat funkci, která představuje matematicky přepis naší úlohy. Postupně si ukážeme tři příklady, kde se budeme stažit najít extrém zadaných funkcí. Ten vyjadřuje cíl optimalizace.
Příklad 1
První z funkcí bude Boothova funkce. Jde o funkci, která má po zobrazení v 3D prostoru podobu konvexně prohnuté plochy (obrázek 1). Funkce má dva argumenty, které jsou definovány v intervalu -10 až 10 a globální minimum má hodnotu 0 pro x = 1 a y = 3. A právě nalezení hodnot pro x a y, které odpovídají globálními minimu bude cílem diferenciální evoluce.

Pro běh diferenciální evoluce nastavíme interval hledaných argumentů funkce a parametry diferenciální evoluce. Velikost populace dáme na 100, počet generací na 1000, mutační konstanta bude rovna hodnotě 0.7 a práh křížení 0.4. Můžeme spustit.
Booth <- function(args) { x <- args[1] y <- args[2] (x + 2*y — 7)² + (2*x + y — 5)² } lower <- c(-10, -10) upper <- -lower set.seed(1234) output <- DEoptim(Booth, lower, upper, DEoptim.control(NP = 100, itermax = 1000, F = 0.7, CR = 0.4)) plot(output, col = rgb(0, 100, 0, 50, maxColorValue = 255), pch = 16) par(mfrow=c(1,2)) plot(output$member$bestmemit, main = “CV”, ylab = “y”, xlab = “x”, col = rgb(0, 100, 0, 50, maxColorValue = 255), pch = 16) plot(c(1:length(output$member$bestvalit)), output$member$bestvalit, main = “Konvergence CV”, ylab = “CV”, xlab = “Generace”, type = “l”, col = “blue”) output$optim$bestval output$optim$bestmem
Po doběhnutí evoluce se můžeme podívat, jakým způsobem se vyvíjelo hledání argumentů funkce. Už po několika málo generacích došlo k nalezení správných argumentů.

Můžeme si ještě zobrazit jak probíhalo vyhodnocení cost value v čase. A také jednotlivé konečné argumenty a hodnotu, odpovídající globálními minimu. Podle toho, jak řešení konvergovalo k hledanému globálními minimu v závislosti na generacích je možné vidět, že diferenciální evoluci trvalo nalezení správného řešení jen velmi krátce.

Příklad 2
Pojďme teď vyzkoušet nalezení extrému druhé funkce. Jde o Matyasovu funkci a opět jde o konvexní plochu.

Globální minimum se nachází v bodě 0,0 a má hodnotu zase 0. Argumenty budeme hledat na intervalu -10 až 10. Ve skriptu upravíme zápis funkce a můžeme spustit.
library(“DEoptim”) Matyas <- function(args) { x <- args[1] y <- args[2] (x + 2*y — 7)² + (2*x + y — 5)² } lower <- c(-10, -10) upper <- -lower set.seed(1234) output <- DEoptim(Matyas, lower, upper, DEoptim.control(NP = 100, itermax = 1000, F = 0.7, CR = 0.4)) plot(output, col = rgb(0, 100, 0, 50, maxColorValue = 255), pch = 16) par(mfrow=c(1,2)) plot(output$member$bestmemit, main = “CV”, ylab = “y”, xlab = “x”, col = rgb(0, 100, 0, 50, maxColorValue = 255), pch = 16) plot(c(1:length(output$member$bestvalit)), output$member$bestvalit, main = “Konvergence CV”, ylab = “CV”, xlab = “Generace”, type = “l”, col = “blue”) output$optim$bestval output$optim$bestmem
Stejně jako v předchozím případě si můžeme zobrazit jak byly postupně zpřesňovány argumenty funkce v závislosti na uplynulých generacích. Podle toho, jak se argumenty vyvíjely je možné vidět, že to umělá inteligence zvládla zase velice rychle.


Příklad 3
Poslední ukázka bude komplexnější. Půjde o funkci Eggholder, která připomíná plato na vejce. Je to funkce, které má spoustu lokálních minim a její argumenty jsou definovány na intervalu -512 až 512.

Jak si s tím poradí umělá inteligence? Nejprve přidáme zápis funkce a upravíme interval argumentů.
library(“DEoptim”) Eggholder <- function(args) { x <- args[1] y <- args[2] -(y + 47) * sin(sqrt(abs(x/2 + (y + 47)))) — x * sin(sqrt(abs(x — (y + 47)))) } lower <- c(-512, -512) upper <- -lower set.seed(1234) output <- DEoptim(Eggholder, lower, upper, DEoptim.control(NP = 100, itermax = 1000, F = 0.7, CR = 0.4)) plot(output, col = rgb(0, 100, 0, 50, maxColorValue = 255), pch = 16) par(mfrow=c(1,2)) plot(output$member$bestmemit, main = “CV”, ylab = “y”, xlab = “x”, col = rgb(0, 100, 0, 50, maxColorValue = 255), pch = 16) plot(c(1:length(output$member$bestvalit)), output$member$bestvalit, main = “Konvergence CV”, ylab = “CV”, xlab = “Generace”, type = “l”, col = “blue”) output$optim$bestval output$optim$bestmem
Po spuštění a následném zobrazení vývoje hledání argumentů vidíme, že i v tomto případu našla diferenciální evoluce řešení hodně brzy, a to ještě před 200. generací. To nám potvrzují i další dva grafy.


Závěr
Dnes jsme si ukázali, jak najít dva parametry funkce tak, abychom dostali její globální minimum. Pro dva parametry v intervalu -10 až 10 by nebylo problém jejich nalezení např. pomocí procházení oboru hodnot pomocí cyklu, ale v případech, kdy je těchto argumentů buď větší množství, nebo daný problém obsahuje velké množství lokální extrémů, jak třeba u plata vajec, by to už pomocí cyklů tak ideální nebylo. Buď by to trvalo příliš dlouho z důvodu velkého rozsahu intervalu hodnot argumentů, v případě kdy tyto hodnoty nejsou celá čísla a je tak nutné řešit inkrementy argumentů v cyklech, nebo by se také mohlo stát, že by algoritmus implementující přístup pomocí podmínek v cyklu nebyl schopný překonat lokální extrémy. A to je důvod, proč jsou metody umělé inteligence tak používané.