.. _sec_calculus: Hesaplama (Kalkülüs) ==================== Bir çokgenin alanını bulmak, eski Yunanlıların bir çokgeni üçgenlere böldüğü ve alanlarını topladığı en az 2.500 yıl öncesine kadar gizemli kalmıştı. Bir daire gibi kavisli şekillerin alanını bulmak için, eski Yunanlılar bu şekillerin içine çokgenler yerleştirdiler. :numref:`fig_circle_area`'de gösterildiği gibi, eşit uzunlukta daha fazla kenarı olan çizili bir çokgen daireye bayağı yaklaşır. Bu işlem *tüketme yöntemi* olarak da bilinir. .. _fig_circle_area: .. figure:: ../img/polygon-circle.svg Tüketme yöntemiyle bir dairenin alanını bulun. Aslında, tüketme yöntemi *integral hesabının* (şurada açıklanacaktır :numref:`sec_integral_calculus`) kaynaklandığı yerdir. 2.000 yıldan fazla bir müddetten sonra, diğer kalkülüs alanı, *diferansiyel (türevsel) kalkülüs* icat edildi. Diferansiyel kalkülüsün en kritik uygulamaları arasındaki optimizasyon problemleri bir şeyin nasıl *en iyi* şekilde yapılacağına kafa yorar. :numref:`subsec_norms_and_objectives`'de tartışıldığı gibi, bu tür sorunlar derin öğrenmede her yerde bulunur. Derin öğrenmede, modelleri daha fazla veri gördükçe daha iyi ve daha iyi olmaları için arka arkaya güncelleyerek *eğitiyoruz*. Genellikle, daha iyi olmak, "modelimiz ne kadar *kötü*?" sorusuna cevap veren bir skor olan *kayıp (yitim) fonksiyonunu* en aza indirmek anlamına gelir. Bu soru göründüğünden daha zekicedir. Sonuçta, gerçekten önemsediğimiz, daha önce hiç görmediğimiz veriler üzerinde iyi performans gösteren bir model üretmektir. Ancak modeli yalnızca gerçekten görebildiğimiz verilere uydurabiliriz. Böylece modellerin uydurulması görevini iki temel kaygıya ayırabiliriz: (i) *Eniyileme*: Modellerimizi gözlemlenen verilere uydurma süreci; (ii) *Genelleme*: Geçerliliği onları eğitmek için kullanılan kesin veri örnekleri kümesinin ötesine geçen modellerin nasıl üretileceğinde bize rehberlik eden matematiksel ilkelerin ve uygulayıcılarının bilgeliği. Daha sonraki bölümlerde optimizasyon problemlerini ve yöntemlerini anlamanıza yardımcı olmak için burada, derin öğrenmede yaygın olarak kullanılan diferansiyel hesaplama hakkında bir tutam bilgi veriyoruz. Türev ve Türev Alma ------------------- Hemen hemen tüm derin öğrenme optimizasyon algoritmalarında önemli bir adım olan türevlerin hesaplanmasını ele alarak başlıyoruz. Derin öğrenmede, tipik olarak modelimizin parametrelerine göre türevi alınabilen kayıp fonksiyonlarını seçeriz. Basitçe ifade etmek gerekirse, bu, her parametre için, o parametreyi sonsuz derecede küçük bir miktarda *arttırırsak* veya *azaltırsak* kaybın ne kadar hızlı artacağını veya azalacağını belirleyebileceğimiz anlamına gelir. Girdi ve çıktıların her ikisi de skaler olan :math:`f: \mathbb {R} \rightarrow \mathbb{R}` fonksiyonumuz olduğunu varsayalım. :math:`f`'nin *türevi* şöyle tanımlanır: .. math:: f'(x) = \lim_{h \rightarrow 0} \frac{f(x+h) - f(x)}{h}, :label: eq_derivative eğer bu limit varsa. :math:`f'(a)` varsa, :math:`f`'nin :math:`a`'da *türevlenebilir* olduğu söylenir. :math:`f`, bir aralığın her sayısında türevlenebilirse, o zaman bu fonksiyon bu aralıkta türevlenebilir. :math:`f'(x)`'in :eq:`eq_derivative`'deki türevini :math:`f(x)`'in :math:`x`'e göre *anlık* değişim oranı olarak yorumlayabiliriz. Sözde anlık değişim oranı, :math:`x` cinsinden :math:`h` :math:`0`'a yaklaşırken değişimini temel alır. Türevleri açıklamayı için bir örnekle deneyelim. :math:`u = f(x) = 3x^2-4x` tanımlayın. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python %matplotlib inline from matplotlib_inline import backend_inline from d2l import mxnet as d2l from mxnet import np, npx npx.set_np() def f(x): return 3 * x ** 2 - 4 * x .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python %matplotlib inline import numpy as np from matplotlib_inline import backend_inline from d2l import torch as d2l def f(x): return 3 * x ** 2 - 4 * x .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python %matplotlib inline import numpy as np from matplotlib_inline import backend_inline from d2l import tensorflow as d2l def f(x): return 3 * x ** 2 - 4 * x .. raw:: html
.. raw:: html
:math:`x = 1` diye ayarlayıp :math:`h` değerinin :math:`0` değerine yaklaşmasına izin verince :math:`\frac{f(x+h) - f(x)}{h}` :eq:`eq_derivative`'in sayısal sonucu :math:`2`'ye yaklaşır. Bu deney matematiksel bir kanıt olmasa da, daha sonra :math:`u'` türevinin :math:`x=1` olduğunda :math:`2` olduğunu göreceğiz. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def numerical_lim(f, x, h): return (f(x + h) - f(x)) / h h = 0.1 for i in range(5): print(f'h={h:.5f}, numerik limit={numerical_lim(f, 1, h):.5f}') h *= 0.1 .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output h=0.10000, numerik limit=2.30000 h=0.01000, numerik limit=2.03000 h=0.00100, numerik limit=2.00300 h=0.00010, numerik limit=2.00030 h=0.00001, numerik limit=2.00003 .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def numerical_lim(f, x, h): return (f(x + h) - f(x)) / h h = 0.1 for i in range(5): print(f'h={h:.5f}, numerik limit={numerical_lim(f, 1, h):.5f}') h *= 0.1 .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output h=0.10000, numerik limit=2.30000 h=0.01000, numerik limit=2.03000 h=0.00100, numerik limit=2.00300 h=0.00010, numerik limit=2.00030 h=0.00001, numerik limit=2.00003 .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def numerical_lim(f, x, h): return (f(x + h) - f(x)) / h h = 0.1 for i in range(5): print(f'h={h:.5f}, numerik limit={numerical_lim(f, 1, h):.5f}') h *= 0.1 .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output h=0.10000, numerik limit=2.30000 h=0.01000, numerik limit=2.03000 h=0.00100, numerik limit=2.00300 h=0.00010, numerik limit=2.00030 h=0.00001, numerik limit=2.00003 .. raw:: html
.. raw:: html
Kendimizi türevler için birkaç eşdeğer gösterimle tanıştıralım. :math:`y = f(x)` verildiğinde, :math:`x` ve :math:`y` sırasıyla :math:`f` işlevinin bağımsız ve bağımlı değişkenleridir. Aşağıdaki ifadeler eşdeğerdir: .. math:: f'(x) = y' = \frac{dy}{dx} = \frac{df}{dx} = \frac{d}{dx} f(x) = Df(x) = D_x f(x), burada :math:`\frac{d}{dx}` ve :math:`D` sembolleri *türev alma* işlevini gösteren *türev alma* operatörleridir. Yaygın işlevlerin türevini alma için aşağıdaki kuralları kullanabiliriz: - :math:`DC = 0` (:math:`C` bir sabit), - :math:`Dx^n = nx^{n-1}` (*üs kuralı*, :math:`n` bir gerçel sayı), - :math:`De^x = e^x`, - :math:`D\ln(x) = 1/x.` Yukarıdaki yaygın işlevler gibi birkaç basit işlevden oluşan bir işlevin türevini alırken için aşağıdaki kurallar bizim için kullanışlı olabilir. :math:`f` ve :math:`g` işlevlerinin ikisinin de türevlenebilir ve :math:`C`'nin sabit olduğunu varsayalım, elimizde *sabit çarpım kuralı*, .. math:: \frac{d}{dx} [Cf(x)] = C \frac{d}{dx} f(x), *toplam kuralı* .. math:: \frac{d}{dx} [f(x) + g(x)] = \frac{d}{dx} f(x) + \frac{d}{dx} g(x), *çarpım kuralı* .. math:: \frac{d}{dx} [f(x)g(x)] = f(x) \frac{d}{dx} [g(x)] + g(x) \frac{d}{dx} [f(x)], ve *bölme kuralı* vardır. .. math:: \frac{d}{dx} \left[\frac{f(x)}{g(x)}\right] = \frac{g(x) \frac{d}{dx} [f(x)] - f(x) \frac{d}{dx} [g(x)]}{[g(x)]^2}. Şimdi :math:`u' = f'(x) = 3 \frac{d}{dx} x^2-4\frac{d}{dx}x = 6x-4`'ı bulmak için yukarıdaki kurallardan birkaçını uygulayabiliriz. Bu nedenle, :math:`x = 1` atadığımız da, :math:`u' = 2` değerine sahibiz: Sayısal sonucun :math:`2`'ye yaklaştığı, bu bölümdeki önceki denememiz tarafından desteklenmektedir. Bu türev aynı zamanda :math:`u = f(x)` eğrisine :math:`x = 1`'deki teğet doğrusunun eğimidir. Türevlerin bu tür yorumunu görselleştirmek için Python'da popüler bir çizim kütüphanesi olan ``matplotlib``'i kullanacağız. ``matplotlib`` tarafından üretilen şekillerin özelliklerini yapılandırmak için birkaç işlev tanımlamamız gerekir. Aşağıdaki ``use_svg_display`` işlevi, daha keskin görüntülü svg şekilleri çıktısı almak için ``matplotlib`` paketini özelleştirir. ``#@save`` yorumunun, aşağıdaki işlev, sınıf veya ifadelerin ``d2l`` paketine kaydedildiği ve böylece daha sonra yeniden tanımlanmadan doğrudan çağrılabilecekleri (örneğin, ``d2l.use_svg_display()``) özel bir terim olduğuna dikkat edin. .. raw:: latex \diilbookstyleinputcell .. code:: python def use_svg_display(): #@save """Jupyter içinde şekli göstermek için svg formatı kullan""" backend_inline.set_matplotlib_formats('svg') Şekil boyutlarını belirtmek için ``set_figsize`` fonksiyonunu tanımlarız. Burada doğrudan ``d2l.plt``'yi kullandığımıza dikkat edin, çünkü içe aktarma komutu, ``from matplotlib import pyplot as plt``, önsöz bölümündeki ``d2l`` paketine kaydedilmek üzere işaretlenmişti. .. raw:: latex \diilbookstyleinputcell .. code:: python def set_figsize(figsize=(3.5, 2.5)): #@save """Şekil ebatını matplotlib için ayarla""" use_svg_display() d2l.plt.rcParams['figure.figsize'] = figsize Aşağıdaki ``set_axes`` işlevi, ``matplotlib`` tarafından üretilen şekillerin eksenlerinin özelliklerini ayarlar. .. raw:: latex \diilbookstyleinputcell .. code:: python #@save def set_axes(axes, xlabel, ylabel, xlim, ylim, xscale, yscale, legend): """Eksenleri matplotlib için ayarla.""" 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() Şekil biçimlendirmeleri için bu üç işlevle, kitap boyunca birçok eğriyi görselleştirmemiz gerekeceğinden, çoklu eğrileri kısa ve öz olarak çizmek için ``plot`` işlevini tanımlıyoruz. .. raw:: latex \diilbookstyleinputcell .. code:: python #@save def plot(X, Y=None, xlabel=None, ylabel=None, legend=None, xlim=None, ylim=None, xscale='linear', yscale='linear', fmts=('-', 'm--', 'g-.', 'r:'), figsize=(3.5, 2.5), axes=None): """Veri noktalarını çiz.""" if legend is None: legend = [] set_figsize(figsize) axes = axes if axes else d2l.plt.gca() # `X` (tensor veya liste) 1 eksenli ise True değeri döndür def has_one_axis(X): 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) axes.cla() for x, y, fmt in zip(X, Y, fmts): if len(x): axes.plot(x, y, fmt) else: axes.plot(y, fmt) set_axes(axes, xlabel, ylabel, xlim, ylim, xscale, yscale, legend) Şimdi :math:`u = f(x)` fonksiyonunu ve :math:`y = 2x - 3` teğet doğrusunu :math:`x=1`'de çizebiliriz, burada :math:`2` katsayısı teğet doğrusunun eğimidir. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python x = np.arange(0, 3, 0.1) plot(x, [f(x), 2 * x - 3], 'x', 'f(x)', legend=['f(x)', 'Teget dogrusu (x=1)']) .. figure:: output_calculus_7e7694_35_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python x = np.arange(0, 3, 0.1) plot(x, [f(x), 2 * x - 3], 'x', 'f(x)', legend=['f(x)', 'Teget dogrusu (x=1)']) .. figure:: output_calculus_7e7694_38_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python x = np.arange(0, 3, 0.1) plot(x, [f(x), 2 * x - 3], 'x', 'f(x)', legend=['f(x)', 'Teget dogrusu (x=1)']) .. figure:: output_calculus_7e7694_41_0.svg .. raw:: html
.. raw:: html
Kısmi Türevler -------------- Şimdiye kadar sadece tek değişkenli fonksiyonların türevinin alınması ile uğraştık. Derin öğrenmede, işlevler genellikle *birçok* değişkene bağlıdır. Bu nedenle, türev alma fikirlerini bu *çok değişkenli* fonksiyonlara genişletmemiz gerekiyor. :math:`y = f(x_1, x_2, \ldots, x_n)`, :math:`n` değişkenli bir fonksiyon olsun. :math:`y`'nin :math:`i.` parametresi :math:`x_i`'ye göre *kısmi türevi* şöyledir: .. math:: \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}. :math:`\frac{\partial y}{\partial x_i}`'ı hesaplarken, :math:`x_1, \ldots, x_{i-1}, x_{i+1}, \ldots, x_n`'ı sabitler olarak kabul eder ve :math:`y`'nin :math:`x_i`'ye göre türevini hesaplayabiliriz. Kısmi türevlerin gösterimi için aşağıdakiler eşdeğerdir: .. math:: \frac{\partial y}{\partial x_i} = \frac{\partial f}{\partial x_i} = f_{x_i} = f_i = D_i f = D_{x_i} f. .. _subsec_calculus-grad: Gradyanlar (Eğimler) -------------------- Fonksiyonun *gradyan* vektörünü elde etmek için çok değişkenli bir fonksiyonun tüm değişkenlerine göre kısmi türevlerini art arda bitiştirebiliriz. :math:`f : \mathbb{R}^n \rightarrow \mathbb{R}` işlevinin girdisinin :math:`n` boyutlu bir vektör, :math:`\mathbf{x} = [x_1, x_2, \ldots, x_n]^\top` olduğunu varsayalım ve çıktı bir skalerdir. :math:`\mathbf{x}`'e göre :math:`f(\mathbf{x})` fonksiyonunun gradyanı, :math:`n` tane kısmi türevli bir vektördür: .. math:: \nabla_{\mathbf{x}} f(\mathbf{x}) = \bigg[\frac{\partial f(\mathbf{x})}{\partial x_1}, \frac{\partial f(\mathbf{x})}{\partial x_2}, \ldots, \frac{\partial f(\mathbf{x})}{\partial x_n}\bigg]^\top, belirsizlik olmadığında, :math:`\nabla_{\mathbf{x}} f(\mathbf{x})` genellikle :math:`\nabla f(\mathbf{x})` ile değiştirilir. :math:`\mathbf{x}` bir :math:`n` boyutlu vektör olsun, aşağıdaki kurallar genellikle çok değişkenli fonksiyonların türevini alırken kullanılır: - Her :math:`\mathbf{A} \in \mathbb{R}^{m \times n}` için, :math:`\nabla_{\mathbf{x}} \mathbf{A} \mathbf{x} = \mathbf{A}^\top`, - Her :math:`\mathbf{A} \in \mathbb{R}^{n \times m}` için, :math:`\nabla_{\mathbf{x}} \mathbf{x}^\top \mathbf{A} = \mathbf{A}`, - Her :math:`\mathbf{A} \in \mathbb{R}^{n \times n}` için, :math:`\nabla_{\mathbf{x}} \mathbf{x}^\top \mathbf{A} \mathbf{x} = (\mathbf{A} + \mathbf{A}^\top)\mathbf{x}`, - :math:`\nabla_{\mathbf{x}} \|\mathbf{x} \|^2 = \nabla_{\mathbf{x}} \mathbf{x}^\top \mathbf{x} = 2\mathbf{x}`. Benzer şekilde, herhangi bir :math:`\mathbf{X}` matrisi için, :math:`\nabla_{\mathbf{X}} \|\mathbf {X} \|_F^2 = 2\mathbf{X}` olur. Daha sonra göreceğimiz gibi, gradyanlar derin öğrenmede optimizasyon algoritmaları tasarlamak için kullanışlıdır. Zincir kuralı ------------- Bununla birlikte, bu tür gradyanları bulmak zor olabilir. Bunun nedeni, derin öğrenmedeki çok değişkenli işlevlerin genellikle *bileşik* olmasıdır, bu nedenle bu işlevlerin türevleri için yukarıda belirtilen kuralların hiçbirini uygulamayabiliriz. Neyse ki, *zincir kuralı* bileşik işlevlerin türevlerini almamızı sağlar. Önce tek değişkenli fonksiyonları ele alalım. :math:`y = f(u)` ve :math:`u=g(x)` işlevlerinin her ikisinin de türevlenebilir olduğunu varsayalım, bu durumda zincir kuralı şunu belirtir: .. math:: \frac{dy}{dx} = \frac{dy}{du} \frac{du}{dx}. Şimdi dikkatimizi, fonksiyonların keyfi sayıda değişkene sahip olduğu daha genel bir senaryoya çevirelim. :math:`y` türevlenebilir fonksiyonunun :math:`u_1, u_2, \ldots, u_m` değişkenlerine sahip olduğunu varsayalım, burada her türevlenebilir fonksiyon :math:`u_i`, :math:`x_1, x_2, \ldots, x_n` değişkenlerine sahiptir. :math:`y` değerinin :math:`x_1, x_2, \ldots, x_n`'nin bir işlevi olduğuna dikkat edin. Sonra bütün :math:`i = 1, 2, \ldots, n` için, zincir kuralı şunu gösterir: .. math:: \frac{dy}{dx_i} = \frac{dy}{du_1} \frac{du_1}{dx_i} + \frac{dy}{du_2} \frac{du_2}{dx_i} + \cdots + \frac{dy}{du_m} \frac{du_m}{dx_i} Özet ---- - Diferansiyel kalkülüs ve integral kalkülüs, ilki derin öğrenmede her yerde bulunan optimizasyon problemlerine uygulanabilen iki analiz dalıdır. - Bir türev, bir fonksiyonun değişkenine göre anlık değişim hızı olarak yorumlanabilir. Aynı zamanda fonksiyonun eğrisine teğet doğrusunun eğimidir. - Gradyan, bileşenleri çok değişkenli bir fonksiyonun tüm değişkenlerine göre kısmi türevleri olan bir vektördür. - Zincir kuralı, bileşik fonksiyonların türevlerini almamızı sağlar. Alıştırmalar ------------ 1. :math:`y = f(x) = x^3 - \frac{1}{x}` fonksiyonunu ve :math:`x = 1` olduğunda teğet doğrusunu çizin. 2. :math:`f(\mathbf{x}) = 3x_1^2 + 5e^{x_2}` fonksiyonunun gradyanını bulun. 3. :math:`f(\mathbf{x}) = \|\mathbf{x}\|_2` fonksiyonunun gradyanı nedir? 4. :math:`u = f(x, y, z)` ve :math:`x = x(a, b)`, :math:`y = y(a, b)` ve :math:`z = z(a, b)` olduğu durum için zincir kuralını yazabilir misiniz? .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
`Tartışmalar `__ .. raw:: html
.. raw:: html
`Tartışmalar `__ .. raw:: html
.. raw:: html
`Tartışmalar `__ .. raw:: html
.. raw:: html