.. _sec_rmsprop: RMSProp ======= :numref:`sec_adagrad` içindeki en önemli konulardan biri, öğrenme oranının önceden tanımlanmış bir zamanlamayla :math:`\mathcal{O}(t^{-\frac{1}{2}})` etkin bir şekilde azalmasıdır. Bu genellikle dışbükey problemler için uygun olsa da, derin öğrenmede karşılaşılanlar gibi dışbükey olmayan olanlar için ideal olmayabilir. Yine de, Adagrad'ın koordinat yönlü uyarlanması ön koşul olarak son derece arzu edilir. :cite:`Tieleman.Hinton.2012`, oran zamanlamasını koordinat-uyarlamalı öğrenme oranlarından ayırmak için basit bir düzeltme olarak RMSProp algoritmasını önerdi. Sorun, Adagrad'ın :math:`\mathbf{g}_t` gradyanının karelerini bir durum vektörü :math:`\mathbf{s}_t = \mathbf{s}_{t-1} + \mathbf{g}_t^2` olarak biriktirmesidir. Sonuç olarak :math:`\mathbf{s}_t`, normalleştirme eksikliğinden dolayı sınır olmadan, esasında algoritma yakınsadıkça doğrusal olarak büyümeye devam eder. Bu sorunu çözmenin bir yolu :math:`\mathbf{s}_t / t`'yi kullanmaktır. :math:`\mathbf{g}_t`'nin makul dağılımları için bu yakınsayacaktır. Ne yazık ki, prosedür tüm değerlerin yörüngesini hatırladığından, limit davranışının etkin olmaya başlaması çok uzun zaman alabilir. Alternatifi, momentum yönteminde kullandığımız gibi sızan bir ortalama kullanmaktır, yani bazı :math:`\gamma > 0` parametresi için :math:`\mathbf{s}_t \leftarrow \gamma \mathbf{s}_{t-1} + (1-\gamma) \mathbf{g}_t^2`. Diğer tüm parçaları değiştirmeden tutmak, RMSProp'u verir. Algoritma --------- Denklemleri ayrıntılı olarak yazalım. .. math:: \begin{aligned} \mathbf{s}_t & \leftarrow \gamma \mathbf{s}_{t-1} + (1 - \gamma) \mathbf{g}_t^2, \\ \mathbf{x}_t & \leftarrow \mathbf{x}_{t-1} - \frac{\eta}{\sqrt{\mathbf{s}_t + \epsilon}} \odot \mathbf{g}_t. \end{aligned} :math:`\epsilon > 0` sabiti, sıfır veya aşırı büyük adım boyutlarına bölünmediğimizden emin olmak için tipik olarak :math:`10^{-6}` olarak ayarlanır. Bu genişleme göz önüne alındığında, koordinat başına uygulanan ölçeklendirmeden bağımsız olarak :math:`\eta` öğrenme oranını kontrol etmede serbestiz. Sızdıran ortalamalar açısından, momentum yöntemi için daha önce uygulanan mantığın aynısını uygulayabiliriz. :math:`\mathbf{s}_t` tanımını genişletmek şu ifadeye yol açar: .. math:: \begin{aligned} \mathbf{s}_t & = (1 - \gamma) \mathbf{g}_t^2 + \gamma \mathbf{s}_{t-1} \\ & = (1 - \gamma) \left(\mathbf{g}_t^2 + \gamma \mathbf{g}_{t-1}^2 + \gamma^2 \mathbf{g}_{t-2} + \ldots, \right). \end{aligned} Daha önce :numref:`sec_momentum` içinde olduğu gibi :math:`1 + \gamma + \gamma^2 + \ldots, = \frac{1}{1-\gamma}` kullanıyoruz. Bu nedenle ağırlıkların toplamı :math:`\gamma^{-1}`'lik bir gözlem yarılanma ömrü ile :math:`1`'e normalleştirilir. Çeşitli :math:`\gamma` seçenekleri için son 40 zaman adımının ağırlıklarını görselleştirelim. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python %matplotlib inline import math from d2l import mxnet as d2l from mxnet import np, npx npx.set_np() d2l.set_figsize() gammas = [0.95, 0.9, 0.8, 0.7] for gamma in gammas: x = np.arange(40).asnumpy() d2l.plt.plot(x, (1-gamma) * gamma ** x, label=f'gamma = {gamma:.2f}') d2l.plt.xlabel('time'); .. figure:: output_rmsprop_251805_3_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python import math import torch from d2l import torch as d2l d2l.set_figsize() gammas = [0.95, 0.9, 0.8, 0.7] for gamma in gammas: x = torch.arange(40).detach().numpy() d2l.plt.plot(x, (1-gamma) * gamma ** x, label=f'gamma = {gamma:.2f}') d2l.plt.xlabel('time'); .. figure:: output_rmsprop_251805_6_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python import math import tensorflow as tf from d2l import tensorflow as d2l d2l.set_figsize() gammas = [0.95, 0.9, 0.8, 0.7] for gamma in gammas: x = tf.range(40).numpy() d2l.plt.plot(x, (1-gamma) * gamma ** x, label=f'gamma = {gamma:.2f}') d2l.plt.xlabel('time'); .. figure:: output_rmsprop_251805_9_0.svg .. raw:: html
.. raw:: html
Sıfırdan Uygulama ----------------- Daha önce olduğu gibi, RMSProp yörüngesini gözlemlemek için :math:`f(\mathbf{x})=0.1x_1^2+2x_2^2` ikinci dereceden polinom işlevini kullanıyoruz. :numref:`sec_adagrad` içinde Adagrad'ı 0.4 öğrenme oranıyla kullandığımızda, öğrenme oranı çok hızlı düştüğü için değişkenlerin algoritmanın sonraki aşamalarında çok yavaş hareket ettiğini hatırlayın. :math:`\eta` ayrı ayrı kontrol edildiğinden bu RMSProp ile gerçekleşmez. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def rmsprop_2d(x1, x2, s1, s2): g1, g2, eps = 0.2 * x1, 4 * x2, 1e-6 s1 = gamma * s1 + (1 - gamma) * g1 ** 2 s2 = gamma * s2 + (1 - gamma) * g2 ** 2 x1 -= eta / math.sqrt(s1 + eps) * g1 x2 -= eta / math.sqrt(s2 + eps) * g2 return x1, x2, s1, s2 def f_2d(x1, x2): return 0.1 * x1 ** 2 + 2 * x2 ** 2 eta, gamma = 0.4, 0.9 d2l.show_trace_2d(f_2d, d2l.train_2d(rmsprop_2d)) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output epoch 20, x1: -0.010599, x2: 0.000000 .. figure:: output_rmsprop_251805_15_1.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def rmsprop_2d(x1, x2, s1, s2): g1, g2, eps = 0.2 * x1, 4 * x2, 1e-6 s1 = gamma * s1 + (1 - gamma) * g1 ** 2 s2 = gamma * s2 + (1 - gamma) * g2 ** 2 x1 -= eta / math.sqrt(s1 + eps) * g1 x2 -= eta / math.sqrt(s2 + eps) * g2 return x1, x2, s1, s2 def f_2d(x1, x2): return 0.1 * x1 ** 2 + 2 * x2 ** 2 eta, gamma = 0.4, 0.9 d2l.show_trace_2d(f_2d, d2l.train_2d(rmsprop_2d)) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output epoch 20, x1: -0.010599, x2: 0.000000 /home/d2l-worker/miniconda3/envs/d2l-tr-release-0/lib/python3.9/site-packages/torch/functional.py:478: UserWarning: torch.meshgrid: in an upcoming release, it will be required to pass the indexing argument. (Triggered internally at ../aten/src/ATen/native/TensorShape.cpp:2895.) return _VF.meshgrid(tensors, **kwargs) # type: ignore[attr-defined] .. figure:: output_rmsprop_251805_18_1.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def rmsprop_2d(x1, x2, s1, s2): g1, g2, eps = 0.2 * x1, 4 * x2, 1e-6 s1 = gamma * s1 + (1 - gamma) * g1 ** 2 s2 = gamma * s2 + (1 - gamma) * g2 ** 2 x1 -= eta / math.sqrt(s1 + eps) * g1 x2 -= eta / math.sqrt(s2 + eps) * g2 return x1, x2, s1, s2 def f_2d(x1, x2): return 0.1 * x1 ** 2 + 2 * x2 ** 2 eta, gamma = 0.4, 0.9 d2l.show_trace_2d(f_2d, d2l.train_2d(rmsprop_2d)) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output epoch 20, x1: -0.010599, x2: 0.000000 .. figure:: output_rmsprop_251805_21_1.svg .. raw:: html
.. raw:: html
Ardından, derin bir ağda kullanılacak RMSProp'u uyguluyoruz. Bu da son derece basit. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def init_rmsprop_states(feature_dim): s_w = np.zeros((feature_dim, 1)) s_b = np.zeros(1) return (s_w, s_b) def rmsprop(params, states, hyperparams): gamma, eps = hyperparams['gamma'], 1e-6 for p, s in zip(params, states): s[:] = gamma * s + (1 - gamma) * np.square(p.grad) p[:] -= hyperparams['lr'] * p.grad / np.sqrt(s + eps) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def init_rmsprop_states(feature_dim): s_w = torch.zeros((feature_dim, 1)) s_b = torch.zeros(1) return (s_w, s_b) def rmsprop(params, states, hyperparams): gamma, eps = hyperparams['gamma'], 1e-6 for p, s in zip(params, states): with torch.no_grad(): s[:] = gamma * s + (1 - gamma) * torch.square(p.grad) p[:] -= hyperparams['lr'] * p.grad / torch.sqrt(s + eps) p.grad.data.zero_() .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def init_rmsprop_states(feature_dim): s_w = tf.Variable(tf.zeros((feature_dim, 1))) s_b = tf.Variable(tf.zeros(1)) return (s_w, s_b) def rmsprop(params, grads, states, hyperparams): gamma, eps = hyperparams['gamma'], 1e-6 for p, s, g in zip(params, states, grads): s[:].assign(gamma * s + (1 - gamma) * tf.math.square(g)) p[:].assign(p - hyperparams['lr'] * g / tf.math.sqrt(s + eps)) .. raw:: html
.. raw:: html
İlk öğrenme oranını 0.01 ve ağırlıklandırma terimi :math:`\gamma`'yı 0.9'a ayarladık. Yani, :math:`\mathbf{s}`, kare gradyanın son :math:`1/(1-\gamma) = 10` adet gözlem üzerinden ortalama olarak toplanır. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python data_iter, feature_dim = d2l.get_data_ch11(batch_size=10) d2l.train_ch11(rmsprop, init_rmsprop_states(feature_dim), {'lr': 0.01, 'gamma': 0.9}, data_iter, feature_dim); .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output loss: 0.245, 0.159 sec/epoch .. figure:: output_rmsprop_251805_39_1.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python data_iter, feature_dim = d2l.get_data_ch11(batch_size=10) d2l.train_ch11(rmsprop, init_rmsprop_states(feature_dim), {'lr': 0.01, 'gamma': 0.9}, data_iter, feature_dim); .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output loss: 0.250, 0.015 sec/epoch .. figure:: output_rmsprop_251805_42_1.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python data_iter, feature_dim = d2l.get_data_ch11(batch_size=10) d2l.train_ch11(rmsprop, init_rmsprop_states(feature_dim), {'lr': 0.01, 'gamma': 0.9}, data_iter, feature_dim); .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output loss: 0.244, 0.115 sec/epoch .. figure:: output_rmsprop_251805_45_1.svg .. raw:: html
.. raw:: html
Kısa Uygulama ------------- RMSProp oldukça popüler bir algoritma olduğundan ``Trainer`` örneğinde de mevcuttur. Tek yapmamız gereken ``rmsprop`` adlı bir algoritma kullanarak, :math:`\gamma`'yı ``gamma1`` parametresine atamak. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python d2l.train_concise_ch11('rmsprop', {'learning_rate': 0.01, 'gamma1': 0.9}, data_iter) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output loss: 0.245, 0.089 sec/epoch .. figure:: output_rmsprop_251805_51_1.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python trainer = torch.optim.RMSprop d2l.train_concise_ch11(trainer, {'lr': 0.01, 'alpha': 0.9}, data_iter) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output loss: 0.242, 0.014 sec/epoch .. figure:: output_rmsprop_251805_54_1.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python trainer = tf.keras.optimizers.RMSprop d2l.train_concise_ch11(trainer, {'learning_rate': 0.01, 'rho': 0.9}, data_iter) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output loss: 0.248, 0.141 sec/epoch .. figure:: output_rmsprop_251805_57_1.svg .. raw:: html
.. raw:: html
Özet ---- - RMSProp, her ikisi de katsayıları ölçeklendirmek için gradyanın karesini kullandığı için Adagrad'a çok benzer. - RMSProp, sızıntı ortalamasını momentum ile paylaşır. Bununla birlikte, RMSProp, katsayı bazında ön koşullayıcıyı ayarlamak için bu tekniği kullanır. - Öğrenme oranının pratikte deney yapan tarafından planlanması gerekir. - :math:`\gamma` katsayısı, koordinat başına ölçeği ayarlarken geçmişin ne kadar geri gideceğini belirler. Alıştırmalar ------------ 1. :math:`\gamma = 1`'i ayarlarsak deneysel olarak ne olur? Neden? 2. Optimizasyon problemi :math:`f(\mathbf{x}) = 0.1 (x_1 + x_2)^2 + 2 (x_1 - x_2)^2`'yi en aza indirmek için döndürün. Yakınsamaya ne olur? 3. Fashion-MNIST eğitimi gibi gerçek bir makine öğrenmesi probleminde RMSProp'a ne olduğunu deneyin. Öğrenme oranını ayarlamak için farklı seçeneklerle denemeler yapın. 4. Optimizasyon ilerledikçe :math:`\gamma`'yı ayarlamak ister misiniz? RMSProp buna ne kadar duyarlıdır? .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
`Tartışmalar `__ .. raw:: html
.. raw:: html
`Tartışmalar `__ .. raw:: html
.. raw:: html
`Tartışmalar `__ .. raw:: html
.. raw:: html