Klasyfikator obrazów na Google Colaboratory
Podobnie jak w artykule o tłumaczeniu maszynowym przygotowaliśmy dla was interaktywne demo zakodowane w języku Python na platformie Google Colaboratory. Uruchamiamy je w analogiczny sposób, a niezbędne pliki można pobrać.
Spróbujemy stworzyć model, który będzie rozpoznawał marki starych polskich samochodów. Dostępnych jest 2400 oznakowanych zdjęć samochodów do szkolenia i 270 w zestawie testowym, które musimy spróbować opatrzyć etykietą. Spójrzmy zatem na kod.
Tutaj importujemy niezbędne biblioteki (do czego one służą, dowiemy się z dalszej lektury):

PATH jest ścieżką do twoich danych − jeśli użyjesz zalecanych metod konfiguracji przedstawionych w tym artykule, nie będziesz musiał tego zmieniać.
sz to rozmiar, do którego obrazy zostaną przeskalowane w celu zapewnienia szybkiego przebiegu uczenia. Zostawmy na razie 224 piksele.
![]()
Ważne jest, aby mieć działający układ GPU NVidia. Schemat programowania używany do pracy z procesorami graficznymi NVidia nosi nazwę CUDA. Dlatego zanim zaczniesz kontynuować, musisz upewnić się, że następująca linia zwraca wartość True. Jeśli masz z tym problemy, to znaczy, że Colaboratory nie został prawidłowo skonfigurowany.
![]()
Ponadto NVidia zapewnia specjalne funkcje zoptymalizowane do głębokiego uczenia zawarte w pakiecie o nazwie CuDNN. Chociaż nie jest to bezwzględnie konieczne, znacznie poprawi wydajność i jest domyślnie uwzględnione we wszystkich obsługiwanych konfiguracjach FastAI. Dlatego jeśli poniższy kod nie zwróci wartości True, warto sprawdzić, dlaczego.

Nasza biblioteka zakłada, że masz katalogi train i valid. Zakłada się także, że każdy katalog będzie zawierał podkatalogi dla każdej klasy, która ma zostać rozpoznana (w tym przypadku maluch, polonez itp.). Jest to wygodnie, bo jeżeli zechcesz rozpoznawać inne auta, wystarczy, że wgrasz je do folderów, bez konieczności kodowania.


Oto jak wyglądają dane surowe:

Użyjemy wstępnie wyszkolonego modelu, czyli modelu stworzonego przez kogoś innego, aby rozwiązać inny problem. Zamiast budować model od zera, aby rozwiązać analogiczny problem, jako punkt wyjścia wykorzystamy model przeszkolony na danych ImageNet (1,2 miliona obrazów i 1000 klas). Model ten to właśnie duża sieć konwolucyjna.
Będziemy używać modelu resnet34, który wygrał konkurs ImageNet 2015. Tutaj jest więcej informacji na temat modeli resnet.
Poniżej przedstawiono sposób szkolenia oraz ocenę marki starego polskiego samochodu w trzech liniach kodu i czasie poniżej 20 sekund z wykorzystaniem gotowego modelu:

Jak dobry jest ten model? Kilka lat temu w podobnym zadaniu stan techniki umożliwiał osiągnięcie 80-procentowej dokładności. Ale Kaggle spowodowało ogromny skok celności − do 98,9%, a autor popularnej biblioteki dogłębnej nauki zwyciężył w konkursie.
Warto przyjrzeć się nie tylko ogólnym wskaźnikom, ale też przykładom każdego z nich:
- Kilka poprawnych etykiet losowo
- Kilka nieprawidłowych etykiet losowo
- Najbardziej poprawne etykiety każdej klasy (tj. te z najwyższym prawdopodobieństwem poprawne)
- Najbardziej niepoprawne etykiety każdej klasy (tj. te z najwyższym prawdopodobieństwem nieprawidłowe)
- Najbardziej niepewne etykiety (tj. te z prawdopodobieństwem najbliższym 0,5)

Stąd wiemy, że maluch to etykieta 0, a polonez to etykieta 1.

To polecenie daje przewidywanie dla zestawu sprawdzania poprawności. Prognozy są w skali logarytmicznej

Kilka poprawnych etykiet losowo:

Kilka niepoprawnych etykiet losowo:

Etykiety dla malucha, które zostały rozpoznane z największą trafnością:

Etykiety dla poloneza, które zostały rozpoznane z największą trafnością:

Etykiety dla malucha, które zostały rozpoznane z najmniejszą trafnością:

Etykiety dla poloneza, które zostały rozpoznane z najmniejszą trafnością:

Najbardziej niepewne predykcje:

Taka analiza danych powinna nas naprowadzić na ścieżkę do poprawy danych celem zwiększenia precyzji.
Metoda learn.lr_find() pomaga znaleźć optymalną prędkość uczenia się. Wykorzystuje technikę opracowaną w 2015 roku i opisaną w publikacji Cyclical Learning Rates for Training Neural Networks. Technika ta polega na tym, że po prostu ciągle zwiększana jest szybkość uczenia z bardzo małej wartości, aż strata przestaje maleć. Możemy określić szybkość uczenia się dla różnych partii, aby zobaczyć, jak to wygląda.
Najpierw tworzymy nowego ucznia, ponieważ chcemy wiedzieć, jak ustawić tempo uczenia się dla nowego (niewytrenowanego) modelu.

W naszym obiekcie learn jest atrybut sched, który zawiera nasz program do planowania szybkości uczenia się i ma kilka wygodnych funkcji kreślenia, w tym:

Widzimy wykres straty w stosunku do wskaźnika uczenia się, aby zobaczyć, gdzie zmniejsza się nasza strata:

Strata wciąż wyraźnie poprawia się w lr = 1e-2 (0.01), więc tego używamy. Zwróć uwagę, że optymalna szybkość uczenia się może się zmieniać podczas treningu modelu, więc możesz chcieć ponownie uruchomić tę funkcję od czasu do czasu.
Jeśli spróbujesz treningu na większej liczbie epok, zauważysz, że zaczynamy przetrenowywać sieć, co oznacza, że model uczy się rozpoznawać konkretne obrazy w zbiorze treningowym, a nie generalizować tak, że uzyskujemy również dobre wyniki na zestawie walidacyjnym. Jednym ze sposobów rozwiązania tego problemu jest efektywne tworzenie większej ilości danych dzięki rozszerzeniu danych. Odnosi się to do losowej zmiany obrazów w sposób, który nie powinien wpływać na ich interpretację, taki jak przekręcanie w poziomie, powiększanie i obracanie z kadrowaniem.
Możemy to zrobić, przekazując aug_tfms (augmentation transforms) dotfms_from_model z listą funkcji do zastosowania, które losowo zmieniają obraz, jak tylko chcemy. W przypadku zdjęć, które są w dużej mierze robione z boku (np. większość zdjęć samochodów, w przeciwieństwie do zdjęć zrobionych od góry do dołu, takich jak zdjęcia satelitarne), możemy użyć wstępnie zdefiniowanej listy funkcji transforms_side_on. Możemy również określić losowe powiększanie obrazów do określonej skali, dodając parametr max_zoom.

Stwórzmy nowy obiekt data, który obejmuje to rozszerzenie transformacji.
Po ponownym treningu widzimy, że precyzja poprawiła się z 80% do 85,71%.

Domyślnie, gdy tworzymy ucznia, ustawia on wszystkie warstwy oprócz ostatniej na zamrożone. Oznacza to, że wciąż aktualizuje wagi tylko w ostatniej warstwie, a warstwy resnet34 nie są modyfikowane.

Czym jest parametr cycle_len? To, co tutaj zrobiliśmy, to technika zwana stochastycznym spadkiem gradientu z restartem (SGDR), wariantem wyżarzania szybkości uczenia, które stopniowo zmniejsza szybkość uczenia się w miarę postępu treningu. Jest to pomocne, ponieważ gdy zbliżamy się do optymalnych wag, chcemy podjąć mniejsze kroki.
Jednakże możemy znaleźć się w części przestrzeni wagi, która nie jest bardzo odporna − to znaczy niewielkie zmiany masy mogą spowodować duże zmiany w stratach. Chcemy zachęcić model do znalezienia części przestrzeni wagi, które są zarówno dokładne, jak i stabilne. Dlatego od czasu do czasu zwiększamy szybkość uczenia (jest to restart w SGDR), co zmusi model do przejścia do innej części przestrzeni wagi, jeśli obecny obszar jest „spiczasty”. Oto obraz tego, jak to może wyglądać, jeśli zresetujemy współczynniki uczenia się trzy razy (w tym dokumencie nazywa się to cyklicznym harmonogramem LR):

Liczba epok pomiędzy resetowaniem współczynnika uczenia się jest ustalana przez cykl_liczba, a liczba razy, kiedy to się dzieje, jest określana jako liczba cykli , i jest tym, co faktycznie przekazujemy jako drugi parametr do dopasowania. Oto jak wyglądały nasze rzeczywiste wskaźniki uczenia się:

Nasza strata w zakresie walidacji nie poprawia się w znacznym stopniu, więc prawdopodobnie nie ma potrzeby dalszego szkolenia ostatniej warstwy na własną rękę. Precyzja po tym zabiegu przekracza już 88%.
Ponieważ w tym momencie mamy całkiem niezły model, możemy chcieć go zapisać, abyśmy mogli go później załadować ponownie bez szkolenia od zera.

Teraz, gdy mamy już wytrenowaną dobrą warstwę końcową, możemy spróbować dopracować pozostałe warstwy, czyli nasz resnet34. Aby zakomunikować uczniowi, że chcemy odblokować pozostałe warstwy, wystarczy użyć Unfreeze ().
![]()
Zauważ, że pozostałe warstwy zostały już przeszkolone do rozpoznawania zdjęć ImageNetowych (podczas gdy nasze końcowe warstwy zostały losowo zainicjowane), więc powinniśmy uważać, aby nie zniszczyć dokładnie wyregulowanych wag, które już tam są.
Generalnie, wcześniejsze warstwy mają więcej funkcji ogólnego przeznaczenia. Dlatego oczekiwalibyśmy, że będą potrzebowały mniejszego dostrajania nowych zestawów danych. Z tego powodu użyjemy różnych współczynników uczenia dla różnych warstw: pierwsze kilka warstw będzie na poziomie 1e-4, środkowe warstwy na poziomie 1e-3, a nasze warstwy − 1e-2, tak jak poprzednio. Mówimy o tym jako o zróżnicowanych wskaźnikach uczenia się, chociaż nie ma standardowej nazwy dla tej technologii w literaturze, o której nam wiadomo.

Kolejną sztuczką, której tutaj użyliśmy, jest dodanie parametru cycle_mult.
Cykle są mierzone w epokach, więc cycle_len = 1 samo w sobie oznaczałoby ciągłe zmniejszanie szybkości uczenia się w trakcie jednej epoki, a następnie przeskakiwanie z powrotem do góry. Parametr cycle_mult mówi, aby pomnożyć długość cyklu przez coś (w tym przypadku przez 2), jak tylko ukończysz jeden cykl.

Zauważ, że to, co przedstawiono powyżej, to wskaźnik uczenia się ostatnich warstw. Współczynniki uczenia się wcześniejszych warstw są ustalane na tych samych wielokrotnościach ostatecznych poziomów warstw zgodnie z pierwotnym żądaniem (pierwsze warstwy mają 100x mniejsze, a warstwy średnie 10x mniejsze szybkości uczenia się, ponieważ ustawiamy lr = np.array ([ 1e-4,1e-3,1e-2]). To wszystko skutkuje precyzją przekraczającą 95%.

Jest jeszcze coś, co możemy zrobić z wcześniej dokonanym rozszerzeniem danych: użyjemy go w czasie wnioskowania (znanym również jako czas testu(TTA)).
TTA po prostu tworzy prognozy, nie tylko na obrazach w twoim zbiorze testowym, ale także tworzy prognozy dla pewnej liczby losowo rozszerzonych ich wersji (domyślnie używa oryginalnego obrazu wraz z czterema losowo rozszerzonymi wersjami). Następnie pobiera średnie prognozy z tych obrazów i wykorzystuje je. Aby użyć TTA w zestawie sprawdzania poprawności, możemy skorzystać z metody "TTA ()" ucznia.

Pozwala to zbliżyć się do 96%.
Dalszej poprawy możemy starać się uzyskać poprzez analizę wyników i wnioskowanie. Pomocna będzie macierz błędów (tablica pomyłek):

Popularnym sposobem analizy wyniku modelu klasyfikacyjnego jest użycie macierzy błędów. Scikit Learn ma wygodną funkcję, którą możemy wykorzystać do tego celu:

Możemy po prostu wydrukować macierz błędów lub wyświetlić widok graficzny (który jest przydatny głównie dla osób z większą liczbą kategorii).

Ponowne spojrzenie na zdjęcia:

Podsumowując: podjęliśmy proste kroki do wyszkolenia klasyfikatora obrazu światowej klasy.

tylko czy źródła są gdzieś dostępne do pobrania (i eksperymentowania)?
git clone ?
wyobraź sobie że Python'a uczy się na kierunku studiów geografia...
jest to jeden z najłatwiejszych jeżyków
a co do trudności to jeszcze nie zauważyłem żadnych pochodnych...
jeśli temat Cie przerasta po prostu możesz go ominąć
wszystkim nie dogodzisz
Robimy ciekawe, techniczne artykuły - źle. Robimy artykuły dla początkujących - też źle. Tak myślę że salomonowym rozwiązaniem jest omijanie tych artykułów które nas nie interesują
jak już mówiłem ...
wszystkim nie dogodzisz
być może problemem jest brak ogniw pośrednich
jest to jeden z najłatwiejszych jeżyków
U mnie na informatyce wszyscy żartowali, że w zdecydowanej większości przypadków (i zastosowań) Python ogranicza się do 'import [odpowiednia biblioteka]' i trzech linijek na jej obsługę
Takiego Laba pokochałem i za takim Labem przez ostatni rok tęskniłem <3