Dlaczego porzuciłem Tensorflow na rzecz Pytorch

Już od jakiegoś czasu nosiłem się z zamiarem przejścia z Tensorflow na PyTorch. Poziom skomplikowania, jaki osiągnął TF zaczął mi przeszkadzać, a tych, których uczyłem wręcz przerażał. Przejście na Pytorch było jedną z lepszych decyzji.

Wpis ten zapoczątkował serię artykułów o PyTorch, w każdym artykule opisuję pewien aspekt tej biblioteki oraz przykłady najpopularniejszych architektur sieci neuronowych.

Moja historia przyjaźni z Pytroch’em sięga roku 2017, gdzie na konferencji PyData Warsaw Adam Paszke opowiadał o nowej bibliotece do uczenia maszynowego. Ja wtedy zapalony użytkownik Tensorflow siedziałem i z otwartą gębą słuchałem, jak Adam po kolei zadaje ciosy na korpus dla TF. Każdy punkt dokładnie trafiał w moje dotychczasowe doświadczenia z pracy z biblioteką od Google.

Prezentacja, która była punktem zapalnym i spowodowała porzucenie TF i przejście na Pytorch.

Co prawda słyszałem już wcześniej o Pytorch, ale nigdy wcześniej nie byłem na tyle zmotywowany, aby zacząć się jej uczyć. Dopiero prezentacja oraz krótka rozmowa po prezentacji zmotywowała mnie, aby zacząć ją poznawać.

Co mnie przekonało do Pytorch?

Swoje odczucia opisuję po ponad 8 miesiącach nauki i pracy z Pytorch głównie w wersji 0.4 (obecnie już 1.0).

To, co mnie zachwyciło to prostota oraz filozofia zgodna z Zen Python. W Tensorflow miałem wrażenie pisania w innym języku, w czymś, co tylko przypomina Pythona. Tak jakby był on na siłę dostawioną fasadą.

Dostęp do zmiennych

Na pierwszym miejscu muszę wymienić możliwość łatwego wyświetlenia zawartości zmiennych. Nawet nie wiecie jak mi szczęka opadła, gdy zobaczyłem, że mogę podejrzeć macierz wag w prostej sieci. Z pozoru tak błaha cecha a tak potężna. U mnie rozwiązało to niemal 90% problemów związanych z nauką oraz debugowaniem własnej architektury.

Możliwość podejrzenia zmiennej w debuggerze lub zwyczajne wyprintowanie jej stanu to dla mnie killer feature .

Integracja z numpy

Pracując z danymi na którymś etapie na pewno będziecie zmuszeni do trzymania danych w tablicy numpy. Możliwość łatwego przekazania lub transformowania tych danych do algorytmu uczącego znacząco ułatwia sprawę. Dwie proste funkcje tensor.numpy i from_numpy pozwalają na proste i co ważne szybkie przekształcenie tensora na tablicę numpy lub tablicy na tensor.

Pytorch idzie nawet dalej, bo prócz prostej integracji z numpy dostajemy w pakiecie całą filozofię pracy. To, co mogliśmy zrobić z tablicami możemy w większości zrobić z tensorami: indeksowanie, slicing, zmiana rozmiarów, stacking itp. Mnie to bardzo ułatwiło zrozumienie niektórych aspektów Pytorch oraz samą naukę. Po prostu część API była już mi znajoma już z numpy.

Dynamiczne budowanie grafu obliczeniowego

W odróżnieniu od Tensorflow, który opiera się na podejściu deklaratywnym, w PyTorch w naturalny sposób można dynamicznie (czyli np. z użyciem 'if’) zmieniać architekturę sieci. Pozwala to na dużą elastyczność i ułatwia implementację wielu nowych architektur.

Dostęp do danych – Datasets i Dataloaders

Dla mnie zawsze było bolączką pisanie kodu, który ma wczytać zbiór danych. Każda szanująca się biblioteka ma już gotowe klasy dostępu do popularnych zbiorów jak MNIST, CIFAR czy IMDB. Niestety, gdy chcesz wczytać swój własny dataset to w wielu przypadkach trzeba było napisać coś samemu.

W Pytorch też trzeba napisać trochę kodu, ale poprzez dostarczenie dobrych abstrakcji łatwiej wepniemy się w cały flow. Klasa Dataset dostarcza dobrze zdefiniowany interfejs dostępu do danych. Nie trzeba pisać własnych konstrukcji a tylko podziedziczyć po niej i nadpisać dwie metody (__len__ i __getitem__) . Proste i czytelne, a zarazem dające dużą elastyczność.

Resztę związaną z podziałem na 'batch-e’, wielowątkowym dostępem do danych, kolejkowaniem dostępu, randomizacją, grupowaniem egzemplarzy w ramach paczek oraz transformacją (augumentacja zdjęć, tokenizacja tekstu itp) załatwia Dataloader. Polecam przykład, w którym zadanie polega na wczytywaniu punktów charakterystycznych twarzy https://pytorch.org/tutorials/beginner/data_loading_tutorial.html

Ułatwione uruchamianie na GPU

Gotowy produkcyjny model trenujemy na GPU, ale zanim to nastąpi większość czasu spędzałem na testowaniu sieci na CPU. W Pytorch’u jedną linijką na początku skryptu mogę określić na jakim 'device’ chcę uruchomić.

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

Przystępniejsze API

Ten punkt jest bardzo subiektywny, bo tyczy się konwencji nazewniczych, sposobu projektowania i interakcji. Nazwy metod, klas oraz cała architektura Pytorch jest dla mnie przystępniejsza niż u Tensorflow. Byłem pozytywnie zaskoczony podejściem do obliczania wstecznej propagacji błędów. Jawne wywołanie funkcji .backprop() odpowiada mojej filozofii programowania i projektowania API. Lubię czyste, proste interfejsy wraz z pewną nadmiarowością nazewniczą. Wolę nadmiarowość niż auto-magiczne działanie.

Niektórym może przeszkadzać, że musimy pamiętać, aby np. jawnie wyzerować gradienty. Dla mnie takie explicite podejście jest w zgodzie z filozofią pythona a daje poczucie większej kontroli.

Pytorch community

Bardzo aktywna i chętna do pomocy społeczność dostępna pod adresem https://discuss.pytorch.org/ . Samo forum jest pokaźnym zbiorem wiedzy na temat sposobów implementacji różnych architektur. Odpowiedzi na swoje pytania albo znajdowałem w innych wątkach, albo uzyskiwałem odpowiedź w przeciągu 6h.

Inne zalety, których nie testowałem

Prócz wymienionych zalet, które odczułem na swojej skórze dla kompletności przytoczę te które są także wymieniane:

  • obliczenia rozproszone w modelu podobnych do MPI
  • torch.jit – jeszcze w fazie beta

Podsumowanie

Tak z ciekawości porównałem Pytorch i Tensorflow na Google Trends. Widać że TF się jeszcze dobrze trzyma, ale dostrzegam już tendencję spadkową. Pytorch idzie w górę i sądzę że rok 2019 będzie zdecydowanie należał tej biblioteki (u mnie na pewno).

Poniżej wklejam aktualizację z 2.12.2019, tak jak sądziłem Pytroch sukcesywnie wspina się w górę. Na pewno na to miał wielki wpływ powstanie bibliotek takich jak: Pytorch-Transformers, Pytorch-Lightning

Z drugiej strony Tensorflow także się trzyma, szczególnie po wydaniu wersji 2.0.

A co znajduje się w waszej skrzynce narzędziowej badacza danych? Pytorch, Tensorflow, fastai, czy jeszcze coś innego?

Jeżeli uważasz ten wpis za wartościowy to Zasubskrybuj bloga. Dostaniesz informacje o nowych artykułach.

Join 100 other subscribers

PS. Photo by Brendan Church on Unsplash

14 Comments Dlaczego porzuciłem Tensorflow na rzecz Pytorch

    1. ksopyla

      Tak i jest to dla mnie też argument za pytroch, bo można w fastai pisać własne nn.modules i to działa.

  1. Paweł

    Cześć. Ciekawy wpis. Mozesz zatem powiedzieć osobie, która startuje z ML aby poszła w stronę pytorcha? Czy lepiej za ciosem wpadać do tensorflow i keras a rownoczesnie robić pytorcha? Pozdro!

    Reply
    1. ksopyla

      Ja teraz szedłbym w Pytroch, ciekawy ekosystem, dobre community, dużo nowych architektur jest w nim implementowanych.
      Ponadto mam doświadczenia z nauczania innych i łatwiej uczy się Pytorch’a.

  2. Paweł

    Cześć. Ciekawy wpis. Mozesz zatem powiedzieć osobie, która startuje z ML aby poszła w stronę pytorcha? Czy lepiej za ciosem wpadać do tensorflow i keras a rownoczesnie robić pytorcha? A może fast.ai skoro wyszedł kurs v3?Pozdro!

    Reply
    1. ksopyla

      Tak fastai jest na pytorch i to jest moim zdaniem kolejny argument za Pytorch.
      Co prawda z fastai miałem krótki romans i brakuje jej jeszcze dobrej dokumentacji.
      Łatwość i szybkość implementacji najnowszych technik i modeli bije chyba nawet KERAS.

  3. Bartosz Ptak

    Cześć!
    Wiele rzeczy, które wymieniłeś jako wyższość mają mieć również swoje miejsce w TF 2.0. Jeśli będą spełniać twoje wymagania, jesteś w stanie porzucić PyTorch i wrócić do tensorflow?

    Reply
    1. ksopyla

      Dzięki Mateusz. Ja już wsiąkłem w Pytroch, obecnie zdobył już tak bogaty ekosystem że ciężko mi się przestawić z powrotem na Tensorflow.

  4. Piotr

    Dzięki za blog. Dodaję go do blogów czytanych.

    Ze swojej strony dodam, że jakoś nie potrafię się przekonać do Pytorch.
    Uczyłem się DL na Tensor (np rozpoznawanie MINST) i kod TF wydaje mi się jakoś bardziej czytelny i bardziej logiczny…

    Reply

Ciekawe, wartościowe, podziel się proszę opinią!

Witryna wykorzystuje Akismet, aby ograniczyć spam. Dowiedz się więcej jak przetwarzane są dane komentarzy.