2.4 Matematinė analizė

Ilgą laiką apskritimo ploto apskaičiavimas išliko paslaptimi. Tada senovės Graikijoje matematikas Archimedas sugalvojo gudrią idėją – į apskritimo vidų įbrėžti daugiakampių seką su vis didesniu viršūnių skaičiumi (2.4.1 pav.). Daugiakampiui su nn viršūnių gauname nn trikampių. Kiekvieno trikampio aukštis artėja prie spindulio rr, kai apskritimą skaidome vis smulkiau. Tuo pat metu jo pagrindas artėja prie 2πr/n2 \pi r/n, nes lanko ir sekantės santykis artėja prie 1, kai viršūnių skaičius didelis. Taigi daugiakampio plotas artėja prie n⋅r⋅12(2πr/n)=πr2n \cdot r \cdot \frac{1}{2} (2 \pi r/n) = \pi r^2.

Apskritimo ploto radimas kaip ribinė procedūra.

2.4.1 pav. Apskritimo ploto radimas kaip ribinė procedūra.

Ši ribinė procedūra yra tiek diferencialinio, tiek integralinio skaičiavimo šaknis. Pirmasis gali pasakyti, kaip padidinti arba sumažinti funkcijos reikšmę keičiant jos argumentus. Tai praverčia sprendžiant optimizavimo uždavinius, su kuriais susiduriame giliajame mokyme, kai pakartotinai atnaujiname savo parametrus, kad sumažintume nuostolių funkciją. Optimizavimas nagrinėja, kaip pritaikyti modelius apmokymo duomenims, o matematinė analizė yra svarbiausia jo būtina sąlyga. Tačiau nepamirškite, kad mūsų galutinis tikslas yra gerai veikti su anksčiau nematytais duomenimis. Ši problema vadinama generalizacija ir bus pagrindinis kitų skyrių dėmesio objektas.

%matplotlib inline
from d2l import mxnet as d2l
from matplotlib_inline import backend_inline
from mxnet import np, npx
npx.set_np()
%matplotlib inline
from d2l import torch as d2l
from matplotlib_inline import backend_inline
import numpy as np
%matplotlib inline
from d2l import tensorflow as d2l
from matplotlib_inline import backend_inline
import numpy as np
%matplotlib inline
from d2l import jax as d2l
from matplotlib_inline import backend_inline
import numpy as np

2.4.1 Išvestinės ir diferencijavimas

Paprasčiau tariant, išvestinė yra funkcijos kitimo greitis atsižvelgiant į jos argumentų pokyčius. Išvestinės gali pasakyti, kaip sparčiai nuostolių funkcija didėtų ar mažėtų, jei kiekvieną parametrą padidintume arba sumažintume be galo mažu dydžiu. Formaliai funkcijoms f:R→Rf: \mathbb{R} \rightarrow \mathbb{R}, atvaizduojančioms skaliarus į skaliarus, ff išvestinė taške xx apibrėžiama kaip

(**

f′(x)=lim⁡h→0f(x+h)−f(x)h.f'(x) = \lim_{h \rightarrow 0} \frac{f(x+h) - f(x)}{h}.

**)

Šis narys dešinėje pusėje vadinamas riba ir parodo, kas nutinka išraiškos reikšmei, kai nurodytas kintamasis artėja prie tam tikros reikšmės. Ši riba parodo, prie ko konverguoja pokyčio hh ir funkcijos reikšmės pokyčio f(x+h)−f(x)f(x + h) - f(x) santykis, kai jo dydį mažiname iki nulio.

Kai f′(x)f'(x) egzistuoja, sakoma, kad ff yra diferencijuojama taške xx; ir kai f′(x)f'(x) egzistuoja visiems xx tam tikroje aibėje, pvz., intervale [a,b][a,b], sakome, kad ff yra diferencijuojama šioje aibėje. Ne visos funkcijos yra diferencijuojamos, įskaitant daugelį tų, kurias norime optimizuoti, pvz., tikslumą ir plotą po imtuvo darbo charakteristikos kreive (angl. area under the receiving operating characteristic, AUC). Tačiau kadangi nuostolių išvestinės skaičiavimas yra lemiamas žingsnis beveik visuose giliųjų neuroninių tinklų apmokymo algoritmuose, dažnai vietoj to optimizuojame diferencijuojamą pakaitinę funkciją.

Išvestinę f′(x)f'(x) galime interpretuoti kaip f(x)f(x) momentinį kitimo greitį xx atžvilgiu. Sudarykime šiek tiek intuicijos pavyzdžiu. (Apibrėžkime u=f(x)=3x2−4xu = f(x) = 3x^2-4x.)

def f(x):
    return 3 * x ** 2 - 4 * x
def f(x):
    return 3 * x ** 2 - 4 * x
def f(x):
    return 3 * x ** 2 - 4 * x
def f(x):
    return 3 * x ** 2 - 4 * x

Nustatę x=1x=1, matome, kad f(x+h)−f(x)h\frac{f(x+h) - f(x)}{h} (artėja prie 22, kai hh artėja prie 00.) Nors šiam eksperimentui trūksta matematinio įrodymo griežtumo, greitai matome, kad iš tiesų f′(1)=2f'(1) = 2.

for h in 10.0**np.arange(-1, -6, -1):
    print(f'h={h:.5f}, numerical limit={(f(1+h)-f(1))/h:.5f}')

Yra keletas ekvivalenčių išvestinių žymėjimo sutarčių. Kai duota y=f(x)y = f(x), šios išraiškos yra ekvivalenčios:

f′(x)=y′=dydx=dfdx=ddxf(x)=Df(x)=Dxf(x),f'(x) = y' = \frac{dy}{dx} = \frac{df}{dx} = \frac{d}{dx} f(x) = Df(x) = D_x f(x),

kur simboliai ddx\frac{d}{dx} ir DD yra diferencijavimo operatoriai. Toliau pateikiame kai kurių dažnų funkcijų išvestines:

ddxC=0for any constant Cddxxn=nxn−1for n≠0ddxex=exddxln⁡x=x−1.\begin{aligned} \frac{d}{dx} C & = 0 && \textrm{for any constant $C$} \\ \frac{d}{dx} x^n & = n x^{n-1} && \textrm{for } n \neq 0 \\ \frac{d}{dx} e^x & = e^x \\ \frac{d}{dx} \ln x & = x^{-1}. \end{aligned}

Funkcijos, sudarytos iš diferencijuojamų funkcijų, dažnai pačios yra diferencijuojamos. Šios taisyklės praverčia dirbant su bet kurių diferencijuojamų funkcijų ff ir gg bei konstantos CC kompozicijomis.

ddx[Cf(x)]=Cddxf(x)Constant multiple ruleddx[f(x)+g(x)]=ddxf(x)+ddxg(x)Sum ruleddx[f(x)g(x)]=f(x)ddxg(x)+g(x)ddxf(x)Product ruleddxf(x)g(x)=g(x)ddxf(x)−f(x)ddxg(x)g2(x)Quotient rule\begin{aligned} \frac{d}{dx} [C f(x)] & = C \frac{d}{dx} f(x) && \textrm{Constant multiple rule} \\ \frac{d}{dx} [f(x) + g(x)] & = \frac{d}{dx} f(x) + \frac{d}{dx} g(x) && \textrm{Sum rule} \\ \frac{d}{dx} [f(x) g(x)] & = f(x) \frac{d}{dx} g(x) + g(x) \frac{d}{dx} f(x) && \textrm{Product rule} \\ \frac{d}{dx} \frac{f(x)}{g(x)} & = \frac{g(x) \frac{d}{dx} f(x) - f(x) \frac{d}{dx} g(x)}{g^2(x)} && \textrm{Quotient rule} \end{aligned}

Pasinaudoję tuo, galime pritaikyti taisykles ir rasti 3x2−4x3 x^2 - 4x išvestinę:

ddx[3x2−4x]=3ddxx2−4ddxx=6x−4.\frac{d}{dx} [3 x^2 - 4x] = 3 \frac{d}{dx} x^2 - 4 \frac{d}{dx} x = 6x - 4.

Įrašę x=1x = 1, matome, kad iš tiesų išvestinė šioje vietoje lygi 22. Atkreipkite dėmesį, kad išvestinės mums pasako funkcijos nuolydį tam tikroje vietoje.

2.4.2 Vizualizavimo priemonės

Funkcijų nuolydžius galime vizualizuoti naudodami matplotlib biblioteką. Turime apibrėžti keletą funkcijų. Kaip rodo pavadinimas, use_svg_display nurodo matplotlib išvesti grafiką SVG formatu, kad vaizdai būtų ryškesni. Komentaras #@save yra speciali modifikacija, leidžianti išsaugoti bet kurią funkciją, klasę ar kitą kodo bloką d2l pakete, kad galėtume jį iškviesti vėliau nekartodami kodo, pvz., per d2l.use_svg_display().

def use_svg_display():  #@save
    """Use the svg format to display a plot in Jupyter."""
    backend_inline.set_matplotlib_formats('svg')

Patogiai galime nustatyti paveikslų dydžius funkcija set_figsize. Kadangi importo sakinys from matplotlib import pyplot as plt d2l pakete buvo pažymėtas #@save, galime kviesti d2l.plt.

def set_figsize(figsize=(3.5, 2.5)):  #@save
    """Set the figure size for matplotlib."""
    use_svg_display()
    d2l.plt.rcParams['figure.figsize'] = figsize

Funkcija set_axes gali susieti ašis su savybėmis, įskaitant užrašus, intervalus ir mastelius.

#@save
def set_axes(axes, xlabel, ylabel, xlim, ylim, xscale, yscale, legend):
    """Set the axes for matplotlib."""
    axes.set_xlabel(xlabel), axes.set_ylabel(ylabel)
    axes.set_xscale(xscale), axes.set_yscale(yscale)
    axes.set_xlim(xlim),     axes.set_ylim(ylim)
    if legend:
        axes.legend(legend)
    axes.grid()

Naudodami šias tris funkcijas, galime apibrėžti funkciją plot, kuri uždeda kelias kreives viena ant kitos. Didelė kodo dalis čia tik užtikrina, kad įvesčių dydžiai ir formos sutaptų.

#@save
def plot(X, Y=None, xlabel=None, ylabel=None, legend=[], xlim=None,
         ylim=None, xscale='linear', yscale='linear',
         fmts=('-', 'm--', 'g-.', 'r:'), figsize=(3.5, 2.5), axes=None):
    """Plot data points."""

    def has_one_axis(X):  # True if X (tensor or list) has 1 axis
        return (hasattr(X, "ndim") and X.ndim == 1 or isinstance(X, list)
                and not hasattr(X[0], "__len__"))
    
    if has_one_axis(X): X = [X]
    if Y is None:
        X, Y = [[]] * len(X), X
    elif has_one_axis(Y):
        Y = [Y]
    if len(X) != len(Y):
        X = X * len(Y)
        
    set_figsize(figsize)
    if axes is None:
        axes = d2l.plt.gca()
    axes.cla()
    for x, y, fmt in zip(X, Y, fmts):
        axes.plot(x,y,fmt) if len(x) else axes.plot(y,fmt)
    set_axes(axes, xlabel, ylabel, xlim, ylim, xscale, yscale, legend)

Dabar galime nubraižyti funkciją u=f(x)u = f(x) ir jos liestinę y=2x−3y = 2x - 3 taške x=1x=1, kur koeficientas 22 yra liestinės nuolydis.

x = np.arange(0, 3, 0.1)
plot(x, [f(x), 2 * x - 3], 'x', 'f(x)', legend=['f(x)', 'Tangent line (x=1)'])

2.4.3 Dalinės išvestinės ir gradientai

Iki šiol diferencijavome tik vieno kintamojo funkcijas. Giliajame mokyme taip pat reikia dirbti su daugelio kintamųjų funkcijomis. Trumpai pristatome išvestinės sąvokas, taikomas tokioms daugelio kintamųjų funkcijoms.

Tegul y=f(x1,x2,…,xn)y = f(x_1, x_2, \ldots, x_n) yra funkcija su nn kintamųjų. yy dalinė išvestinė ii-ojo jos parametro xix_i atžvilgiu yra

∂y∂xi=lim⁡h→0f(x1,…,xi−1,xi+h,xi+1,…,xn)−f(x1,…,xi,…,xn)h.\frac{\partial y}{\partial x_i} = \lim_{h \rightarrow 0} \frac{f(x_1, \ldots, x_{i-1}, x_i+h, x_{i+1}, \ldots, x_n) - f(x_1, \ldots, x_i, \ldots, x_n)}{h}.

Kad apskaičiuotume ∂y∂xi\frac{\partial y}{\partial x_i}, galime laikyti x1,…,xi−1,xi+1,…,xnx_1, \ldots, x_{i-1}, x_{i+1}, \ldots, x_n konstantomis ir apskaičiuoti yy išvestinę xix_i atžvilgiu. Šios dalinių išvestinių žymėjimo sutartys visos yra dažnos ir reiškia tą patį:

∂y∂xi=∂f∂xi=∂xif=∂if=fxi=fi=Dif=Dxif.\frac{\partial y}{\partial x_i} = \frac{\partial f}{\partial x_i} = \partial_{x_i} f = \partial_i f = f_{x_i} = f_i = D_i f = D_{x_i} f.

Daugelio kintamųjų funkcijos dalines išvestines visų jos kintamųjų atžvilgiu galime sujungti, kad gautume vektorių, vadinamą funkcijos gradientu. Tarkime, kad funkcijos f:Rn→Rf: \mathbb{R}^n \rightarrow \mathbb{R} įvestis yra nn-matis vektorius x=[x1,x2,…,xn]⊤\mathbf{x} = [x_1, x_2, \ldots, x_n]^\top, o išvestis – skaliaras. Funkcijos ff gradientas x\mathbf{x} atžvilgiu yra nn dalinių išvestinių vektorius:

∇xf(x)=[∂x1f(x),∂x2f(x),…∂xnf(x)]⊤.\nabla_{\mathbf{x}} f(\mathbf{x}) = \left[\partial_{x_1} f(\mathbf{x}), \partial_{x_2} f(\mathbf{x}), \ldots \partial_{x_n} f(\mathbf{x})\right]^\top.

Kai nėra dviprasmybės, ∇xf(x)\nabla_{\mathbf{x}} f(\mathbf{x}) paprastai pakeičiamas ∇f(x)\nabla f(\mathbf{x}). Šios taisyklės praverčia diferencijuojant daugelio kintamųjų funkcijas:

  • Visoms A∈Rm×n\mathbf{A} \in \mathbb{R}^{m \times n} turime ∇xAx=A⊤\nabla_{\mathbf{x}} \mathbf{A} \mathbf{x} = \mathbf{A}^\top ir ∇xx⊤A=A\nabla_{\mathbf{x}} \mathbf{x}^\top \mathbf{A} = \mathbf{A}.
  • Kvadratinėms matricoms A∈Rn×n\mathbf{A} \in \mathbb{R}^{n \times n} turime ∇xx⊤Ax=(A+A⊤)x\nabla_{\mathbf{x}} \mathbf{x}^\top \mathbf{A} \mathbf{x} = (\mathbf{A} + \mathbf{A}^\top)\mathbf{x} ir visų pirma ∇x∥x∥2=∇xx⊤x=2x\nabla_{\mathbf{x}} \|\mathbf{x} \|^2 = \nabla_{\mathbf{x}} \mathbf{x}^\top \mathbf{x} = 2\mathbf{x}.

Panašiai bet kuriai matricai X\mathbf{X} turime ∇X∥X∥F2=2X\nabla_{\mathbf{X}} \|\mathbf{X} \|_\textrm{F}^2 = 2\mathbf{X}.

2.4.4 Grandinės taisyklė

Giliajame mokyme dominantys gradientai dažnai sunkiai apskaičiuojami, nes dirbame su giliai įdėtomis funkcijomis (funkcijų (funkcijų...)). Laimei, grandinės taisyklė tuo pasirūpina. Grįždami prie vieno kintamojo funkcijų, tarkime, kad y=f(g(x))y = f(g(x)) ir kad pagrindinės funkcijos y=f(u)y=f(u) ir u=g(x)u=g(x) abi yra diferencijuojamos. Grandinės taisyklė teigia, kad

dydx=dydududx.\frac{dy}{dx} = \frac{dy}{du} \frac{du}{dx}.

Grįždami prie daugelio kintamųjų funkcijų, tarkime, kad y=f(u)y = f(\mathbf{u}) turi kintamuosius u1,u2,…,umu_1, u_2, \ldots, u_m, kur kiekvienas ui=gi(x)u_i = g_i(\mathbf{x}) turi kintamuosius x1,x2,…,xnx_1, x_2, \ldots, x_n, t. y. u=g(x)\mathbf{u} = g(\mathbf{x}). Tada grandinės taisyklė teigia, kad

∂y∂xi=∂y∂u1∂u1∂xi+∂y∂u2∂u2∂xi+…+∂y∂um∂um∂xi  and so  ∇xy=A∇uy,\frac{\partial y}{\partial x_{i}} = \frac{\partial y}{\partial u_{1}} \frac{\partial u_{1}}{\partial x_{i}} + \frac{\partial y}{\partial u_{2}} \frac{\partial u_{2}}{\partial x_{i}} + \ldots + \frac{\partial y}{\partial u_{m}} \frac{\partial u_{m}}{\partial x_{i}} \ \textrm{ and so } \ \nabla_{\mathbf{x}} y = \mathbf{A} \nabla_{\mathbf{u}} y,

kur A∈Rn×m\mathbf{A} \in \mathbb{R}^{n \times m} yra matrica, kurioje yra vektoriaus u\mathbf{u} išvestinė vektoriaus x\mathbf{x} atžvilgiu. Taigi gradiento apskaičiavimui reikia apskaičiuoti vektoriaus ir matricos sandaugą. Tai viena pagrindinių priežasčių, kodėl tiesinė algebra yra tokia neatsiejama dalis kuriant giliojo mokymosi sistemas.

2.4.5 Diskusija

Nors vos paliečiame gilią temą, jau išryškėja keletas sąvokų: pirma, diferencijavimo kompozicijos taisykles galima taikyti įprastai, todėl galime automatiškai skaičiuoti gradientus. Ši užduotis nereikalauja kūrybiškumo, todėl savo pažintines galias galime nukreipti kitur. Antra, skaičiuojant vektorines reikšmes turinčių funkcijų išvestines, reikia dauginti matricas, sekant kintamųjų priklausomybės grafą nuo išvesties iki įvesties. Visų pirma šis grafas einamas tiesiogine kryptimi, kai vertiname funkciją, ir atgaline kryptimi, kai skaičiuojame gradientus. Vėlesniuose skyriuose formaliai pristatysime atgalinį sklidimą – skaičiavimo procedūrą grandinės taisyklei taikyti.

Optimizavimo požiūriu gradientai leidžia mums nustatyti, kaip perkelti modelio parametrus, kad sumažintume nuostolius, o kiekvienam visoje knygoje naudojamų optimizavimo algoritmų žingsniui reikės apskaičiuoti gradientą.

2.4.6 Pratimai

  1. Iki šiol išvestinių taisykles priėmėme kaip savaime suprantamas. Naudodami apibrėžtį ir ribas, įrodykite savybes (i) f(x)=cf(x) = c, (ii) f(x)=xnf(x) = x^n, (iii) f(x)=exf(x) = e^x ir (iv) f(x)=log⁡xf(x) = \log x.
  2. Panašiai įrodykite sandaugos, sumos ir dalmens taisykles iš pirmųjų principų.
  3. Įrodykite, kad daugiklio konstantos taisyklė išplaukia kaip atskiras sandaugos taisyklės atvejis.
  4. Apskaičiuokite f(x)=xxf(x) = x^x išvestinę.
  5. Ką reiškia, kad f′(x)=0f'(x) = 0 kuriam nors xx? Pateikite funkcijos ff ir vietos xx pavyzdį, kuriam tai galėtų galioti.
  6. Nubraižykite funkciją y=f(x)=x3−1xy = f(x) = x^3 - \frac{1}{x} ir jos liestinę taške x=1x = 1.
  7. Raskite funkcijos f(x)=3x12+5ex2f(\mathbf{x}) = 3x_1^2 + 5e^{x_2} gradientą.
  8. Koks yra funkcijos f(x)=∥x∥2f(\mathbf{x}) = \|\mathbf{x}\|_2 gradientas? Kas nutinka, kai x=0\mathbf{x} = \mathbf{0}?
  9. Ar galite užrašyti grandinės taisyklę atvejui, kai u=f(x,y,z)u = f(x, y, z) ir x=x(a,b)x = x(a, b), y=y(a,b)y = y(a, b) bei z=z(a,b)z = z(a, b)?
  10. Kai duota apgręžiama funkcija f(x)f(x), apskaičiuokite jos atvirkštinės funkcijos f−1(x)f^{-1}(x) išvestinę. Čia turime, kad f−1(f(x))=xf^{-1}(f(x)) = x ir atvirkščiai f(f−1(y))=yf(f^{-1}(y)) = y. Užuomina: savo išvedime naudokite šias savybes.

Diskusijos

Diskusijos

Diskusijos

Diskusijos