uczenie głębokie to podzbiór metod uczenia maszynowego, które opierają się na sztucznych sieciach neuronowych. Są one inspirowane przetwarzaniem informacji i rozproszonymi węzłami komunikacyjnymi w systemach biologicznych, takich jak mózg. W uczeniu głębokim każdy poziom uczy się przekształcać dane wejściowe w nieco bardziej abstrakcyjną i złożoną reprezentację. Na przykład w systemie rozpoznawania twarzy piksele mogą być jedną warstwą systemu, podczas gdy krawędzie mogą być inne, oczy mogą być inne, a twarz może być inna. Złożoność metod głębokiego uczenia sprawia, że korzystanie z istniejących pakietów jest popularne w społeczności programistycznej. TensorFlow i PyTorch w Pythonie są popularne, podobnie jak pakiet Keras w R. Jednak w produkcji systemów głębokiego uczenia wydajność i bezpieczeństwo to dwie kwestie, które napędzają firmy do wyboru funkcjonalnych języków programowania, takich jak Clojure i Haskell.
- trudności implementacji głębokiego uczenia
- dlaczego Programowanie funkcyjne jest bardziej odpowiednie do uczenia głębokiego
- Clojure
- moc programowania współbieżnego w Clojure
- równoległość w Clojure jest tania
- funkcje łańcuchowe w Clojure oznaczają przejrzystość
- tożsamość i stan w Clojure zapewniają bezpieczeństwo
- Biblioteki i ograniczenia
- Haskell
- Type safety w Haskell zapewnia bezpieczeństwo i elastyczność
- prosty jawny kod w Haskell zapewnia jasne implementacje
- równoległość wielordzeniowa w Haskell zapewnia wydajność
- Biblioteki i ograniczenia
- wnioski
trudności implementacji głębokiego uczenia
przy wprowadzaniu systemów głębokiego uczenia do produkcji, sieci neuronowe mogą zawierać milion parametrów. Dane mogą szybko eksplodować, aby wytrenować te parametry. Ta eksplozja danych wymaga wydajności, którą można osiągnąć tylko dzięki wydajnemu językowi programowania z bezpiecznymi możliwościami współbieżności i równoległości. Ze względu na złożoność sieci neuronowych, przy przekazywaniu danych z warstwy na warstwę, ważna jest prostota i spójność sposobu, w jaki język programowania obsługuje te dane. Bezpieczeństwo oznacza w tym przypadku możliwość zachowania stanu oryginalnych danych w spójny sposób, a prostota oznacza możliwość łatwego odczytu i utrzymania bazy kodu przy maksymalizacji wydajności.
dlaczego Programowanie funkcyjne jest bardziej odpowiednie do uczenia głębokiego
próbując rozwiązać niektóre trudności, które mogą wystąpić podczas wdrażania uczenia głębokiego, Programiści odkrywają, że funkcjonalne języki programowania mogą zapewnić rozwiązania.
w informatyce Programowanie funkcyjne jest paradygmatem programowania, który traktuje obliczenia jako ocenę funkcji matematycznych i unika zmieniających się stanów i zmiennych danych. Jest to wzorzec programistyczny bliższy matematycznemu myśleniu.
modele głębokiego uczenia są zasadniczo modelami matematycznymi. Na przykład sztuczne sieci neuronowe obejmują połączone węzły, z których każdy wykonuje proste operacje matematyczne. Używając funkcjonalnego języka programowania, programiści są w stanie opisać te operacje matematyczne w języku, który jest bliższy samym operacjom. Jawny sposób pisania tych programów znacznie ułatwia czytanie i utrzymywanie bazy kodu.
jednocześnie składowy charakter algorytmów głębokiego uczenia oznacza, że na każdej warstwie pracy neuronowej warstwy lub funkcje mają tendencję do łączenia się ze sobą w celu wykonywania zadań. Można to łatwo zaimplementować za pomocą funkcjonalnego łańcucha funkcjonalnego języka programowania.
ponadto w uczeniu głębokim, gdy funkcje są stosowane do danych, Dane nie ulegają zmianie. Nowe wartości mogą być wyprowadzane sekwencyjnie w dół linii, ale same dane pozostają spójne. Funkcja niezmienności funkcjonalnego języka programowania pozwoli programiście na utworzenie nowego zbioru danych za każdym razem, gdy nowe wartości są generowane bez zmiany oryginalnego niezmiennego zbioru danych. Ułatwia to zachowanie spójności danych w całej sieci neuronowej.
wreszcie, duża liczba parametrów i danych szkoleniowych zaangażowanych we wdrażanie głębokiego uczenia oznacza, że równoległość i współbieżność są kluczami do tworzenia systemów głębokiego uczenia na poziomie produkcyjnym. Równoległość oznacza uruchamianie wątków na różnych procesorach, aby przyspieszyć proces uczenia się. Współbieżność oznacza możliwość zarządzania wątkami, aby uniknąć konfliktów. Programowanie funkcyjne pozwala na współbieżność i równoległość bez żadnych kosztów. Oznacza to, że ze swej natury Programowanie funkcyjne, gdzie Czysta funkcja jest bezstanowa, zawsze będzie produkować to samo wyjście dla określonego wejścia, prowadzić do możliwości wyodrębnienia dowolnej funkcji i wykonania, kiedy tylko zechcesz. Ułatwia to zarządzanie współbieżnością i równoległością. Nie musisz radzić sobie z takimi problemami, jak impasy i warunki wyścigu. Różne wątki uzyskujące dostęp do różnych procesorów będą mogły działać niezależnie bez żadnych sporów.
Clojure
dzięki programowaniu funkcyjnemu zyskuje popularność w deep learning, a dzięki solidnym pakietom dostępnym do deep learning, Clojure jest obecnie preferowany przez firmy takie jak Walmart i Facebook. Jest to wysokopoziomowy, dynamiczny, funkcjonalny język programowania oparty na języku programowania LISP i posiada Kompilatory, które umożliwiają uruchamianie zarówno w środowisku Java, jak i.NET runtime environment.
moc programowania współbieżnego w Clojure
Clojure nie zastępuje systemu wątków Javy, a raczej z nim współpracuje. Ponieważ podstawowe struktury danych są niezmienne, można je łatwo udostępniać między wątkami. Jednocześnie możliwe są zmiany stanu w programie, ale Clojure zapewnia mechanizmy zapewniające spójność Stanów. Jeśli wystąpią konflikty między dwiema transakcjami próbującymi zmodyfikować ten sam odnośnik, jedna z nich zostanie wycofana. Nie ma potrzeby wyraźnego zamykania.
(import '(java.util.concurrent Executors))(defn test-stm (let (fn (dotimes (dosync (doseq (alter r + 1 t)))))) (range nthreads))] (doseq (.get future)) (.shutdown pool) (map deref refs)))(test-stm 10 10 10000) -> (550000 550000 550000 550000 550000 550000 550000 550000 550000 550000)
źródło
równoległość w Clojure jest tania
w głębokim uczeniu modele muszą trenować na dużych ilościach danych. Równoległość oznacza uruchamianie wielu wątków na różnych procesorach. Równoległość, która jest tania, oznacza znaczną poprawę wydajności. Korzystanie z partycji w połączeniu z map może osiągnąć równoległość, która jest mniej kosztowna.
(defn calculate-pixels-2 (let (doall (map (fn (let (get-color (process-pixel (/ row (double *width*)) (/ col (double *height*)))))) x))) work)] (doall (apply concat result))))
źródło
funkcje łańcuchowe w Clojure oznaczają przejrzystość
w Clojure istnieje wiele funkcji dla bardzo niewielu typów danych. Funkcje mogą być również przekazywane jako argumenty do innych funkcji, co umożliwia łączenie funkcji w uczeniu głębokim. Dzięki implementacji bliższej rzeczywistemu modelowi matematycznemu kod Clojure może być łatwy do odczytania i utrzymania.
;; pipe arg to function(-> "x" f1) ; "x1";; pipe. function chaining(-> "x" f1 f2) ; "x12"
źródło
tożsamość i stan w Clojure zapewniają bezpieczeństwo
w Clojure tożsamość każdego modelu ma jeden stan w dowolnym momencie. Ten stan jest prawdziwą wartością, która nigdy się nie zmienia. Jeśli tożsamość wydaje się zmieniać, dzieje się tak dlatego, że jest powiązana z innym stanem. Nowe wartości są funkcjami starego. W każdej warstwie sieci neuronowej zawsze zachowywany jest stan oryginalnych danych. Każdy zestaw danych z nowymi wartościami, które są wyjściami funkcji, może działać niezależnie. Oznacza to, że działania mogą być wykonywane na tych zestawach danych bezpiecznie lub bez względu na niezgodność. W każdej chwili możemy wrócić do pierwotnego stanu danych. Dlatego spójność w tym przypadku oznacza bezpieczeństwo.
Biblioteki i ograniczenia
historycznie biblioteka uczenia maszynowego cortex zawiera wszystko, czego potrzebujesz do implementacji algorytmów uczenia maszynowego w Clojure. Wraz z rosnącą ostatnio popularnością open-source mxnet framework for deep learning, łatwiej jest wdrożyć deep learning przy użyciu interfejsu API MXNET-Clojure.
chociaż obecnie dostępne są różne interfejsy API i biblioteki uczenia maszynowego dla Clojure, nadal istnieje stroma krzywa uczenia się, aby uzyskać płynność w tym zakresie. Komunikaty o błędach mogą być tajemnicze, a firmy będą musiały zainwestować z góry, aby wykorzystać je do skalowania swoich systemów uczenia maszynowego. Ponieważ więcej przykładów systemów gotowych do produkcji jest pisanych w Clojure, język ten zyska większą popularność w nadchodzących latach, ale tylko wtedy, gdy liczba i rozmiar bibliotek towarzyszących użyciu Clojure będzie stale rosnąć.
Haskell
Haskell jest językiem funkcjonalnym, który jest statycznie typowany za pomocą wnioskowania typów i leniwej oceny. Jest on oparty na semantyce języka programowania Miranda i uważany za bardziej ekspresyjny, szybszy i bezpieczniejszy w implementacji uczenia maszynowego.
Type safety w Haskell zapewnia bezpieczeństwo i elastyczność
Type safety definiuje ograniczenia dotyczące typów wartości, które może posiadać zmienna. Pomoże to zapobiegać nielegalnym operacjom, zapewnia lepsze bezpieczeństwo pamięci i prowadzi do mniejszej liczby błędów logicznych. Leniwa ewaluacja oznacza, że Haskell opóźni ewaluację wyrażenia, dopóki jego wartość nie będzie potrzebna. Pozwala również uniknąć powtarzających się ocen, co pozwoli zaoszczędzić czas pracy. Jednocześnie leniwa ewaluacja pozwala na definiowanie nieskończonych struktur danych. Daje to programiście nieograniczone możliwości matematyczne.
prosty jawny kod w Haskell zapewnia jasne implementacje
jedną z największych zalet Haskella jest to, że może on opisywać algorytmy w bardzo wyraźnych konstrukcjach matematycznych. Model można przedstawić w kilku linijkach kodu. Możesz również odczytać kod w ten sam sposób, w jaki możesz odczytać równanie matematyczne. Może to być bardzo potężne w złożonych algorytmach, takich jak algorytmy głębokiego uczenia w uczeniu maszynowym. Na przykład poniższa implementacja pojedynczej warstwy sieci neuronowej typu feed-forward pokazuje, jak czytelny może być Kod.
import Numeric.LinearAlgebra.Static.Backproplogistic :: Floating a => a -> alogistic x = 1 / (1 + exp (-x))feedForwardLog :: (KnownNat i, KnownNat o) => Model (L o i :& R o) (R i) (R o)feedForwardLog (w :&& b) x = logistic (w #> x + b)
źródło
równoległość wielordzeniowa w Haskell zapewnia wydajność
w uczeniu głębokim typowe sieci neuronowe będą zawierały milion parametrów definiujących model. Ponadto, duża ilość danych jest wymagana do poznania tych parametrów, co, obliczeniowo, jest bardzo czasochłonne. Korzystanie z wielu rdzeni do równoległego współdzielenia pamięci i procesu na jednej maszynie może być bardzo wydajne, jeśli chodzi o wdrażanie uczenia głębokiego. Jednak w Haskell implementacja równoległości wielordzeniowej jest łatwa.
Biblioteki i ograniczenia
Biblioteka Hlearn Haskella zawiera implementacje algorytmów uczenia maszynowego, podczas gdy Wiązanie tensor-flow dla Haskella może być używane do głębokiego uczenia. Równoległość i współbieżność są natomiast używane do równoległości i współbieżności.
chociaż istnieją pewne biblioteki uczenia maszynowego opracowane w Haskell, implementacje ground-up nadal będą musiały być wykonane dla gotowych do produkcji implementacji Haskell. Podczas gdy biblioteki publiczne dostępne dla konkretnych zadań uczenia głębokiego i uczenia maszynowego są ograniczone, użycie Haskella w sztucznej inteligencji również będzie ograniczone. Firmy takie jak Aetion Technologies i Credit Suisse Global Modeling and Analytics Group wykorzystują Haskell w swoich wdrożeniach—oto pełna lista organizacji, które z niego korzystają.
wnioski
modele głębokiego uczenia są złożonymi modelami matematycznymi, które wymagają określonych warstw funkcji. Funkcjonalne języki programowania, takie jak Clojure i Haskell, mogą często reprezentować złożoność z czystszym kodem, który jest bliższy matematyce modelu. Prowadzi to do oszczędności czasu, wydajności i łatwego zarządzania bazą kodu. Specyficzne właściwości programowania funkcyjnego pozwalają na bezpieczniejsze implementacje w tych językach niż w innych językach. Wraz z rozwojem technologii sztucznej inteligencji, ocena tych języków na potrzeby wielkoskalowych projektów programistycznych w sztucznej inteligencji stanie się bardziej rozpowszechniona.
ten artykuł jest częścią Behind the Code, mediów dla programistów, przez programistów. Odkryj więcej artykułów i filmów, odwiedzając Behind the Code!
chcesz się przyłączyć? Pobierz publikację!
Śledź nas na Twitterze, aby być na bieżąco!
Ilustracja Wiktorii Roussel