praca-magisterska/docs/document.tex

455 lines
20 KiB
TeX
Raw Normal View History

\documentclass[12pt,a4paper,reqno,twoside]{mwbk}
\usepackage[MeX]{polski}
\usepackage[utf8]{inputenc}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{makeidx}
\usepackage{graphicx}
\usepackage{fancyhdr}
\usepackage{chapter-style}
2020-04-06 19:23:25 +02:00
\usepackage{tikz}
\usepackage{listings}
\textheight 21.1 cm
\voffset = 1.2 cm
\textwidth 14 cm
\hoffset = -0.5 cm
\oddsidemargin = 1.4 cm
\newtheorem{de}{Definicja}
\newtheorem{tw}{Twierdzenie}
\pagestyle{fancy}
\renewcommand{\chaptermark}[1]{\markboth{#1}{}}
%\renewcommand{\sectionmark}[1]{\markright{\thesection\ #1}}
\fancyhf{} \fancyhead[LE,RO]{\small\thepage}
%\fancyhead[LO]{\small\rightmark}
\fancyhead[RE]{\small\leftmark}
\fancyheadoffset[LO]{0 cm}
\fancyheadoffset[RE]{0 cm}
\renewcommand{\headrulewidth}{0.5pt}
\renewcommand{\footrulewidth}{0pt}
\addtolength{\headheight}{0.5pt}
\fancypagestyle{plain}{
\fancyhead{}
\renewcommand{\headrulewidth}{0pt}
}
\makeindex
\begin{document}
% Strona tytułowa
\thispagestyle{empty}
\begin{center}
\textsc{UNIWERSYTET IM. ADAMA MICKIEWICZA W POZNANIU}
\vglue 0.1 cm
\textsc{WYDZIAŁ MATEMATYKI I INFORMATYKI}
\vglue 2.1 cm
{\LARGE \bf Cezary Adam Pukownik}
\vglue 1cm
{\large Kierunek: Analiza i przetwarzanie danych}
2020-04-06 19:23:25 +02:00
% \medskip
2020-04-06 19:23:25 +02:00
% {\large Specjalność: Uczenie maszynowe}
\medskip
{\large Numer albumu: 444337}
\vspace{1.5cm}
{\Huge \bf Generowanie muzyki \\[4pt] przy pomocy głębokiego uczenia\\}
\vspace{0.8cm}
{\large \bf Music generation with deep learning\\}
\end{center}
\vspace{3cm}
\hspace{7.5cm}{Praca licencjacka}\\[-12pt]
\hspace{7.5cm}{napisana pod kierunkiem}\\[-12pt]
\hspace{7.5cm}{dr hab. Tomasza Góreckiego}
\vspace{2.2cm}
\begin{center}
\textsc{POZNAŃ 2020}
\end{center}
% Koniec strony tytułowej
\clearpage \thispagestyle{empty} \cleardoublepage
% Oświadczenie
\thispagestyle{empty}
\begin{flushright}
Poznań, dnia .....................
\end{flushright}
\vglue 2.4 cm
\begin{center}
\large \bf OŚWIADCZENIE
\end{center}
\vglue 1.2 cm
Ja, niżej podpisany Cezary Pukownik, student Wydziału Matematyki i Informatyki Uniwersytetu im. Adama Mickiewicza w Poznaniu oświadczam, że przedkładaną pracę dyplomową pt: "Generowanie muzyki przy pomocy głębokiego uczenia", napisałem samodzielnie. Oznacza to, że przy pisaniu pracy, poza niezbędnymi konsultacjami, nie korzystałem z pomocy innych osób, a w szczególności nie zlecałem opracowania rozprawy lub jej części innym osobom, ani nie odpisywałem tej rozprawy lub jej części od innych osób.
Oświadczam również, że egzemplarz pracy dyplomowej w wersji drukowanej jest całkowicie zgodny z egzemplarzem pracy dyplomowej w wersji elektronicznej.
Jednocześnie przyjmuję do wiadomości, że przypisanie sobie, w pracy dyplomowej, autorstwa istotnego fragmentu lub innych elementów cudzego utworu lub ustalenia naukowego stanowi podstawę stwierdzenia nieważności postępowania w sprawie nadania tytułu zawodowego.
\bigskip
\noindent $[TAK]^{\star}$ - wyrażam zgodę na udostępnianie mojej pracy w czytelni Archiwum UAM
\medskip
\noindent $[TAK]^{\star}$ - wyrażam zgodę na udostępnianie mojej pracy w zakresie koniecznym do ochrony mojego prawa do autorstwa lub praw osób trzecich
\vglue 1.2 cm
\noindent{\small $^{\star}$Należy wpisać TAK w przypadku wyrażenia zgody na udostępnianie pracy w czytelni Archiwum UAM, NIE w przypadku braku zgody. Niewypełnienie pola oznacza brak zgody na udostępnianie pracy.}
\vglue 2 cm
\hglue 6cm ............................................................
% Koniec oświadczenia
2020-04-06 19:23:25 +02:00
% #######################################################
% CZĘŚĆ GŁÓWNA PRACY
% #######################################################
\clearpage \thispagestyle{empty} \cleardoublepage
\tableofcontents
\chapter*{Streszczenie}
\chapter*{Abstract}
2020-04-06 19:23:25 +02:00
\chapter*{Wstęp}
2020-04-06 19:23:25 +02:00
Uczenie maszynowe w ostatnich latach mocno zyskało na popularności. Zastosowania i możliwości różnych algorytmów Mashine Learning czasami przekraczają nasze wyobrażenie o tym co komputer może zrobić. Niektóre aplikacje potrafią wręcz zaskoczyć użytkowników tym co potrafią zrobić. Wśród takich aplikacji znajdują się takie, które potrafią przewidywać następne wartości akcji giełdowych, rozpoznawać na filmie obiekty w czasie rzeczywistym, czy nawet prowadzić samochód. Algorytmy wyuczone proponują nam spersonalizowane reklamy, czy produkty na podstawie naszych upodobań. Najczęstsze zastosowania dotyczą przetwarzania obrazów lub tekstu, natomiast zastosowania w przetwarzaniu muzyki są niszowe i rzadko spotykane.
2020-04-06 19:23:25 +02:00
Celem tej pracy jest stworzenie modelu sieci neurowej, którego zadaniem bedzie generowanie krótkich multiinstrumentalnych klipów muzycznych.
2020-04-06 19:23:25 +02:00
W pierwszej częsci swojej pracy przedstawię podstawowe koncepcje związane z muzyką oraz sposobami jej reprezentacji. Następnie opiszę w jaki sposób działają sieci neuronowe, jak się uczą oraz podstawowe architektury sieci, które pomogą zrozumieć model który wykorzystałem.
2020-04-06 19:23:25 +02:00
Następnie przedstawię koncepcję działania modelu, jakie idee stały za wyborami które podjąłem w projektowaniu sieci. W szczegółowy sposób opiszę sposób ekstrakcji danych, tak aby mogły być one wykorzystane przez model. Opiszę architekturę którą wybrałem oraz przedstawię i opisze fragmenty kodu w języku python.
2020-04-06 19:23:25 +02:00
W kolejnym rozdziale skupimy się na rezultatach pracy, przedstawie zalety i wady modelu. Przeprowadze analizę jakie muzyczne koncepcje model się nauczył na podstawie danych oraz doprowadzę do ostatecznej konkluzji czy wygenerowana muzyka może być przyjemna dla odbiorcy.
\newpage
\chapter{Reprezentacja muzyki}
2020-04-07 07:40:35 +02:00
W tym rozdziale przedstawię podstawowe koncepcje muzyczne, sposoby reprezentacji muzyki oraz omówię podstawy działania protokołu MIDI.
2020-04-06 19:23:25 +02:00
\section{Podstawowe koncepcje}
\subsection{Dźwięk muzyczny}
Drgania powietrza z otoczenia człowieka są przetwarzane w mózgu i rozumiane jako dźwięki. Takie drgania nazywamy falą dźwiękową. Dzwięk muzyczny jest to fala dźwiękowa, którą wytwarza intrument muzyczny. Dzwięk muzyczny charakteryzuje się trzema podstawowymi parametrami:
\begin{itemize}
\item wysokość (ang. pitch) - jest to częstotliwość drgań wyrażona w hercach. Im większa częstotliwość tym dzźięk jest rozumiany jako wyższy,
Zakres słyszalny dla człowieka wynosi od 20Hz do 20kHz.
\item głośność (ang. velocity) - jest to amplituda drgań fali dźwiękowej. Im większa aplituda, tym dźwięk jest odczuwany jako głosniejszy,
\item długość (ang. duration) - jest to czas z jakim dźwięk wybrzmiewa, np. 2 sekundy.
\end{itemize}
% Przykład dźwięku myczynego przedstawiono na Rusynku~\ref{fig:sine}
% \begin{figure}[!htb]
% \centering
% \includegraphics[width=\linewidth]{images/sine_wave.png}
% \caption{Przykład fali dźwiękowej}
% \label{fig:sine}
% \end{figure}
\subsection{Sygnał dźwiękowy}
W rzeczywistości, utwór muzyczny jest zazwyczaj kombinacją wielu fal dźwiękowych, o różnych charaketystykach i nazwywany jest sygnałem dźwiękowym. Wizualizację sygnalu dźwiękowego przedstawiono na Rysunku~\ref{fig:waveform}
\begin{figure}[!htb]
\centering
\includegraphics[width=\linewidth]{images/waveform.png}
\caption{Przykład przebiegu fali dźwiękowej}
\label{fig:waveform}
\end{figure}
\subsection{Zapis nutowy}
Reprezentacja muzyki jako sygnału dźwiękowego przechowuje informacje o dokładnym brzmieniu danego utworu tzn. jakie drgania należy wytworzyć, aby móc odtwozyć dźwięki. Taki zapis nie informuje nas bezpośrednio jakie instrumenty zostały użyte, jakie wysokości i długości dźwięków zostały wykorzystane. Dlatego ludzkość na przestrzeni wieków opracowała abstrakcyjne objekty, które reprezentują utwór w czytelny dla człowieka sposób.
\subsubsection{Tempo}
W muzyce symbolicznej tempo informuje nas o prędkości utworu. W muzyce klasycznej stosowało się opisowy sposób dostosowywania tempa np. Allegro - Szybko lub Adagio - wolno. Jak można szybko stwierdzić są to zwroty subiektywne i nie wyznaczają tempa jednoznacznie. Obecnie wyraża się tempo w liczbie uderzeń na minutę (BPM ang. beats per minute). I tak Allegro jest to od 120 do 168 BPM a Adagio od 66 do 76 BPM. \footnote{źródlo: http://www.classicalmusiccity.com/search/article.php?vars=446/
Basic-Tempo-Markings.html 5 kwietnia 19:37
}
\subsubsection{Nuta}
Nuta jest to graficzna reprezentacja dźwięku muzycznego. Informuje nas ona o dwóch parametrach dźwięku, wysokości oraz długości dźwięku. Długość dźwięku nazywa się jej wartością. Podstawową wartością nuty jest ćwierćnuta, odpowiada ona jednemu uderzeniu. Dla przykładu w tempie 60 BPM w ciągu minuty zagramy dokładnie 60 ćwierć nut. Kolejne wartości tworzone poprzez sumowanie lub podział długości ćwierćnuty. Półnuta trwa tyle co dwie ćwierćnuty, cała nuta tyle co dwie półnuty, ósemka trwa połowę czasu ćwiercnuty, a szesnastka połowę ósemki itd.
\begin{figure}[!htb]
\centering
\includegraphics[width=\linewidth]{images/wartosc_nut.jpg}
\caption{źródlo: https://www.infomusic.pl/poradnik/46934,poradnik-teoria-muzyki-rytm 5 kwietnia 2020 12:46}
\label{fig:waveform}
\end{figure}
Tak jak pisałem wcześniej, wysokość dźwięku jest to częstotliwość drgań fali dźwiękowej wyrażona w hercach. W muzyce symbolicznej dla uproszczenia wybrane częstotliwości zostały nazwane literami alfabetu C, D, E, F, G, A, H.
Każdej literze przypisana jest częstotliwość zgodnie z Tabelą~\ref{table:dzwieki}
\begin{table}[!htb]
\centering
\begin{tabular}{||c | c||}
\hline
Dzwięk & Ćzęstotliwość \\ [0.5ex]
\hline\hline
$C_4$ & 261,6\\
\hline
$D_4$ & 293,7\\
\hline
$E_4$ & 329,6\\
\hline
$F_4$ & 349,2\\
\hline
$G_4$ & 391,9\\
\hline
$A_4$ & 440,0\\
\hline
$H_4$ & 493,9\\
\hline
\end{tabular}
\caption{Dźwięki symboliczne oraz ich częstosliwości}
\label{table:dzwieki}
\end{table}
W zapisie nutowym aby nucie nadać wysokość, umieszcza się ją w odpowiednim miejscu na pięciolonii. Przedstawione powyżej dźwięki zapisalibyśmy w taki sposób jak przedstawiono na Rysunku~\ref{fig:pieciolinia}
\begin{figure}[!htb]
\centering
\includegraphics[width=\linewidth]{images/nuty_linia.png}
\caption{źródlo: https://amplitudaschool.weebly.com/lekcja-11.html 5 kwietnia 2020 13:24}
\label{fig:pieciolinia}
\end{figure}
\subsubsection{Oktawy}
Oktawą nazywamy zestaw ośmiu nut od C do H. Podane w Tabeli~\ref{table:dzwieki} częstotliwości nut odpowiadają dźwiękom w oktawie czwartej. Dlatego w indeksie dolnym nuty widnieje liczba 4. Aby utworzyć dźwięk, np. $A_5$ należy pomnożyć częstotliwość dźwięku $A_4$ razy dwa, natomiast aby utworzyć dźwięk $A_3$, należy tę częstotliwość podzielić przez dwa.
\[ A_5 = 440Hz * 2 = 880Hz \]
\[ A_3 = 440Hz / 2 = 220Hz \]
W ten sposób możemy utworzyć nieskończenie wiele oktaw, jednak w rzeczywistości używa się nut od C0 do C8.
\subsubsection{Akord}
Gdy w jednym momencie zabrzmią dwie lub więcej różnych nut, wtedy mówimy o akordzie. Akord potrafi dodać emocje do brzmienia całego utworu.
\section{Cyfrowa reprezentacja muzyki symbolicznej}
\subsection{Standard MIDI}
Standrd MIDI (ang. Musical Instrument Digital Interface) został stworzony w 1983 aby umożliwić synchronizację i wymianę informacji między elektronicznymi urządzeniami muzycznymi takimi jak syntezatory, keyboardy czy sekwencery.
W późniejszych latach został on zaadaptowany do środowiska komputerowego jako cyfrowa reprezentacja muzyki symbolicznej.
\begin{figure}[!htb]
\centering
\begin{lstlisting}
note_on channel=0 note=48 velocity=100 time=0
note_on channel=0 note=53 velocity=100 time=0
note_on channel=0 note=60 velocity=100 time=0
note_on channel=0 note=48 velocity=0 time=220
note_on channel=0 note=48 velocity=100 time=0
note_on channel=0 note=53 velocity=0 time=0
note_on channel=0 note=55 velocity=100 time=0
note_on channel=0 note=60 velocity=0 time=0
\end{lstlisting}
\caption{Fragment protokołu MIDI}
\end{figure}
\subsubsection{Wiadomości}
Plik MIDI zawiera zestaw wiadomości przesyłanych w czasie rzeczywistym o każdej nucie w utworze. Dwie wiadomości, które są dla nas szczególnie istotne to:
\begin{itemize}
\item note\textunderscore on, który sygnalizuje aby rozpocząć grać nutę,
\item note\textunderscore off, który sygnalizuje aby zakończyć grać nutę.
\end{itemize}
\medskip
Dla przykładu wiadomość:
\begin{center}
note\textunderscore on, channel 0, note 48, velocity 100, time 0. \\
\end{center}
oznacza aby na kanele 0 zagrać dźwięk nr 48 z głośnością 100 w momencie 0 utworu. Nie informuje nas on jednak o długości trwania dźwęku. Aby zakończyć dźwęk, należy wysłac wiadomość:
\begin{center}
note\textunderscore off, channel 0, note 48, velocity 100, time 24. \\
\end{center}
Zwróćmy uwagę że aby ustalić wartość nuty, potrzebujemy odebrać dwie wiadomości. Różnica między parametrami time, informuje nas o długości nuty. W tym przypadku jest to 24.
Co oznacza ćwierćnutę.
\subsubsection{Rozdzielczość}
Czas w MIDI jest reprezentowany jako liczba naturalna i jest on zależny od ustalonego tempa utworu. Standardowa rozdzielczość pliku MIDI to 24. Oznacza to, że jedna jednostka czasu odpowiada jednej dwudziestejczwartej jednego udeżenia.
\subsubsection{Kanały}
Plik MIDI posiada 16 kanałów numerowanych od 0 do 15. Każdy kanał odpowiada intrumentowi lub ścieżce. Kanał 9 jest kanałem zarezerwowanym na intrumenty perkusyjne.
\subsubsection{Nuty}
Nuty w formacie MIDI opisane są kolejnymi cyframi naturalnymi w przedziale od 0 do 127. Odpowiada to dźwękom od $C_0$ do $C_8$. Dla przykładu nuta 69 odpowiada $A_4$, a nuta 47 odpowiada $B_2$.
Wyjątkiem są nuty z kanału dziewiątego, gdzie istnieją tylko nuty z zakresu od 35 do 81 i każda nuta odpowiada innemu elementowi perkusyjnemu np. 35 to stopa, a 37 to werbel.
\subsubsection{Głośność}
Za głośność dźwęku odpowiada parametr velocity, który jest liczbą z przedziału od 0 do 127. Im większa jest wartość tym głośniej wybrzmi dźwęk.
\subsubsection{Program}
Program w kontekscie standardu MIDI oznacza intrument który ma zagrać nuty. W standardzie GM (ang. General MIDI), jest 16 grup intrumenów a w każdej z nich znajduje się po 8 intrumentów. Są to piania, chromatyczne perkusje, organy, gitary, basy, intrumenty smyczkowe, zestawy intrumentów, intrumenty dmuchane blaszane, intrumenty dmuchane drewniane, flety, syntezatory prowadzące, syntezatory uzupełniające, efekty syntetyczne, instrumenty etniczne, perkusjonalia i efekty dzwiekowe.
\subsubsection{Ścieżka}
Ścieżka (ang. Track) grupuje nuty aby podzielić utwór muzyczny na różne intrumenty. Protokół MIDI pozwala aby grać wiele ścieżek dzwiękowych jednocześnie, wtedy mówimy o muzyce polifonicznej lub multiintrumentalnej.
\chapter{Wprowadzenie do sieci neuronowych}
W tym rozdziale opiszę podstawy działania sieci neuronowych.
\subsection{Regresja liniowa}
Podstawą wszystkich sieci neuronowych, jest regresja liniowa. W statystyce wykorzystywana aby wyjaśnić liniowe zalezności między zmiennymi.
Prosty model regresji liniowej dla jednej zmiennej można opisać wzorem.
\[\hat{y} = ax+b\]
2020-04-06 19:23:25 +02:00
gdzie,
\begin{itemize}
\item $\hat{y}$ jest to estymacja zmiennej objaśnianej,
\item $x$ jest to zmienna objaśniająca,
\item $a$ jest parametrem modelu,
\item $b$ jest wyrazem wolnym.
\end{itemize}
\medskip
Zadaniem jest znalezienie takiego parametru $a\in \mathbb{R}$ oraz wyrazu wolnego $b \in \mathbb{R}$, aby dla znanych wartości $x \in \mathbb{R}$ estymacja zmiennej objasnianej $\hat{y} \in \mathbb{R}$ najlepiej opisywała zmienną objasnaną $y \in \mathbb{R}$
\medskip
\begin{figure}[!htb]
\centering
\includegraphics[width=\linewidth]{images/linear_reg.png}
\caption{Regresja liniowa jednej zmiennej}
\label{fig:linreg}
\end{figure}
Wartość zmiennej objaśnianej $y$ można również opisać za pomocą wielu zmiennych objaśniająych. Wtedy dla zmiennych objaśniającej $x_1, x_2, ... , x_n \in \mathbb{R}$ szukamy parametrów $\theta_1, \theta_2, ... ,\theta_n \in \mathbb{R}$. Otrzymany w ten sposób model nazywany jest również hipotezą i oznaczamy go $h(x)$.
\[h(x) = b + \theta_1x_2 + \theta_2x_2 + ... + \theta_nx_n = b + \sum_{i=1}^{n} \theta_ix_i\]
\subsection{Uczenie modelu}
\subsubsection{Funkcja kosztu}
Celem uczenia modelu jest znalecienie ogólnych parametrów, aby model dla każdej pary $x, y$ zwracał wartości $\hat{y}$ najlepiej opisujące całe zjawisko według pewnego kryterium. W ten sposób jesteśmy wstanie znaleźć przybliżenie funkcji $h(x)$.
2020-04-07 07:40:35 +02:00
W tym celu używa się funcji $J_\theta(h)$, która zwraca wrtość błędu między wartościami $h(x)$ oraz $y$ dla wszystkich obserwacji. Taka funckcja nazywana jest funkcją kosztu.
2020-04-06 19:23:25 +02:00
Dla przykładu regresji liniowej, funkcją kosztu może być odchylenie średnio kwadratowe. Wtedy funkcja kosztu przyjmuje postać:
\[ J_\theta(h) = \frac{1}{m}\sum_{i=1}^{m}(y_i-h(x_i))^2 \]
gdzie $m \in \mathbb{N}$ jest liczbą obserwacji.
Przy zdefiniowanej funcji kosztu, proces uczenia sprowadza się do znalezienia takich parametrów funcji $h(x)$ aby funkcja kosztu była najmniejsza. Jest to problem optymalizacyjny sprowadzający się do znalezienia globalnego minimum funcji.
\subsubsection{Metoda gradientu prostego}
Jednym z algorytmów stosowanych do rozwiązania powyższego problemu optymalizacji jest metoda gradientu prostego (ang. gradient descent).
\begin{figure}[!htb]
\centering
\def\layersep{2.5cm}
\begin{tikzpicture}[shorten >=1pt,->,draw=black!50, node distance=\layersep]
\tikzstyle{every pin edge}=[<-,shorten <=1pt]
\tikzstyle{neuron}=[circle,fill=black!25,minimum size=17pt,inner sep=0pt]
\tikzstyle{input neuron}=[neuron, fill=black!50];
\tikzstyle{output neuron}=[neuron, fill=black!50];
\tikzstyle{hidden neuron}=[neuron, fill=black!50];
\tikzstyle{annot} = [text width=4em, text centered]
% Draw the input layer nodes
\foreach \name / \y in {1,...,4}
% This is the same as writing \foreach \name / \y in {1/1,2/2,3/3,4/4}
\node[input neuron, pin=left:Input \#\y] (I-\name) at (0,-\y) {};
% Draw the hidden layer nodes
\foreach \name / \y in {1,...,5}
\path[yshift=0.5cm]
node[hidden neuron] (H-\name) at (\layersep,-\y cm) {};
% Draw the output layer node
\node[output neuron,pin={[pin edge={->}]right:Output}, right of=H-3] (O) {};
% Connect every node in the input layer with every node in the
% hidden layer.
\foreach \source in {1,...,4}
\foreach \dest in {1,...,5}
\path (I-\source) edge (H-\dest);
% Connect every node in the hidden layer with the output layer
\foreach \source in {1,...,5}
\path (H-\source) edge (O);
% Annotate the layers
\node[annot,above of=H-1, node distance=1cm] (hl) {Hidden layer};
\node[annot,left of=hl] {Input layer};
\node[annot,right of=hl] {Output layer};
\end{tikzpicture}
\caption{źródlo: Przykład sieci neuronowej}
\label{fig:neuralnet1}
\end{figure}
\chapter{Projekt}
W tym rozdzialę opiszę w jaki sposób zbudowałem swój własny geneator muzyki, jak przechodził procesz uczenia, jakie próbki udało mi się wygenrować. Opis kodu który napisałem.
2020-04-06 19:23:25 +02:00
\chapter{Podsumowanie}
Ostateczne wnioski, czy muzyka generowana komputerowa da się lubić? Czy to pozytywnie wpłynie na przemysł muzyczny? Tak i nie. Może złużyć jako inspiracja dla muzyków, proces wspierający. Z drugiej strony może obnizy koszty produkowania muzyki pop, która i tak jest już bardzo powtarzalna. Czy sieci neuronowe nauczą się produkować Hity?
\begin{thebibliography}{99}
\bibitem{} Briot, J.P., Hadjeres, G., Pachet, F.D. (2019): {\em Deep Learning Techniques for Music Generation - A Survey. arXiv:1709.01620v3}
\bibitem{} Goodfellow, I., Bengio, Y., Courville, A. (2016): {\em Deep Learning. MIT Press.}
\bibitem{} Zocca, V., Spacagna, G., Slater, D., Roelants, P. (2018): {\em Deep Learning. Uczenie głębokie z językiem Python. Helion.}
\end{thebibliography}
\printindex
\end{document}