====== Calculul cu o Singură Variabilă ======
În , am văzut elementele de bază ale calculului diferențial. Această secțiune face o scufundare mai adâncă în fundamentele calculului și cum îl putem înțelege și aplica în contextul învățării automate.
===== Calcul Diferențial =====
Calculul diferențial este fundamental studiul modului în care funcțiile se comportă la schimbări mici. Pentru a vedea de ce acest lucru este atât de esențial pentru învățarea profundă, să considerăm un exemplu.
Să presupunem că avem o rețea neuronală profundă unde ponderile sunt, pentru comoditate, concatenate într-un singur vector $\mathbf{w} = (w_1, \ldots, w_n)$. Dat un set de date de antrenare, considerăm pierderea rețelei noastre neuronale pe acest set de date, pe care o vom scrie ca $\mathcal{L}(\mathbf{w})$.
Această funcție este extraordinar de complexă, codificând performanța tuturor modelelor posibile ale arhitecturii date pe acest set de date, deci este aproape imposibil de spus ce set de ponderi $\mathbf{w}$ va minimiza pierderea. Astfel, în practică, începem adesea prin inițializarea ponderilor noastre //aleatoriu//, și apoi luăm iterativ pași mici în direcția care face ca pierderea să scadă cât mai rapid posibil.
Întrebarea devine apoi ceva ce la suprafață nu este mai ușor: cum găsim direcția care face ca ponderile să scadă cât mai repede posibil? Pentru a săpa în asta, să examinăm mai întâi cazul cu o singură pondere: $L(\mathbf{w}) = L(x)$ pentru o singură valoare reală $x$.
Să luăm $x$ și să încercăm să înțelegem ce se întâmplă când îl schimbăm cu o cantitate mică la $x + \epsilon$. Dacă doriți să fiți concreți, gândiți-vă la un număr precum $\epsilon = 0.0000001$. Pentru a ne ajuta să vizualizăm ce se întâmplă, să graficăm o funcție exemplu, $f(x) = \sin(x^x)$, peste $[0, 3]$.
#@tab pytorch
%matplotlib inline
from d2l import torch as d2l
from IPython import display
import torch
torch.pi = torch.acos(torch.zeros(1)).item() * 2 # Define pi in torch
# Plot a function in a normal range
x_big = torch.arange(0.01, 3.01, 0.01)
ys = torch.sin(x_big**x_big)
d2l.plot(x_big, ys, 'x', 'f(x)')
La această scară largă, comportamentul funcției nu este simplu. Totuși, dacă reducem intervalul la ceva mai mic precum $[1.75,2.25]$, vedem că graficul devine mult mai simplu.
#@tab pytorch
# Plot a the same function in a tiny range
x_med = torch.arange(1.75, 2.25, 0.001)
ys = torch.sin(x_med**x_med)
d2l.plot(x_med, ys, 'x', 'f(x)')
Ducând asta la o extremă, dacă ne apropiem într-un segment mic, comportamentul devine mult mai simplu: este doar o linie dreaptă.
#@tab pytorch
# Plot a the same function in a tiny range
x_small = torch.arange(2.0, 2.01, 0.0001)
ys = torch.sin(x_small**x_small)
d2l.plot(x_small, ys, 'x', 'f(x)')
Aceasta este observația cheie a calculului cu o singură variabilă: comportamentul funcțiilor familiare poate fi modelat printr-o linie într-un interval suficient de mic. Asta înseamnă că pentru majoritatea funcțiilor, este rezonabil să ne așteptăm ca pe măsură ce schimbăm valoarea $x$ a funcției cu puțin, ieșirea $f(x)$ va fi de asemenea schimbată cu puțin. Singura întrebare la care trebuie să răspundem este, „Cât de mare este schimbarea în ieșire comparativ cu schimbarea în intrare? Este jumătate de mare? De două ori mai mare?”
Astfel, putem considera raportul schimbării în ieșirea unei funcții pentru o mică schimbare în intrarea funcției. Putem scrie asta formal ca
$$
\frac{L(x+\epsilon) - L(x)}{(x+\epsilon) - x} = \frac{L(x+\epsilon) - L(x)}{\epsilon}.
$$
Acest lucru este deja suficient pentru a începe să ne jucăm în cod. De exemplu, să presupunem că știm că $L(x) = x^{2} + 1701(x-4)^3$, atunci putem vedea cât de mare este această valoare la punctul $x = 4$ după cum urmează.
#@tab all
# Define our function
def L(x):
return x**2 + 1701*(x-4)**3
# Print the difference divided by epsilon for several epsilon
for epsilon in [0.1, 0.001, 0.0001, 0.00001]:
print(f'epsilon = {epsilon:.5f} -> {(L(4+epsilon) - L(4)) / epsilon:.5f}')
Acum, dacă suntem observatori, vom observa că ieșirea acestui număr este suspect de aproape de $8$. Într-adevăr, dacă descreștem $\epsilon$, vom vedea că valoarea devine progresiv mai aproape de $8$. Astfel putem concluziona, corect, că valoarea pe care o căutăm (gradul în care o schimbare în intrare schimbă ieșirea) ar trebui să fie $8$ la punctul $x=4$. Modul în care un matematician codifică acest fapt este
$$
\lim_{\epsilon \rightarrow 0}\frac{L(4+\epsilon) - L(4)}{\epsilon} = 8.
$$
Ca o mică digresiune istorică: în primele câteva decenii de cercetare a rețelelor neuronale, oamenii de știință foloseau acest algoritm (//metoda diferențelor finite//) pentru a evalua cum se schimba o funcție de pierdere sub o mică perturbație: doar schimba ponderile și vezi cum se schimba pierderea. Acest lucru este ineficient computațional, necesitând două evaluări ale funcției de pierdere pentru a vedea cum o singură schimbare a unei variabile a influențat pierderea. Dacă am încerca să facem asta cu chiar și câteva mii de parametri, ar necesita câteva mii de evaluări ale rețelei pe întregul set de date! Nu a fost rezolvată până în 1986 când //algoritmul backpropagation// introdus în ((Rumelhart.Hinton.Williams.ea.1988)) a oferit o modalitate de a calcula cum //orice// schimbare a ponderilor împreună ar schimba pierderea în același timp de calcul ca o singură predicție a rețelei pe setul de date.
Înapoi la exemplul nostru, această valoare $8$ este diferită pentru diferite valori ale lui $x$, deci are sens să o definim ca o funcție de $x$. Mai formal, această rată de schimbare dependentă de valoare este referită ca //derivata// care este scrisă ca
$$\frac{df}{dx}(x) = \lim_{\epsilon \rightarrow 0}\frac{f(x+\epsilon) - f(x)}{\epsilon}.$$
Diferite texte vor folosi notații diferite pentru derivată. De exemplu, toate notațiile de mai jos indică același lucru:
$$
\frac{df}{dx} = \frac{d}{dx}f = f' = \nabla_xf = D_xf = f_x.
$$
Majoritatea autorilor vor alege o singură notație și vor rămâne cu ea, totuși chiar și asta nu este garantat. Este cel mai bine să fiți familiari cu toate acestea. Vom folosi notația $\frac{df}{dx}$ pe parcursul acestui text, cu excepția cazului în care vrem să luăm derivata unei expresii complexe, caz în care vom folosi $\frac{d}{dx}f$ pentru a scrie expresii precum $$
\frac{d}{dx}\left[x^4+\cos\left(\frac{x^2+1}{2x-1}\right)\right].
$$
De multe ori, este intuitiv util să desfacem definiția derivatei :eqref:''%%eq_der_def%%'' din nou pentru a vedea cum se schimbă o funcție când facem o schimbare mică a lui $x$:
$$\begin{aligned} \frac{df}{dx}(x) = \lim_{\epsilon \rightarrow 0}\frac{f(x+\epsilon) - f(x)}{\epsilon} & \implies \frac{df}{dx}(x) \approx \frac{f(x+\epsilon) - f(x)}{\epsilon} \\ & \implies \epsilon \frac{df}{dx}(x) \approx f(x+\epsilon) - f(x) \\ & \implies f(x+\epsilon) \approx f(x) + \epsilon \frac{df}{dx}(x). \end{aligned}$$
Ultima ecuație merită menționată explicit. Ne spune că dacă luați orice funcție și schimbați intrarea cu o cantitate mică, ieșirea se va schimba cu acea cantitate mică scalată de derivată.
În acest fel, putem înțelege derivata ca factorul de scalare care ne spune cât de mare schimbare obținem în ieșire de la o schimbare în intrare.
===== Reguli ale Calculului =====
Ne întoarcem acum la sarcina de a înțelege cum să calculăm derivata unei funcții explicite. Un tratament formal complet al calculului ar deriva totul de la primele principii. Nu ne vom răsfăța în această tentație aici, ci mai degrabă vom oferi o înțelegere a regulilor comune întâlnite.
==== Derivate Comune ====
Așa cum s-a văzut în , când calculăm derivate putem adesea folosi o serie de reguli pentru a reduce calculul la câteva funcții de bază. Le repetăm aici pentru ușurința referinței.
* **Derivata constantelor.** $\frac{d}{dx}c = 0$.
* **Derivata funcțiilor liniare.** $\frac{d}{dx}(ax) = a$.
* **Regula puterii.** $\frac{d}{dx}x^n = nx^{n-1}$.
* **Derivata exponențialelor.** $\frac{d}{dx}e^x = e^x$.
* **Derivata logaritmului.** $\frac{d}{dx}\log(x) = \frac{1}{x}$.
==== Reguli de Derivare ====
Dacă fiecare derivată ar trebui să fie calculată separat și stocată într-un tabel, calculul diferențial ar fi aproape imposibil. Este un dar al matematicii că putem generaliza derivatele de mai sus și calcula derivate mai complexe precum găsirea derivatei lui $f(x) = \log\left(1+(x-1)^{10}\right)$. Așa cum a fost menționat în , cheia pentru a face acest lucru este codificarea a ceea ce se întâmplă când luăm funcții și le combinăm în diverse moduri, cel mai important: sume, produse și compuneri.
* **Regula sumei.** $\frac{d}{dx}\left(g(x) + h(x)\right) = \frac{dg}{dx}(x) + \frac{dh}{dx}(x)$.
* **Regula produsului.** $\frac{d}{dx}\left(g(x)\cdot h(x)\right) = g(x)\frac{dh}{dx}(x) + \frac{dg}{dx}(x)h(x)$.
* **Regula lanțului.** $\frac{d}{dx}g(h(x)) = \frac{dg}{dh}(h(x))\cdot \frac{dh}{dx}(x)$.
Să vedem cum putem folosi :eqref:''%%eq_small_change%%'' pentru a înțelege aceste reguli. Pentru regula sumei, considerați următorul lanț de raționament:
$$
\begin{aligned}
f(x+\epsilon) & = g(x+\epsilon) + h(x+\epsilon) \\
& \approx g(x) + \epsilon \frac{dg}{dx}(x) + h(x) + \epsilon \frac{dh}{dx}(x) \\
& = g(x) + h(x) + \epsilon\left(\frac{dg}{dx}(x) + \frac{dh}{dx}(x)\right) \\
& = f(x) + \epsilon\left(\frac{dg}{dx}(x) + \frac{dh}{dx}(x)\right).
\end{aligned}
$$
Comparând acest rezultat cu faptul că $f(x+\epsilon) \approx f(x) + \epsilon \frac{df}{dx}(x)$, vedem că $\frac{df}{dx}(x) = \frac{dg}{dx}(x) + \frac{dh}{dx}(x)$ așa cum s-a dorit. Intuiția aici este: când schimbăm intrarea $x$, $g$ și $h$ contribuie împreună la schimbarea ieșirii cu $\frac{dg}{dx}(x)$ și $\frac{dh}{dx}(x)$.
Produsul este mai subtil, și va necesita o nouă observație despre cum să lucrăm cu aceste expresii. Vom începe ca înainte folosind :eqref:''%%eq_small_change%%'':
$$
\begin{aligned}
f(x+\epsilon) & = g(x+\epsilon)\cdot h(x+\epsilon) \\
& \approx \left(g(x) + \epsilon \frac{dg}{dx}(x)\right)\cdot\left(h(x) + \epsilon \frac{dh}{dx}(x)\right) \\
& = g(x)\cdot h(x) + \epsilon\left(g(x)\frac{dh}{dx}(x) + \frac{dg}{dx}(x)h(x)\right) + \epsilon^2\frac{dg}{dx}(x)\frac{dh}{dx}(x) \\
& = f(x) + \epsilon\left(g(x)\frac{dh}{dx}(x) + \frac{dg}{dx}(x)h(x)\right) + \epsilon^2\frac{dg}{dx}(x)\frac{dh}{dx}(x). \\
\end{aligned}
$$
Aceasta seamănă cu calculul făcut mai sus, și într-adevăr vedem răspunsul nostru ($\frac{df}{dx}(x) = g(x)\frac{dh}{dx}(x) + \frac{dg}{dx}(x)h(x)$) stând lângă $\epsilon$, dar există problema acelui termen de mărime $\epsilon^{2}$. Ne vom referi la acesta ca un //termen de ordin superior//, deoarece puterea lui $\epsilon^2$ este mai mare decât puterea lui $\epsilon^1$. Vom vedea într-o secțiune ulterioară că uneori vom dori să ținem evidența acestora, totuși pentru moment observați că dacă $\epsilon = 0.0000001$, atunci $\epsilon^{2}= 0.0000000000001$, care este vast mai mic. Pe măsură ce trimitem $\epsilon \rightarrow 0$, putem ignora în siguranță termenii de ordin superior. Ca o convenție generală în această anexă, vom folosi “$\approx$” pentru a denota că cei doi termeni sunt egali până la termeni de ordin superior. Totuși, dacă dorim să fim mai formali putem examina câtul diferenței
$$
\frac{f(x+\epsilon) - f(x)}{\epsilon} = g(x)\frac{dh}{dx}(x) + \frac{dg}{dx}(x)h(x) + \epsilon \frac{dg}{dx}(x)\frac{dh}{dx}(x),
$$
și vedem că pe măsură ce trimitem $\epsilon \rightarrow 0$, termenul din dreapta merge la zero de asemenea.
În final, cu regula lanțului, putem progresa din nou ca înainte folosind :eqref:''%%eq_small_change%%'' și vedem că
$$
\begin{aligned}
f(x+\epsilon) & = g(h(x+\epsilon)) \\
& \approx g\left(h(x) + \epsilon \frac{dh}{dx}(x)\right) \\
& \approx g(h(x)) + \epsilon \frac{dh}{dx}(x) \frac{dg}{dh}(h(x))\\
& = f(x) + \epsilon \frac{dg}{dh}(h(x))\frac{dh}{dx}(x),
\end{aligned}
$$
unde în a doua linie vedem funcția $g$ ca având intrarea sa ($h(x)$) schimbată de cantitatea mică $\epsilon \frac{dh}{dx}(x)$.
Aceste reguli ne oferă un set flexibil de instrumente pentru a calcula esențial orice expresie dorită. De exemplu,
$$
\begin{aligned}
\frac{d}{dx}\left[\log\left(1+(x-1)^{10}\right)\right] & = \left(1+(x-1)^{10}\right)^{-1}\frac{d}{dx}\left[1+(x-1)^{10}\right]\\
& = \left(1+(x-1)^{10}\right)^{-1}\left(\frac{d}{dx}[1] + \frac{d}{dx}[(x-1)^{10}]\right) \\
& = \left(1+(x-1)^{10}\right)^{-1}\left(0 + 10(x-1)^9\frac{d}{dx}[x-1]\right) \\
& = 10\left(1+(x-1)^{10}\right)^{-1}(x-1)^9 \\
& = \frac{10(x-1)^9}{1+(x-1)^{10}}.
\end{aligned}
$$
Unde fiecare linie a folosit următoarele reguli:
- Regula lanțului și derivata logaritmului.
- Regula sumei.
- Derivata constantelor, regula lanțului, și regula puterii.
- Regula sumei, derivata funcțiilor liniare, derivata constantelor.
Două lucruri ar trebui să fie clare după ce facem acest exemplu:
- Orice funcție pe care o putem scrie folosind sume, produse, constante, puteri, exponențiale, și logaritmi poate avea derivata sa calculată mecanic urmând aceste reguli.
- A avea un om care să urmeze aceste reguli poate fi plictisitor și predispus la erori!
Din fericire, aceste două fapte împreună sugerează o cale înainte: acesta este un candidat perfect pentru mecanizare! Într-adevăr backpropagation, pe care îl vom revizita mai târziu în această secțiune, este exact asta.
===== Aproximarea Liniară =====
Când lucrăm cu derivate, este adesea util să interpretăm geometric aproximarea folosită mai sus. În particular, notați că ecuația
$$
f(x+\epsilon) \approx f(x) + \epsilon \frac{df}{dx}(x),
$$
aproximează valoarea lui $f$ printr-o linie care trece prin punctul $(x, f(x))$ și are panta $\frac{df}{dx}(x)$. În acest fel spunem că derivata oferă o aproximare liniară funcției $f$, așa cum este ilustrat mai jos:
#@tab pytorch
# Compute sin
xs = torch.arange(-torch.pi, torch.pi, 0.01)
plots = [torch.sin(xs)]
# Compute some linear approximations. Use d(sin(x))/dx = cos(x)
for x0 in [-1.5, 0.0, 2.0]:
plots.append(torch.sin(torch.tensor(x0)) + (xs - x0) *
torch.cos(torch.tensor(x0)))
d2l.plot(xs, plots, 'x', 'f(x)', ylim=[-1.5, 1.5])
===== Derivate de Ordin Superior =====
Să facem acum ceva ce la suprafață poate părea ciudat. Luați o funcție $f$ și calculați derivata $\frac{df}{dx}$. Aceasta ne oferă rata de schimbare a lui $f$ în orice punct.
Totuși, derivata, $\frac{df}{dx}$, poate fi văzută ca o funcție ea însăși, deci nimic nu ne oprește să calculăm derivata lui $\frac{df}{dx}$ pentru a obține $\frac{d^2f}{dx^2} = \frac{df}{dx}\left(\frac{df}{dx}\right)$. Vom numi aceasta a doua derivată a lui $f$. Această funcție este rata de schimbare a ratei de schimbare a lui $f$, sau cu alte cuvinte, cum se schimbă rata de schimbare. Putem aplica derivata de orice număr de ori pentru a obține ceea ce se numește a $n$-a derivată. Pentru a păstra notația curată, vom denota a $n$-a derivată ca
$$
f^{(n)}(x) = \frac{d^{n}f}{dx^{n}} = \left(\frac{d}{dx}\right)^{n} f.
$$
Să încercăm să înțelegem //de ce// aceasta este o noțiune utilă. Mai jos, vizualizăm $f^{(2)}(x)$, $f^{(1)}(x)$, și $f(x)$.
Mai întâi, considerați cazul în care a doua derivată $f^{(2)}(x)$ este o constantă pozitivă. Asta înseamnă că panta primei derivate este pozitivă. Ca rezultat, prima derivată $f^{(1)}(x)$ poate începe negativă, devine zero într-un punct, și apoi devine pozitivă la sfârșit. Asta ne spune panta funcției noastre originale $f$ și prin urmare, funcția $f$ însăși scade, se aplatizează, apoi crește. Cu alte cuvinte, funcția $f$ se curbează în sus, și are un singur minim așa cum este arătat în .
{{:wiki:img:posSecDer.svg|Dacă presupunem că a doua derivată este o constantă pozitivă, atunci prima derivată este crescătoare, ceea ce implică faptul că funcția însăși are un minim.}}
În al doilea rând, dacă a doua derivată este o constantă negativă, asta înseamnă că prima derivată este descrescătoare. Asta implică faptul că prima derivată poate începe pozitivă, devine zero într-un punct, și apoi devine negativă. Prin urmare, funcția $f$ însăși crește, se aplatizează, apoi scade. Cu alte cuvinte, funcția $f$ se curbează în jos, și are un singur maxim așa cum este arătat în .
{{:wiki:img:negSecDer.svg|Dacă presupunem că a doua derivată este o constantă negativă, atunci prima derivată este descrescătoare, ceea ce implică faptul că funcția însăși are un maxim.}}
În al treilea rând, dacă a doua derivată este întotdeauna zero, atunci prima derivată nu se va schimba niciodată—este constantă! Asta înseamnă că $f$ crește (sau scade) la o rată fixă, și $f$ este ea însăși o linie dreaptă așa cum este arătat în .
{{:wiki:img:zeroSecDer.svg|Dacă presupunem că a doua derivată este zero, atunci prima derivată este constantă, ceea ce implică faptul că funcția însăși este o linie dreaptă.}}
Pentru a rezuma, a doua derivată poate fi interpretată ca descriind modul în care funcția $f$ se curbează. O a doua derivată pozitivă duce la o curbă în sus, în timp ce o a doua derivată negativă înseamnă că $f$ se curbează în jos, și o a doua derivată zero înseamnă că $f$ nu se curbează deloc.
Să ducem asta cu un pas mai departe. Considerați funcția $g(x) = ax^{2}+ bx + c$. Putem calcula atunci că
$$
\begin{aligned}
\frac{dg}{dx}(x) & = 2ax + b \\
\frac{d^2g}{dx^2}(x) & = 2a.
\end{aligned}
$$
Dacă avem o funcție originală $f(x)$ în minte, putem calcula primele două derivate și găsi valorile pentru $a, b$, și $c$ care le fac să se potrivească cu acest calcul. Similar secțiunii anterioare unde am văzut că prima derivată a dat cea mai bună aproximare cu o linie dreaptă, această construcție oferă cea mai bună aproximare printr-o pătratică. Să vizualizăm asta pentru $f(x) = \sin(x)$.
#@tab pytorch
# Compute sin
xs = torch.arange(-torch.pi, torch.pi, 0.01)
plots = [torch.sin(xs)]
# Compute some quadratic approximations. Use d(sin(x)) / dx = cos(x)
for x0 in [-1.5, 0.0, 2.0]:
plots.append(torch.sin(torch.tensor(x0)) + (xs - x0) *
torch.cos(torch.tensor(x0)) - (xs - x0)**2 *
torch.sin(torch.tensor(x0)) / 2)
d2l.plot(xs, plots, 'x', 'f(x)', ylim=[-1.5, 1.5])
Vom extinde această idee la ideea de //serie Taylor// în secțiunea următoare.
===== Serii Taylor =====
//Seria Taylor// oferă o metodă de a aproxima funcția $f(x)$ dacă ne sunt date valorile pentru primele $n$ derivate la un punct $x_0$, i.e., $\left\{ f(x_0), f^{(1)}(x_0), f^{(2)}(x_0), \ldots, f^{(n)}(x_0) \right\}$. Ideea va fi de a găsi un polinom de grad $n$ care se potrivește cu toate derivatele date la $x_0$.
Am văzut cazul lui $n=2$ în secțiunea anterioară și puțină algebră arată că acesta este
$$
f(x) \approx \frac{1}{2}\frac{d^2f}{dx^2}(x_0)(x-x_0)^{2}+ \frac{df}{dx}(x_0)(x-x_0) + f(x_0).
$$
Așa cum putem vedea mai sus, numitorul de $2$ este acolo pentru a anula $2$-ul pe care îl obținem când luăm două derivate ale lui $x^2$, în timp ce ceilalți termeni sunt toți zero. Aceeași logică se aplică pentru prima derivată și valoarea însăși.
Dacă împingem logica mai departe la $n=3$, vom concluziona că
$$
f(x) \approx \frac{\frac{d^3f}{dx^3}(x_0)}{6}(x-x_0)^3 + \frac{\frac{d^2f}{dx^2}(x_0)}{2}(x-x_0)^{2}+ \frac{df}{dx}(x_0)(x-x_0) + f(x_0).
$$
unde $6 = 3 \times 2 = 3!$ provine de la constanta pe care o obținem în față dacă luăm trei derivate ale lui $x^3$.
Mai mult, putem obține un polinom de grad $n$ prin
$$
P_n(x) = \sum_{i = 0}^{n} \frac{f^{(i)}(x_0)}{i!}(x-x_0)^{i}.
$$
unde notația
$$
f^{(n)}(x) = \frac{d^{n}f}{dx^{n}} = \left(\frac{d}{dx}\right)^{n} f.
$$
Într-adevăr, $P_n(x)$ poate fi văzut ca cea mai bună aproximare polinomială de gradul $n$ a funcției noastre $f(x)$.
Deși nu ne vom scufunda complet în eroarea aproximărilor de mai sus, merită menționată limita infinită. În acest caz, pentru funcții bine comportate (cunoscute ca funcții analitice reale) precum $\cos(x)$ sau $e^{x}$, putem scrie numărul infinit de termeni și aproxima exact aceeași funcție
$$
f(x) = \sum_{n = 0}^\infty \frac{f^{(n)}(x_0)}{n!}(x-x_0)^{n}.
$$
Luați $f(x) = e^{x}$ ca un exemplu. Deoarece $e^{x}$ este propria sa derivată, știm că $f^{(n)}(x) = e^{x}$. Prin urmare, $e^{x}$ poate fi reconstruit luând seria Taylor la $x_0 = 0$, i.e.,
$$
e^{x} = \sum_{n = 0}^\infty \frac{x^{n}}{n!} = 1 + x + \frac{x^2}{2} + \frac{x^3}{6} + \cdots.
$$
Să vedem cum funcționează asta în cod și să observăm cum creșterea gradului aproximării Taylor ne aduce mai aproape de funcția dorită $e^x$.
#@tab pytorch
# Compute the exponential function
xs = torch.arange(0, 3, 0.01)
ys = torch.exp(xs)
# Compute a few Taylor series approximations
P1 = 1 + xs
P2 = 1 + xs + xs**2 / 2
P5 = 1 + xs + xs**2 / 2 + xs**3 / 6 + xs**4 / 24 + xs**5 / 120
d2l.plot(xs, [ys, P1, P2, P5], 'x', 'f(x)', legend=[
"Exponential", "Degree 1 Taylor Series", "Degree 2 Taylor Series",
"Degree 5 Taylor Series"])
Seriile Taylor au două aplicații primare:
- //Aplicații teoretice//: Adesea când încercăm să înțelegem o funcție prea complexă, folosirea seriilor Taylor ne permite să o transformăm într-un polinom cu care putem lucra direct.
- //Aplicații numerice//: Unele funcții precum $e^{x}$ sau $\cos(x)$ sunt dificile pentru mașini de calculat. Ele pot stoca tabele de valori la o precizie fixă (și acest lucru este adesea făcut), dar tot lasă întrebări deschise precum “Care este a 1000-a cifră a lui $\cos(1)$?” Seriile Taylor sunt adesea utile pentru a răspunde la astfel de întrebări.
===== Rezumat =====
* Derivatele pot fi folosite pentru a exprima cum se schimbă funcțiile când schimbăm intrarea cu o cantitate mică.
* Derivatele elementare pot fi combinate folosind reguli de derivare pentru a crea derivate arbitrar de complexe.
* Derivatele pot fi iterate pentru a obține derivate de ordinul doi sau mai mare. Fiecare creștere în ordin oferă informații mai detaliate despre comportamentul funcției.
* Folosind informația din derivatele unui singur exemplu de date, putem aproxima funcții bine comportate prin polinoame obținute din seria Taylor.
===== Exerciții =====
- Care este derivata lui $x^3-4x+1$?
- Care este derivata lui $\log(\frac{1}{x})$?
- Adevărat sau Fals: Dacă $f'(x) = 0$ atunci $f$ are un maxim sau minim la $x$?
- Unde este minimul lui $f(x) = x\log(x)$ pentru $x\ge0$ (unde presupunem că $f$ ia valoarea limită de $0$ la $f(0)$)?
[[https://discuss.d2l.ai/t/1088|Discuții]]