"Deep Learning" - book review

18 maja 2023
Jakub Rojek Jakub Rojek
Source: real photo of the book
Kategorie: Programowanie, Literatura

Wiadomo, że dobrze czytać książki, a jeszcze lepiej czytać dobre książki. W przypadku literatury fachowej dochodzi do tego jeszcze potrzeba, aby książka była jak najdłużej aktualna i faktycznie niosła ze sobą wiedzę - w końcu nie są to tanie towary. Z tego powodu, czy tego chcemy, czy nie warto nabywać pozycje omawiające podstawy teoretyczne. Z drugiej strony, wiadomo, że często najłatwiej zaznajomić się z tematem poprzez przykłady, co zazwyczaj wymaga wprowadzenia narzędzi, które mają tendencję do starzenia się. A gdyby tak połączyć te dwa obszary i mieć książkę, która zawiera zarówno teorię (wręcz matematyczną), jak i praktykę? Taki miał być "Deep Learning. Praktyczne wprowadzenie z zastosowaniem środowiska Pythona". Przynajmniej teoretycznie - zobaczmy, czy w praktyce też tak jest. Tak, jestem dumny z tego słownego żartu.

Obecnie warto zasięgnąć trochę informacji o sieciach neuronowych lub je rozszerzyć. Powodem jest, oczywiście, stale rosnący udział metod uczenia maszynowego lub - szerzej mówiąc - sztucznej inteligencji w zastosowaniach komercyjnych, co sprawia, że specjaliści w tych dziedzinach, umiejący dobrać, przygotować i pomyślnie wytrenować model będą na wagę złota. A nawet, jeśli programista jest specjalistą w innej dziedzinie lub niecodziennie ma kontakt z podobną funkcjonalnością, to warto przyswoić sobie tę wiedzę lub odświeżyć, jeśli posiada się już podstawy ze studiów. Z takim podejściem rozglądałem się za odpowiednią książką i trafiłem na bohatera dzisiejszego tekstu. Poniżej jego recenzja.

Nie ukrywam, że szczególnie zachęciła mnie obietnica połączenia teorii i praktyki w postaci przykładów kodu, a konktretnie w Pythonie. Jeśli ktoś programuje nie od wczoraj, to doskonale wie, że to właśnie w tym języku powstała bardzo duża pula bibliotek do uczenia maszynowego, statystyki i innych "naukowych" tematów. Stąd ta technologia jest tak lubiana w ośrodkach naukowych i nie tylko, gdyż trzeba przyznać, że Python jest bardzo uniwersalny. Jeśli ktoś potrzebuje konkretów, to w książce zabawa koncentruje się wokół takich paczek jak NumPy, scikit-learn i Keras. Warto wspomnieć, że to wszystko nie oznacza, iż w innych językach nie można wykonywać podobnych obliczeń - też znajdą się tam potrzebne biblioteki. A to ważne dla osób niesympatyzujących z Pythonem stosowanym w książce, która w dodatku nie przedstawia tego kodu bardzo przejrzyście - można zauważyć tutaj trochę skrótów, sklejanie fragmentów w sposób wymagający uwagi (choć tego akurat trudno było uniknąć), wykorzystanie niuansów składni, a jeśli chodzi o estetykę kodu, to pewnie miałbym trochę uwag podczas przeglądu. Natomiast warto wspomnieć, że jeśli ktoś nie zna tej technologii lub nie jest w niej biegły, to nie musi się martwić - cały jeden rozdział jest poświęcony konstrukcjom Pythona, a inny bibliotece NumPy. Jeśli ktoś jest zapoznany z tymi zagadnieniami, to może spokojnie te fragmenty ominąć, szybciej dochodząc do "mięsa".

Nie jest to bowiem książka stricte o kodowaniu, tylko o uczeniu maszynowym, więc omówmy ją pod tym kątem. Trzeba przyznać, że autor (Ronald T. Kneusel, naukowiec specjalizujący się w omawianym temacie) starał się napisać pozycję dla zielonych, choć ambitnych. I niemalże mu się to udało, ale najpierw prześledźmy, co tutaj mamy:

  • przypomnienie zagadnień ze statystyki i algebry liniowej (wektory, macierze), które są stosowane w tym obszarze,
  • informacje dotyczące budowania zestawu danych do uczenia i testowania,
  • klasyczne metody uczenia maszynowego: centroidy, metoda k najbliższych sąsiadów, naiwny Bayes, drzewa decyzyjne, lasy losowe, maszyny wektorów nośnych (SVM),
  • sieci neuronowe nadzorowane - matematyczne omówienie podstaw i zasad uczenia się,
  • miary oceny przydatności modeli, czyli statystyki operujące na macierzy pomyłek (true positive i inne, bardziej złożone wskaźniki, które z tego wynikają),
  • splotowe sieci neuronowe, stosowane głównie do rozpoznawania grafik,
  • klasyfikowanie próbek dźwiękowych.

Na początku powiedzmy sobie jedną rzecz - autor bardzo dużo miejsca poświęca właściwemu przygotowaniu zestawów danych, a także eksperymentom. W mojej ocenie to bardzo ważne, ponieważ uczenie maszynowe nie polega na tym, że bierzemy wybraną metodę (jeszcze najlepiej taką, której nazwa nam się najbardziej podoba), wrzucamy do niej dane i zyskujemy idealny klasyfikator. Bardzo dużo zależy od "wejścia", które zostanie przygotowane i podzielone na zestawy uczące, walidujące oraz testowe. Oczywiście, rekordów powinno być dużo, ale znaczenie mają też atrybuty, czystość i charakter, gdyż to przekłada się później na wybór konkretnej metody. Co więcej, autor opisuje, w jaki sposób rozszerzać zbiór danych, co pomaga modelowi w uczeniu. Trochę zaskoczyło mnie, że z setek danych w ten sposób można zrobić tysiące i model rzeczywiście działa lepiej. W książce przedstawione są metody, jak to się robi.

Eksperymenty też są ciekawą sprawą, gdyż autor poświęca kilka rozdziałów na pokazanie, w jaki sposób zmiany metod dla poszczególnych problemów (zbiorów danych) oraz dobranie odpowiednich parametrów pozwalają podnieść lub zmniejszyć skuteczność modelu. Tak, zmniejszyć - książka pod tym kątem "nie jest nudna" i pokazuje, że nie zawsze zmiana wszystkich ustawień wydłużająca czas nauki powoduje polepszenie rezultatu. Warto korzystać z wniosków oraz wykresów zaprezentowanych przez dr. Kneusela, aby oszczędzić sobie pracy w rzeczywistych przypadkach.

Jeśli chodzi o samo wyjaśnianie metod, to mam wrażenie, że jest dosyć nierówne. W przypadku klasycznych (tzw. płytkich) podejść autor omawia je nieźle, w łatwy do zrozumienia sposób, choć może czasem aż w nieco zbyt skrócony. Nie ukrywam, że gdybym nie miał wcześniej odpowiedniego przedmiotu na studiach, to np. trudniej byłoby mi zrozumieć ideę drzewa decyzyjnego - tam aż prosi się jakiś przykład krok po kroku przy każdej metodzie, aby pokazać zasadę działania danej ścieżki klasyfikacji. Natomiast przy sieciach neuronowych autor wyraźnie za punkt honoru postawił sobie wyjaśnienie tego zagadnienia faktycznie od podstaw. Także tych matematycznych, które nie dla wszystkich są równie zrozumiałe. I mam wrażenie, że trochę przesadził - brakuje mi tutaj (lub je przypadkiem pominąłem) takiego wytłumaczenia na prostym przykładzie, jak działa sieć przy uczeniu się kolejnych informacji, nawet na bardzo małym zbiorze danych, co oznacza zmiana wag itd. Zamiast tego autor skupia się na gradiencie, pochodnych, funkcjach i operowaniu symbolami. Owszem - to powinno być i na pewno jest to coś, co przyda się studentom informatyki czy osobom, chcącym tym zagadnieniem zająć się na poważnie. Ale obawiam się, że programiści chcący zrozumieć faktycznie podstawy sieci od strony praktycznej, aby móc potem używać biblioteki, odbiją się od tej pozycji, chyba że zagryzą zęby lub od razu przejdą do rozdziałów opisujących eksperymenty. Sam w którymś momencie zacząłem bardziej kartkować niż wnikliwie czytać, z czego nie jestem dumny, ale właśnie sądziłem, że wszystko wyjaśni się w doświadczeniach.

Warto też wspomnieć, że w tej książce mamy do czynienia głównie z problemami klasyfikacji i to binarnej (dwie przeciwstawne klasy), ale jak najbardziej uwzględnione są też podejścia z wieloma klasami. To atut tej pozycji - pokazuje, w jaki sposób podchodzić do tego problemu (i to od praktycznej strony), a także jak ocenić, czy dobrze wytrenowaliśmy taki model. W ten sposób przedstawione jest np. klasyfikowanie grafik z cyframi oraz próbkami dźwiękowymi, czemu towarzyszy omówienie drugiego "konika" autora, a więc sieci splotowych (gdzieniegdzie nazywanych też "konwolucyjnymi"). Także w tym przypadku mamy trochę matematyki, ale tym razem jest ona dość zrozumiała. Tym niemniej, zabrakło chyba bardziej czytelnego przykładu, ale to może już moje wygórowane wymagania.

Należy wspomnieć o tym, że w tej książce nie ma omówionych sieci rekurencyjnych, nienadzorowanych, a także ze wzmocnieniem. O każdym z tych zagadnień jest wspomnienie zawarte w 1-2 akapitach, ale to tyle. Trochę szkoda, gdyż to właśnie sieci ze wzmocnieniem są najbardziej interesujące w kontekście nowych narzędzi AI robiących furorę, natomiast należy zwrócić uwagę na to, że do ich zrozumienia i tak potrzebna jest wiedza o podstawach uczenia się sieci neuronowych, którą autor dostarcza. Dodatkowo, jeśli miałby dołączyć rozdziały dotyczące każdego typu sieci, to książka miałaby nie ok. 470 stron, tylko bliżej 600. Oczywiście, co najmniej połowa tomu dotyczy ogólnych informacji, takich jak posługiwanie się Pythonem, danymi wejściowymi oraz klasycznymi metodami uczenia się, ale taki jest urok pozycji dla początkujących.

Jeśli chodzi o styl pisania, to mimo fragmentów bardzo technicznych i ścisłej terminologii, autor zdecydowanie unika naukowego patosu. Wtedy, kiedy jest potrzeba, wprowadza "wykładowy klimat", ale pozwala sobie również na kolokwialne sformułowania (szczególnie, kiedy model nie działa tak dobrze, jak zakładano), a w niektórych miejscach nawet na drobne żarty. Również tłumacz stanął na wysokości zadania i widać, że nie była to tylko osoba dobrze znająca język angielski, ale także znawca obszaru sztucznej inteligencji. Książka ma dość dużo wykresów, grafik i listingów kodu, więc mimo wspomnianych już 470 stron nie jest to długa pozycja.

Podsumowując, uważam, że recenzowana książka to niezły podręcznik do nauki podstaw uczenia maszynowego i sieci neuronowych, ale głównie dla studentów informatyki, którzy jakieś podstawy mieli na uczelni lub poznali je inną drogą. Niektóre części są opisane zbyt skrótowo, inne zbyt matematycznie. Natomiast dużą zaletą jest faktyczne podpieranie się przykładowymi kodami w Pythonie, prezentowanie gotowych programów oraz wyników eksperymentów wraz z omówieniem przydatności poszczególnych metod. Powiedziałbym, że to taka książka na 6/10, może 7/10 - jak najbardziej godna uwagi, choć nie sprawi, że wszyscy nagle będą biegli w fundamentach czegoś, co być może zaleje świat.

Pozdrawiam i dziękuję - Jakub Rojek.

Lubimy pisać, nawet bardzo, ale na co dzień tworzymy aplikacje webowe i mobilne. Sprawdź niektóre z wykonanych przez programów.

Komentarze

Wczytywanie komentarzy...

O autorze

Jakub Rojek

Główny programista i współwłaściciel Wilda Software, z wieloletnim doświadczeniem w tworzeniu i rozwoju oprogramowania, ale także w pisaniu tekstów na różnorakich blogach. Zaprawiony w boju analityk i architekt systemów IT. Jednocześnie absolwent Politechniki Poznańskiej i okazjonalny prowadzący zajęcia na tej uczelni. W wolnych chwilach oddaje się graniu w gry wideo (głównie w karcianki), czytaniu książek, oglądaniu futbolu amerykańskiego i e-sportu, odkrywaniu cięższej muzyki oraz wytykaniu innym błędów językowych.

Jakub Rojek