Optimisasi Lanjut dan Analisis Konveks — Tranche Asli 1: Metode Stokastik Komposit, Cermin, dan Minibatch

Lapisan penyelesaian kursus mandiri

2026-08-25

Pernyataan edisi. Materi asli untuk menutup kesenjangan kurikulum O015/D90.
Teks dan laboratorium baru: CC BY-SA 4.0; kelas dan makro: CC BY 4.0.
Rujukan matematis tidak menyiratkan penyusunan, pemeriksaan, persetujuan, sponsor, atau dukungan oleh penulis maupun institusi yang dirujuk.

Tentang tranche ini

Tranche ini adalah lapisan penghubung mandiri setelah tulang punggung Habring dan tiga modul Becker yang diterima. Ia bukan terjemahan terselubung dari satu sumber lain. Definisi, teorema, bukti, algoritma, latihan, petunjuk, solusi, dan laboratorium ditulis secara mandiri, lalu diperiksa terhadap sumber matematis yang disebutkan di akhir bab.

Peran tranche ini terbatas dan dapat diuji: menghubungkan operator proksimal dengan oracle stokastik; membuktikan pengurangan varians minibatch dengan dan tanpa penggantian; mengembangkan penurunan cermin stokastik dalam geometri Bregman; serta menempatkan penaksir SAGA yang telah diterima ke dalam langkah proksimal komposit tanpa mengklaim teorema yang belum dibuktikan.

Tidak ada prosa matematis, gambar, latihan, solusi, atau kode laboratorium pihak ketiga yang disalin. Infrastruktur pembaca memakai salinan persis shinybook.cls yang dibundel dengan sumber Habring dan adaptasi Indonesia macros-id.tex dari macros.tex milik Habring; keduanya dipertahankan berdasarkan bukti lisensi CC BY 4.0 pada tingkat kiriman arXiv dan tidak dilisensikan ulang sebagai CC BY-SA; shinybook.cls sendiri tidak memuat pemberitahuan lisensi terpisah. Prakata sumber Habring mengakui templat Christian Clason, dan kredit tersebut dipertahankan di sini. Catatan Royer berlisensi CC BY-NC 4.0 dan material sumber lain mempertahankan hak masing-masing; semuanya dipakai hanya sebagai saksi verifikasi dan rujukan matematis. Seluruh teks substantif dan kode laboratorium baru tranche ini tersedia berdasarkan CC BY-SA 4.0. Ini adalah edisi mandiri dan tidak menyiratkan dukungan pihak yang dirujuk.

Provenans produksi dan QA: OpenAI Codex gpt-5.6-sol, Ultra, atas instruksi pengguna repositori. Seluruh kredit penulis dan kontributor manusia pada sumber pendamping tetap dipertahankan.

Metode Stokastik Komposit, Cermin, dan Minibatch

Bab ini mengisi penghubung yang belum tersedia di tulang punggung Habring dan tiga modul Becker yang telah diterima. Habring telah mengembangkan operator proksimal, gradien proksimal deterministik, dan subgradien stokastik terproyeksi. Modul Becker 3 telah membuktikan ketakbiasan penaksir SAGA dan identitas varians tabelnya. Yang masih diperlukan ialah satu kerangka yang menjelaskan bagaimana operator proksimal, geometri non-Euklides, pengambilan sampel minibatch, dan reduksi varians saling terhubung.

Seluruh rumusan, bukti penghubung, latihan, petunjuk, solusi, dan laboratorium dalam bab ini ditulis secara mandiri. Catatan Habring, catatan gradien stokastik Clément W. Royer, modul Becker 3, serta rujukan penelitian pada akhir bab dipakai untuk memeriksa istilah, batas teori, dan konteks; tidak ada prosa, tata letak, gambar, atau kode mereka yang disalin.

Kita memakai norma \(\left\lVert \cdot\right\rVert\) pada ruang berdimensi hingga dan norma dual \[\begin{equation} \left\lVert y\right\rVert_*=\sup_{\left\lVert x\right\rVert\leq1}\left\langle y,x\right\rangle. \end{equation}\] Untuk bagian proksimal dan minibatch, norma tersebut adalah norma Euklides. Filtrasi \(\mathcal F_k\) memuat seluruh informasi sebelum oracle pada iterasi \(k\) dipanggil. Dengan demikian, \(x_k\) terukur terhadap \(\mathcal F_k\).

Masalah komposit dan oracle stokastik

Pertimbangkan masalah komposit \[\begin{equation} \label{orig01:eq:composite-problem} \min_{x\in\mathbb{R}^d} F(x), \qquad F(x)=f(x)+g(x), \end{equation}\] dengan \(f:\mathbb{R}^d\to\mathbb{R}\) konveks, terdiferensialkan, dan mempunyai gradien \(L\)-Lipschitz, sedangkan \(g:\mathbb{R}^d\to(-\infty,+\infty]\) proper, konveks, dan semikontinu bawah. Andaikan himpunan peminim \(X^*=\arg\min F\) tidak kosong.

Oracle pada \(x_k\) mengembalikan \(G_k\) dan memenuhi, hampir pasti, \[\begin{equation} \label{orig01:eq:oracle} \mathbb{E}[G_k\mid\mathcal F_k]=\nabla f(x_k), \qquad \mathbb{E}\!\left[\left\lVert G_k-\nabla f(x_k)\right\rVert^2\mid\mathcal F_k\right] \leq \nu_k^2. \end{equation}\] Besaran \(\nu_k^2\) boleh berubah sepanjang iterasi. Notasi ini sengaja memisahkan varians oracle dari konstanta kemulusan \(L\) dan dari fungsi kerugian \(\ell\) pada model statistik.

Gradien proksimal stokastik

Dengan ukuran langkah \(\tau_k>0\), pembaruan gradien proksimal stokastik ialah \[\begin{equation} \label{orig01:eq:spg-update} x_{k+1} =\operatorname{prox}_{\tau_k g}\bigl(x_k-\tau_kG_k\bigr). \end{equation}\] Jika \(g=\delta_C\) adalah fungsi indikator himpunan konveks tertutup \(C\), pembaruan ini menjadi proyeksi stokastik. Jika \(g(x)=\lambda\left\lVert x\right\rVert_1\), pembaruan ini menjadi ambang lunak setelah langkah gradien stokastik.

Algoritma 1: gradien proksimal stokastik. Pilih \(x_0\in\operatorname{dom}g\). Untuk \(k=0,1,\dots\), panggil oracle pada \(x_k\) untuk memperoleh \(G_k\), pilih \(\tau_k\), lalu hitung (3). Untuk pelaporan ergodik, simpan rerata iterat yang disebutkan dalam teorema berikut.

Lemma (Ketaksamaan satu langkah).

Ambil \(x\in\operatorname{dom}g\) dan tetapkan \(\tau_k=\tau\) dengan \(0<\tau\leq(2L)^{-1}\). Di bawah (2), iterasi (3) memenuhi \[\begin{multline} \label{orig01:eq:spg-one-step} \mathbb{E}[F(x_{k+1})-F(x)\mid\mathcal F_k]\ \leq \frac{\left\lVert x_k-x\right\rVert^2- \mathbb{E}[\left\lVert x_{k+1}-x\right\rVert^2\mid\mathcal F_k]}{2\tau} +\tau\nu_k^2. \end{multline}\]

Bukti. Tuliskan \(x^+=x_{k+1}\), \(s=x^+-x_k\), dan \(\delta_k=G_k-\nabla f(x_k)\). Kondisi optimalitas proks memberikan \[\begin{equation} \frac{x_k-x^+}{\tau}-G_k\in\partial g(x^+). \end{equation}\] Ketaksamaan subgradien untuk \(g\), kekonveksan \(f\), dan lemma penurunan untuk \(f\) yang \(L\)-mulus menghasilkan \[\begin{multline} F(x^+)-F(x) \leq \frac{\left\lVert x_k-x\right\rVert^2-\left\lVert x^+-x\right\rVert^2}{2\tau} -\frac{1-L\tau}{2\tau}\left\lVert s\right\rVert^2 -\left\langle \delta_k,x^+-x\right\rangle. \label{orig01:eq:spg-pathwise} \end{multline}\] Pecah suku terakhir sebagai \(-\left\langle \delta_k,s\right\rangle-\left\langle \delta_k,x_k-x\right\rangle\). Karena \(x_k-x\) terukur terhadap \(\mathcal F_k\) dan \(\mathbb{E}[\delta_k\mid\mathcal F_k]=0\), suku kedua hilang dalam ekspektasi bersyarat. Untuk suku pertama, maksimisasi kuadrat atau ketaksamaan Young memberi \[\begin{equation} -\left\langle \delta_k,s\right\rangle -\frac{1-L\tau}{2\tau}\left\lVert s\right\rVert^2 \leq\frac{\tau}{2(1-L\tau)}\left\lVert \delta_k\right\rVert^2 \leq\tau\left\lVert \delta_k\right\rVert^2, \end{equation}\] dengan ketaksamaan terakhir menggunakan \(\tau L\leq1/2\). Mengambil ekspektasi bersyarat membuktikan klaim. ◻

Teorema (Batas ergodik proksimal stokastik).

Andaikan \(\nu_k^2\leq\sigma^2/b\) untuk semua \(k\), dengan \(b\geq1\). Ambil \(x^*\in X^*\), \(0<\tau\leq(2L)^{-1}\), dan definisikan \[\begin{equation} \bar x_K=\frac1K\sum_{k=0}^{K-1}x_{k+1}. \end{equation}\] Maka, untuk \(K\geq1\), \[\begin{equation} \label{orig01:eq:spg-ergodic-rate} \mathbb{E}[F(\bar x_K)-F(x^*)] \leq \frac{\left\lVert x_0-x^*\right\rVert^2}{2\tau K} +\frac{\tau\sigma^2}{b}. \end{equation}\]

Bukti. Terapkan Lema Ketaksamaan satu langkah dengan \(x=x^*\), ambil ekspektasi penuh, lalu jumlahkan untuk \(k=0,\dots,K-1\). Suku jarak meneleskop dan suku terakhir yang tidak negatif dapat dibuang. Kekonveksan \(F\) memberi \(F(\bar x_K)\leq K^{-1}\sum_{k=0}^{K-1}F(x_{k+1})\), yang menyelesaikan bukti. ◻

Jika \(R=\left\lVert x_0-x^*\right\rVert>0\), \(\sigma>0\), dan batas kemulusan tidak aktif, pilihan yang menyeimbangkan kedua suku pada (6) ialah \[\begin{equation} \tau=R\sqrt{\frac{b}{2\sigma^2K}}, \qquad \mathbb{E}[F(\bar x_K)-F(x^*)] \leq\frac{\sqrt2R\sigma}{\sqrt{bK}}. \end{equation}\] Dalam praktik, \(R\) dan \(\sigma\) biasanya tidak diketahui. Rumus ini adalah penjelas skala, bukan resep penalaan tanpa diagnosis.

Minibatch: identitas varians dan biaya oracle

Ambil \(b\) sampel bersyarat iid \(G_{k,1},\dots,G_{k,b}\) dengan rerata \(\nabla f(x_k)\) dan varians kuadrat paling besar \(\sigma^2\). Penaksir minibatch dengan penggantian adalah \[\begin{equation} \label{orig01:eq:minibatch} \widehat G_k^{(b)}=\frac1b\sum_{j=1}^{b}G_{k,j}. \end{equation}\]

Proposisi (Penyusutan varians dengan penggantian).

Penaksir (7) tak bias dan memenuhi \[\begin{equation} \mathbb{E}\!\left[ \left\lVert \widehat G_k^{(b)}-\nabla f(x_k)\right\rVert^2 \mid\mathcal F_k \right]\leq\frac{\sigma^2}{b}. \end{equation}\]

Bukti. Setelah dikondisikan pada \(\mathcal F_k\), simpangan setiap sampel mempunyai rerata nol dan pasangan simpangan yang berbeda saling bebas. Semua suku silang dalam kuadrat norma mempunyai ekspektasi nol. Tersisa \(b\) suku diagonal yang masing-masing dikalikan \(b^{-2}\). ◻

Untuk jumlah hingga \(f=N^{-1}\sum_{i=1}^{N}f_i\), pengambilan sampel tanpa penggantian mempunyai koreksi populasi hingga yang tidak boleh disamakan dengan rumus iid.

Proposisi (Koreksi populasi hingga).

Andaikan \(N\geq2\) dan \(1\leq b\leq N\). Pada suatu \(x\), tuliskan \(h_i=\nabla f_i(x)-\nabla f(x)\) dan \(V_N=N^{-1}\sum_{i=1}^{N}\left\lVert h_i\right\rVert^2\). Jika \(S\) dipilih seragam dari semua subhimpunan berukuran \(b\) tanpa penggantian, maka \[\begin{equation} \label{orig01:eq:finite-population} \mathbb{E}\left\lVert \frac 1b\sum_{i\in S}\nabla f_i(x)-\nabla f(x)\right\rVert^2 =\frac{N-b}{b(N-1)}V_N. \end{equation}\]

Bukti. Peluang inklusi satu indeks adalah \(b/N\) dan peluang inklusi dua indeks berbeda adalah \(b(b-1)/(N(N-1))\). Kembangkan kuadrat norma. Karena \(\sum_i h_i=0\), berlaku \(\sum_{i\ne j}\left\langle h_i,h_j\right\rangle=-\sum_i\left\lVert h_i\right\rVert^2\). Substitusi kedua peluang inklusi lalu penyederhanaan memberikan faktor pada (8). Khusus \(b=N\), varians tepat nol. ◻

Minibatch menurunkan varians per iterasi, tetapi memakai \(b\) evaluasi gradien komponen. Jika biaya serial yang tersedia adalah \(T=bK\), batas tertala ideal \(\sqrt2R\sigma/\sqrt{bK}\) menjadi \(\sqrt2R\sigma/\sqrt T\): tidak ada percepatan kompleksitas oracle hanya dari pengelompokan. Keuntungan nyata dapat datang dari paralelisme, arsitektur perangkat, pengurangan komunikasi, atau batas langkah yang lebih baik. Pernyataan ini juga menjelaskan mengapa perbandingan hanya berdasarkan banyak iterasi dapat menyesatkan.

Penurunan cermin stokastik

Proyeksi Euklides memperlakukan semua arah dengan geometri yang sama. Pada simpleks, matriks semidefinit positif, atau ruang dengan struktur sparsitas, pilihan geometri lain dapat lebih alami.

Misalkan \(X\subset\mathbb{R}^d\) tak kosong, tertutup, dan konveks. Ambil fungsi pembangkit \(h:X\to\mathbb{R}\) yang bernilai hingga dan kontinu pada \(X\), terdiferensialkan di setiap iterat, dan \(\alpha\)-konveks kuat terhadap \(\left\lVert \cdot\right\rVert\). Untuk setiap \(x\in X\) dan setiap titik keterdiferensialan \(y\), \[\begin{equation} h(x)\geq h(y)+\left\langle \nabla h(y),x-y\right\rangle +\frac\alpha2\left\lVert x-y\right\rVert^2. \end{equation}\] Divergensi Bregman yang dibangkitkan oleh \(h\) ialah \[\begin{equation} \label{orig01:eq:bregman} D_h(x,y)=h(x)-h(y)-\left\langle \nabla h(y),x-y\right\rangle. \end{equation}\] Divergensi ini tidak harus simetris dan bukan metrik, tetapi \(D_h(x,y)\geq(\alpha/2)\left\lVert x-y\right\rVert^2\).

Untuk fungsi konveks \(\Phi:X\to\mathbb{R}\), andaikan oracle menghasilkan \(G_k\) dengan \[\begin{equation} \label{orig01:eq:mirror-oracle} \bar G_k\coloneqq\mathbb{E}[G_k\mid\mathcal F_k]\in\partial\Phi(x_k), \qquad \mathbb{E}[\left\lVert G_k\right\rVert_*^2\mid\mathcal F_k]\leq M^2. \end{equation}\] Ambil \(\tau_k>0\) dan andaikan masalah berikut hampir pasti mencapai peminim unik \(x_{k+1}\) pada titik keterdiferensialan \(h\): \[\begin{equation} \label{orig01:eq:mirror-update} x_{k+1}=\arg\min_{x\in X} \left\{\tau_k\left\langle G_k,x\right\rangle+D_h(x,x_k)\right\}. \end{equation}\] Untuk pembanding optimum \(x^*\) yang dipakai di bawah, andaikan pula \(D_h(x^*,x_0)<\infty\). Asumsi eksplisit ini dapat diganti dengan syarat Legendre/interior standar yang menjamin sifat-sifat yang sama.

Algoritma 2: penurunan cermin stokastik. Pilih \(x_0\) dalam daerah terdiferensialkan \(h\). Pada iterasi \(k\), ambil subgradien stokastik \(G_k\), selesaikan masalah Bregman (11), dan perbarui rerata berbobot \(\sum_j\tau_jx_j/\sum_j\tau_j\).

Lemma (Ketaksamaan tiga titik stokastik).

Untuk setiap \(x\in X\), pembaruan (11) memenuhi \[\begin{equation} \label{orig01:eq:mirror-one-step} \tau_k\left\langle G_k,x_k-x\right\rangle \leq D_h(x,x_k)-D_h(x,x_{k+1}) +\frac{\tau_k^2}{2\alpha}\left\lVert G_k\right\rVert_*^2. \end{equation}\]

Bukti. Kondisi optimalitas pada himpunan \(X\) memberi \[\begin{equation} \left\langle \tau_kG_k+\nabla h(x_{k+1})-\nabla h(x_k),x-x_{k+1}\right\rangle\geq0. \end{equation}\] Identitas tiga titik Bregman mengubah bagian yang memuat \(h\) menjadi \[\begin{equation} \tau_k\left\langle G_k,x_{k+1}-x\right\rangle \leq D_h(x,x_k)-D_h(x,x_{k+1})-D_h(x_{k+1},x_k). \end{equation}\] Tambahkan \(\tau_k\left\langle G_k,x_k-x_{k+1}\right\rangle\) pada kedua sisi. Gunakan \(D_h(x_{k+1},x_k)\geq(\alpha/2)\left\lVert x_{k+1}-x_k\right\rVert^2\), dualitas norma, dan ketaksamaan Young. Hasilnya tepat (12). ◻

Teorema (Batas ergodik cermin stokastik).

Di bawah (10), untuk \(K\geq1\) definisikan \(S_K=\sum_{k=0}^{K-1}\tau_k\) dan \[\begin{equation} \widetilde x_K=\frac1{S_K}\sum_{k=0}^{K-1}\tau_kx_k. \end{equation}\] Untuk setiap \(x^*\in\arg\min_{x\in X}\Phi(x)\), \[\begin{equation} \label{orig01:eq:mirror-rate} \mathbb{E}[\Phi(\widetilde x_K)-\Phi(x^*)] \leq \frac{D_h(x^*,x_0)}{S_K} +\frac{M^2}{2\alpha} \frac{\sum_{k=0}^{K-1}\tau_k^2}{S_K}. \end{equation}\]

Bukti. Ambil ekspektasi bersyarat pada Lema Ketaksamaan tiga titik stokastik. Karena \(x_k-x^*\) terukur terhadap \(\mathcal F_k\) dan \(\bar G_k\in\partial\Phi(x_k)\), \[\begin{equation} \mathbb{E}[\left\langle G_k,x_k-x^*\right\rangle\mid\mathcal F_k] \geq\Phi(x_k)-\Phi(x^*). \end{equation}\] Jumlahkan sehingga divergensi Bregman meneleskop, lalu gunakan kekonveksan \(\Phi\) pada rerata berbobot. ◻

Untuk \(M>0\) dan \(D_h(x^*,x_0)>0\), gunakan \(\tau=\sqrt{2\alpha D_h(x^*,x_0)/(M^2K)}\). Ruas kanan kemudian menjadi \[\begin{equation} M\sqrt{\frac{2D_h(x^*,x_0)}{\alpha K}}. \end{equation}\] Pada geometri Euklides, \(h(x)=\left\lVert x\right\rVert_2^2/2\) dan pembaruan cermin menjadi subgradien stokastik terproyeksi. Jadi metode cermin memperluas, bukan menduplikasi, teorema stokastik Habring.

Simpleks dan pembaruan eksponensial

Pada simpleks \(\Delta_d=\{x\in\mathbb{R}_+^d:\sum_{j=1}^{d}x_j=1\}\), ambil \(h(x)=\sum_jx_j\log x_j\), dengan konvensi perluasan kontinu \(0\log0=0\). Fungsi ini kontinu pada \(\Delta_d\) dan terdiferensialkan pada interior relatifnya. Mulai dari \(x_{0,j}>0\). Divergensi Bregman ialah divergensi Kullback–Leibler. Terhadap norma \(\ell_1\), fungsi ini \(1\)-konveks kuat. Kondisi optimalitas memberi pembaruan tertutup \[\begin{equation} \label{orig01:eq:exponentiated-update} x_{k+1,j} =\frac{x_{k,j}\exp(-\tau_kG_{k,j})} {\sum_{r=1}^{d}x_{k,r}\exp(-\tau_kG_{k,r})}. \end{equation}\] Jika \(x_0\) seragam, maka \(D_h(x^*,x_0)\leq\log d\). Dengan batas \(\left\lVert G_k\right\rVert_\infty\leq M\), Teorema Batas ergodik cermin stokastik memberi skala \(M\sqrt{2\log(d)/K}\) setelah penalaan ideal. Ketergantungan logaritmik pada dimensi menjelaskan kegunaan geometri entropi di simpleks.

Dari SAGA ke pembaruan proksimal

Untuk masalah jumlah hingga \(f=N^{-1}\sum_i f_i\), modul Becker 3 mendefinisikan penaksir SAGA \[\begin{equation} v_k=\nabla f_{J_k}(x_k)-g_{J_k}^k+\bar g_k \end{equation}\] dan membuktikan \(\mathbb{E}[v_k\mid\mathcal F_k]=\nabla f(x_k)\). Untuk masalah komposit, perubahan algoritmik yang benar bukan mengurangkan subgradien \(g\), melainkan memakai langkah proksimal \[\begin{equation} \label{orig01:eq:prox-saga} x_{k+1}=\operatorname{prox}_{\tau g}(x_k-\tau v_k). \end{equation}\]

Korolari (Penghubung varians untuk Prox-SAGA).

Andaikan asumsi masalah komposit berlaku, \(0<\tau\leq(2L)^{-1}\), dan definisikan \[\begin{equation} \omega_k^2 =\mathbb{E}[\left\lVert v_k-\nabla f(x_k)\right\rVert^2\mid\mathcal F_k]. \end{equation}\] Untuk \(\bar x_K=K^{-1}\sum_{k=0}^{K-1}x_{k+1}\) dan \(x^*\in X^*\), \[\begin{equation} \label{orig01:eq:prox-saga-bridge} \mathbb{E}[F(\bar x_K)-F(x^*)] \leq\frac{\left\lVert x_0-x^*\right\rVert^2}{2\tau K} +\frac{\tau}{K}\sum_{k=0}^{K-1}\mathbb{E}[\omega_k^2]. \end{equation}\] Jika \(\mathbb{E}[\omega_k^2]\leq C\rho^k\) dengan \(C\geq0\) dan \(0<\rho<1\), maka \[\begin{equation} \mathbb{E}[F(\bar x_K)-F(x^*)] \leq\frac{\left\lVert x_0-x^*\right\rVert^2}{2\tau K} +\frac{\tau C}{K(1-\rho)}. \end{equation}\]

Bukti. Terapkan bukti Teorema Batas ergodik proksimal stokastik dengan \(G_k=v_k\) dan varians bersyarat \(\omega_k^2\). Untuk klaim terakhir, gunakan jumlah deret geometri hingga yang dibatasi oleh \((1-\rho)^{-1}\). ◻

Korolari ini menjelaskan hubungan yang hilang, tetapi sengaja tidak mengklaim bahwa varians SAGA selalu turun geometrik. Pembuktian klaim semacam itu memerlukan fungsi Lyapunov gabungan untuk galat iterat dan galat tabel. Teorema laju linear bersyarat pada modul Becker 3 menyediakan hasil khusus untuk kasus mulus dan konveks kuat; korolari di sini menunjukkan bagaimana penaksir yang sama masuk ke masalah komposit.

Laboratorium 1: regresi renggang dengan biaya oracle tetap

Laboratorium terbuka pada labs/original-01/stochastic-composite-lab.py membangun masalah regresi kuadrat dengan regularisasi \(\ell_1\), \[\begin{equation} \label{orig01:eq:lab-objective} F(x)=\frac{1}{2N}\left\lVert Ax-y\right\rVert_2^2+\lambda\left\lVert x\right\rVert_1. \end{equation}\] Skrip membandingkan gradien proksimal stokastik, minibatch dengan penggantian, dan Prox-SAGA pada anggaran evaluasi gradien komponen yang sama. Referensi numerik dihitung oleh FISTA deterministik sampai norma pemetaan gradien proksimal memenuhi toleransi yang dilaporkan.

Tugas laboratorium:

  1. jalankan skrip tanpa mengubah benih acak dan verifikasikan konfigurasi beku yang dicatat pada berkas hasil;

  2. bandingkan kesenjangan objektif terhadap evaluasi gradien komponen, bukan hanya terhadap iterasi;

  3. periksa apakah minibatch menurunkan varians arah pada checkpoint yang sama;

  4. ubah ukuran minibatch tetapi pertahankan anggaran oracle, lalu jelaskan perbedaan antara keuntungan statistik dan keuntungan paralel;

  5. ganti \(\lambda\) dan ukur perubahan sparsitas serta norma pemetaan gradien proksimal;

  6. laporkan setiap hasil yang bertentangan dengan batas teori beserta asumsi yang mungkin tidak terpenuhi.

CSV dan JSON yang dihasilkan adalah permukaan aksesibel utama. Grafik SVG hanya merupakan bantuan visual dan tidak menjadi satu-satunya pembawa informasi.

Dengan konfigurasi beku (\(N=320\), \(d=40\), \(\lambda=0{,}03\), 12 epoch, dan 3.840 evaluasi gradien komponen per metode), nilai referensi FISTA adalah \(0{,}31517396778742246\) dengan norma pemetaan gradien proksimal \(1{,}49\times10^{-15}\). Hasil terminal deterministik adalah:

Metode Kesenjangan objektif Norma pemetaan Tak nol
Proks-SGD, \(b=1\) \(4{,}9169\times10^{-2}\) \(2{,}1155\times10^{-2}\) 33
Proks-minibatch, \(b=16\) \(2{,}5707\times10^{-3}\) \(9{,}8630\times10^{-3}\) 10
Prox-SAGA \(2{,}0444\times10^{-9}\) \(9{,}8666\times10^{-6}\) 5

Angka tersebut adalah satu eksperimen terkontrol, bukan urutan kinerja universal. Berkas hasil JSON, CSV, dan SVG mempunyai SHA-256 berikut:

86ff701a…c447
61a6591a…5d37
87c772d9…2830.

Identitas lengkap dicatat dalam receipt QA.

Latihan, petunjuk, dan solusi lengkap

Latihan (Pembaruan proksimal untuk Lasso).

Untuk \(f(x)=(2N)^{-1}\left\lVert Ax-y\right\rVert_2^2\) dan \(g(x)=\lambda\left\lVert x\right\rVert_1\), tuliskan pembaruan (3) ketika minibatch \(S_k\) dipakai. Tunjukkan bahwa setiap koordinat diperoleh dengan ambang lunak.

Petunjuk bertahap. (i) Hitung gradien setiap suku kuadrat. (ii) Gunakan keterpisahan norma \(\ell_1\). (iii) Selesaikan masalah proksimal skalar pada tiga kasus tanda.

Solusi lengkap. Jika \(f_i(x)=\tfrac12(a_i^\top x-y_i)^2\), maka \[\begin{equation} G_k=\frac1{|S_k|}\sum_{i\in S_k}a_i(a_i^\top x_k-y_i). \end{equation}\] Tuliskan \(z_k=x_k-\tau_kG_k\). Karena \(\operatorname{prox}_{\tau_k\lambda\left\lVert \cdot\right\rVert_1}\) terpisah per koordinat, \[\begin{equation} (x_{k+1})_j =\operatorname{sign}((z_k)_j) \max\{|(z_k)_j|-\tau_k\lambda,0\}. \end{equation}\] Rumus ini mengikuti dengan memeriksa kondisi \(0\in u-z+\tau_k\lambda\partial|u|\) pada \(u>0\), \(u<0\), dan \(u=0\).

Latihan (Konstanta pada ketaksamaan satu langkah).

Mulai dari (5). Buktikan batas yang lebih tajam \[\begin{equation} \mathbb{E}[F(x_{k+1})-F(x)\mid\mathcal F_k] \leq\frac{\left\lVert x_k-x\right\rVert^2- \mathbb{E}\left\lVert x_{k+1}-x\right\rVert^2}{2\tau} +\frac{\tau\nu_k^2}{2(1-L\tau)} \end{equation}\] untuk \(0<\tau<L^{-1}\).

Petunjuk bertahap. (i) Maksimalkan \(-\left\langle \delta,s\right\rangle-c\left\lVert s\right\rVert^2\) terhadap \(s\). (ii) Ambil \(c=(1-L\tau)/(2\tau)\). (iii) Gunakan ketakbiasan hanya setelah memisahkan \(x_k-x\).

Solusi lengkap. Dualitas norma Euklides dan pelengkapan kuadrat memberikan \[\begin{equation} \sup_s\{-\left\langle \delta,s\right\rangle-c\left\lVert s\right\rVert^2\} =\frac{\left\lVert \delta\right\rVert^2}{4c} =\frac{\tau\left\lVert \delta\right\rVert^2}{2(1-L\tau)}. \end{equation}\] Suku \(-\left\langle \delta_k,x_k-x\right\rangle\) mempunyai ekspektasi bersyarat nol. Substitusi batas varians menyelesaikan klaim. Lema utama memakai \(\tau L\leq1/2\) hanya untuk mengganti faktor ini dengan batas sederhana \(\tau\nu_k^2\).

Latihan (Sampel tanpa penggantian).

Untuk \(N\geq2\), buktikan Proposisi Koreksi populasi hingga dengan peubah indikator \(I_i=\mathbf1\{i\in S\}\). Periksa kasus \(b=1\) dan \(b=N\).

Petunjuk bertahap. (i) Gunakan \(\mathbb{E}I_i=b/N\). (ii) Untuk \(i\ne j\), gunakan \(\mathbb{E}[I_iI_j]=b(b-1)/(N(N-1))\). (iii) Pakai \(\sum_i h_i=0\).

Solusi lengkap. Karena \(b^{-1}\sum_{i\in S}h_i=b^{-1}\sum_iI_ih_i\), ekspektasi kuadrat normanya adalah \[\begin{multline} \frac1{b^2}\left[ \frac bN\sum_i\left\lVert h_i\right\rVert^2 +\frac{b(b-1)}{N(N-1)} \sum_{i\ne j}\left\langle h_i,h_j\right\rangle \right]. \end{multline}\] Suku silang sama dengan \(-\sum_i\left\lVert h_i\right\rVert^2\). Koefisien akhirnya \((N-b)/(bN(N-1))\), dan penggantian \(\sum_i\left\lVert h_i\right\rVert^2=NV_N\) memberi rumus yang diminta. Untuk \(b=1\) faktor menjadi satu; untuk \(b=N\) menjadi nol.

Latihan (Cermin entropi pada simpleks).

Turunkan (14) dari (11). Jelaskan mengapa iterat yang mulai positif tetap positif dan berjumlah satu.

Petunjuk bertahap. (i) Tambahkan pengali Lagrange untuk \(\sum_jx_j=1\). (ii) Diferensialkan terhadap setiap \(x_j\). (iii) Gunakan kendala jumlah untuk menentukan faktor normalisasi.

Solusi lengkap. Dengan konvensi \(0\log0=0\) dan \(D_h(x,x_k)=\sum_jx_j\log(x_j/x_{k,j})\) pada simpleks, kondisi stasioner adalah \[\begin{equation} \tau_kG_{k,j}+\log(x_j/x_{k,j})+1+\eta=0. \end{equation}\] Jadi \(x_j=x_{k,j}\exp(-\tau_kG_{k,j})\exp(-1-\eta)\). Menjumlahkan seluruh koordinat menunjukkan bahwa faktor terakhir adalah kebalikan jumlah pada penyebut (14). Eksponensial dan penyebut positif mempertahankan kepositifan, sedangkan normalisasi mempertahankan jumlah satu.

Latihan (Anggaran oracle dan ukuran minibatch).

Andaikan batas tertala ideal adalah \(\sqrt2R\sigma/\sqrt{bK}\) dan satu iterasi minibatch memakai \(b\) evaluasi gradien komponen. Untuk anggaran serial \(T=bK\), tentukan ketergantungannya pada \(b\). Sebutkan dua keadaan ketika minibatch tetap berguna.

Petunjuk bertahap. (i) Ganti \(K\) dengan \(T/b\). (ii) Bedakan waktu dinding dari jumlah panggilan oracle. (iii) Perhatikan pengambilan sampel tanpa penggantian.

Solusi lengkap. Substitusi memberi \[\begin{equation} \frac{\sqrt2R\sigma}{\sqrt{b(T/b)}} =\frac{\sqrt2R\sigma}{\sqrt T}, \end{equation}\] yang bebas dari \(b\). Jadi model ideal tidak memprediksi penghematan evaluasi gradien serial. Minibatch tetap berguna jika evaluasi dapat diparalelkan atau komunikasi dapat diamortisasi; ia juga dapat membantu melalui koreksi populasi hingga tanpa penggantian, vektorisasi perangkat, atau batas langkah yang tidak tercakup dalam model sederhana.

Latihan (Varians yang menyusut pada Prox-SAGA).

Mulai dari (16). Jika \(\mathbb{E}\omega_k^2\leq C/(k+1)\), turunkan batas eksplisit menggunakan bilangan harmonik \(H_K=\sum_{j=1}^{K}j^{-1}\). Bandingkan dengan kasus geometrik.

Petunjuk bertahap. (i) Jumlahkan batas varians. (ii) Gunakan \(H_K\leq1+\log K\). (iii) Jangan menyimpulkan laju iterat terakhir dari batas ergodik.

Solusi lengkap. Substitusi langsung memberi \[\begin{equation} \mathbb{E}[F(\bar x_K)-F(x^*)] \leq\frac{\left\lVert x_0-x^*\right\rVert^2}{2\tau K} +\frac{\tau C H_K}{K} \leq\frac{\left\lVert x_0-x^*\right\rVert^2}{2\tau K} +\frac{\tau C(1+\log K)}{K}. \end{equation}\] Peluruhan geometrik menjadikan jumlah varians terbatas secara seragam dan menghasilkan \(\mathcal{O}(1/K)\) tanpa faktor logaritmik. Kedua kesimpulan hanya berlaku untuk rerata \(\bar x_K\) dalam korolari ini; laju iterat terakhir memerlukan analisis tambahan.

Peta asumsi dan batas klaim

Hasil Asumsi penentu Yang tidak diklaim
Proksimal stokastik \(f\) konveks dan \(L\)-mulus; \(g\) proper, tertutup, konveks; oracle tak bias; varians terbatas laju iterat terakhir atau konvergensi nonkonveks
Minibatch iid sampel bersyarat bebas dengan penggantian koreksi populasi hingga
Minibatch tanpa penggantian subhimpunan seragam berukuran \(1\leq b\leq N\) dari populasi dengan \(N\geq2\) independensi antaranggota batch
Cermin stokastik pembangkit \(\alpha\)-konveks kuat; pembaruan terdefinisi; \(D_h(x^*,x_0)<\infty\); momen dual kedua terbatas simetri divergensi Bregman
Prox-SAGA penghubung ketakbiasan SAGA dan kontrol varians yang dinyatakan peluruhan geometrik varians tanpa Lyapunov

Bab ini tidak membahas ketaksamaan variasional atau operator monoton maksimal; materi tersebut adalah tranche asli berikutnya. Bab ini juga tidak mengulang LP/MIP, simpleks sebagai algoritma pemrograman linear, dualitas LP, sensitivitas LP, jaringan, atau optimisasi diskret yang merupakan cakupan O018. Kata simpleks di sini hanya menunjuk himpunan probabilitas \(\Delta_d\).

Rujukan matematis dan saksi verifikasi

  • Andreas Habring, Lecture Notes: Convex Optimization, arXiv:2607.11664v1, khususnya operator proksimal dan subgradien stokastik.

  • Clément W. Royer, Lecture Notes on Stochastic Gradient Methods, edisi 2023/2024, khususnya pembahasan minibatch dan biaya epoch; dipakai sebagai saksi perbandingan, bukan sumber prosa bab ini.

  • Lorenzo Rosasco, Silvia Villa, dan Bang Công Vũ, Convergence of Stochastic Proximal Gradient Algorithm, arXiv:1403.5074, sebagai rujukan primer bagi keluarga metode proksimal stokastik.

  • Amir Beck dan Marc Teboulle, Mirror Descent and Nonlinear Projected Subgradient Methods for Convex Optimization, Operations Research Letters 31 (2003), 167–175, DOI:10.1016/S0167-6377(02)00231-6.

  • Aaron Defazio, Francis Bach, dan Simon Lacoste-Julien, SAGA: A Fast Incremental Gradient Method With Support for Non-Strongly Convex Composite Objectives, arXiv:1407.0202v3.

Lampiran laboratorium lengkap

Lampiran ini membawa kode dan keluaran beku laboratorium ke permukaan baca reflow. Empat berkas asli disertakan sebagai unduhan byte-identik pada HTML dan sebagai sumber daya termanifestasi pada EPUB; tautan EPUB menuju representasi lengkap di dalam pembaca. Tabel dan grafik bersifat redundan: data lengkap tetap tersedia dalam CSV dan JSON.

Grafik kesenjangan objektif

Grafik logaritmik kesenjangan objektif terhadap jumlah evaluasi gradien komponen untuk Proks-SGD, Proks-minibatch, dan Prox-SAGA; seluruh nilai tersedia dalam tabel data lengkap, CSV, dan JSON.
Kesenjangan objektif terhadap evaluasi gradien komponen. Seluruh nilai tersedia dalam tabel data lengkap, CSV, dan JSON.

Tabel data lengkap

Seluruh 38 baris hasil laboratorium dengan biaya oracle tetap
methodcomponent_gradient_evaluationsepochsobjectiveobjective_gapprox_gradient_mapping_normnonzero_coordinatesdirection_variance_trace
prox_sgd_b100.00.55133623168075810.23616226389333560.1083285579496747601.1468193719792907
prox_sgd_b13201.00.37021754820522960.055043580417807160.021444123030821837350.20287630148456232
prox_sgd_b16402.00.34569104358974780.0305170758023253220.018590943751343902260.2049691821609164
prox_sgd_b19603.00.352612416713872450.0374384489264499850.01936197482100853340.2519231892272348
prox_sgd_b112804.00.368119371699590860.05294540391216840.029796229670094147340.13168723150568945
prox_sgd_b116005.00.34406045974310730.0288864919556848230.01772940293189908320.17837355463918506
prox_sgd_b119206.00.367304004246453540.052130036459031080.022939657645467362360.1855969433395085
prox_sgd_b122407.00.339674645116602450.0245006773291799870.012560809370328175280.20583985615470013
prox_sgd_b125608.00.332771697991128050.0175977302037055860.013759461627893042220.21181935832129542
prox_sgd_b128809.00.342241730836037370.0270677630486149120.015798406128366645280.27433629954292693
prox_sgd_b1320010.00.35396514270667470.0387911749192522140.020535508430316735350.16457694344643045
prox_sgd_b1352011.00.344888725645687070.0297147578582646070.016623659246199234330.2108599340100843
prox_sgd_b1384012.00.36434304376408750.049169075976665030.021155328208993934330.26136164865160183
prox_minibatch_b1600.00.55133623168075810.23616226389333560.1083285579496747600.07167621074870567
prox_minibatch_b163201.00.478029840930646770.16285587314322430.08798911404534003190.05572471404755659
prox_minibatch_b166402.00.425750948732875170.110576980945452710.07263472377858442190.04530167691546953
prox_minibatch_b169603.00.393095569084267240.077921601296844780.05967953266400586270.03731134660361215
prox_minibatch_b1612804.00.36525068323220260.050076715444780150.04678905972517255260.029991266926131112
prox_minibatch_b1616005.00.347328097532568160.03215412974514570.038856894448275725170.02655369940668307
prox_minibatch_b1619206.00.338574223397136940.0234002556097144820.03232876621638514150.02411665732740852
prox_minibatch_b1622407.00.333131304973360960.0179573371859385040.026317750019252795180.021550879809775537
prox_minibatch_b1625608.00.32539964900289120.010225681215468740.021504470211626138110.01951610028110142
prox_minibatch_b1628809.00.321556124589033040.0063821568016105830.01623058440910809120.017903354865238353
prox_minibatch_b16320010.00.318639280914874260.00346531312745179680.01293714505555607870.017365712120880016
prox_minibatch_b16352011.00.31879317871120530.00361921092378286740.010395977334385874170.01643895223004758
prox_minibatch_b16384012.00.31774471266333510.0025707448759126340.009863014116815592100.01638661162760481
prox_saga3201.00.55133623168075810.23616226389333560.1083285579496747600.0
prox_saga6402.00.33646710791855160.021293140131129150.030882283903767606130.09782001800634663
prox_saga9603.00.321033182069177360.0058592142817548990.012180776828082843180.06029196457916808
prox_saga12804.00.315745006576055030.00057103878863257180.00515518136814555760.03248213576359973
prox_saga16005.00.31530738456428920.000133416776866734920.00233720285200673160.012430610167196843
prox_saga19206.00.31518316218568919.194398266632042e-060.000665788158391836950.003997002859597115
prox_saga22407.00.3151906356234811.6667836058525953e-050.000906906295689870150.001237648754466667
prox_saga25608.00.31517524431959451.2765321720231704e-060.000255973206412499658.69567909247325e-05
prox_saga28809.00.315174109770024751.4198260228637238e-078.335204162947475e-0552.0228054402838927e-05
prox_saga320010.00.31517408263284251.1484542006279241e-077.642797522666668e-0551.029106808858402e-05
prox_saga352011.00.315173987834191042.0046768578474428e-083.045036972269875e-0552.2866507233178645e-06
prox_saga384012.00.31517396983185942.0444369530636664e-099.866567454031472e-0654.5430827278459796e-07

Tabel berikut memuat semua baris hasil eksperimen dengan tajuk kolom yang dapat ditelusuri oleh teknologi bantu.

Berkas laboratorium byte-identik

  • stochastic-composite-lab.py — 13655 byte; SHA-256 21a0df89524b34916d1f659636bf8f92a5730efb7e263e0fbd7393e6f2c936fd
  • results.json — 2432 byte; SHA-256 86ff701a51d091ee74c110917cb1888c6e7448489207e6ee1372753bd1e4c447
  • results.csv — 4189 byte; SHA-256 61a6591ad7d1b41230a086482314448871f3697954d4c84133a7a5f4f775d37c
  • objective-gap.svg — 86616 byte; SHA-256 87c772d901ee734356981ee35f19fc3c3ae47fea6f11528edbee6d015a3f2830

Daftar berikut diikat oleh ukuran byte dan SHA-256. Pada HTML tautannya mengunduh berkas byte-identik; pada EPUB tautannya menuju representasi lengkap di dalam pembaca, sementara salinan byte-identik tetap termanifestasi.

Kode program Python lengkap

#!/usr/bin/env python3
"""Deterministic open-computation lab for O015 original tranche 1.

The experiment compares proximal SGD, proximal minibatch SGD, and Prox-SAGA
on an L1-regularized least-squares problem under a common component-gradient
evaluation budget. It writes accessible CSV/JSON results and a redundant SVG
plot. No network access or proprietary solver is required.

Original lab code and documentation: CC BY-SA 4.0
https://creativecommons.org/licenses/by-sa/4.0/
Produced by OpenAI Codex gpt-5.6-sol, Ultra, on the repository user's
instructions. Python, NumPy, and Matplotlib are unbundled runtime dependencies;
their own licenses remain unchanged. Cited researchers did not author this code.
"""

from __future__ import annotations

import csv
import hashlib
import json
import math
from pathlib import Path

import matplotlib

matplotlib.use("Agg")
matplotlib.rcParams["svg.hashsalt"] = "o015-original-01-20260825"
import matplotlib.pyplot as plt
import numpy as np


HERE = Path(__file__).resolve().parent
RESULT_JSON = HERE / "results.json"
RESULT_CSV = HERE / "results.csv"
RESULT_SVG = HERE / "objective-gap.svg"

SEED = 20260825
N = 320
D = 40
TRUE_NONZERO = 8
NOISE_STD = 0.08
LAMBDA = 0.03
EPOCHS = 12
BATCH_SIZE = 16
REFERENCE_MAX_ITER = 50000
REFERENCE_TOL = 1e-11


def sha256(path: Path) -> str:
    return hashlib.sha256(path.read_bytes()).hexdigest()


def soft_threshold(z: np.ndarray, threshold: float) -> np.ndarray:
    return np.sign(z) * np.maximum(np.abs(z) - threshold, 0.0)


def objective(a: np.ndarray, y: np.ndarray, x: np.ndarray) -> float:
    residual = a @ x - y
    return float(0.5 * residual @ residual / len(y) + LAMBDA * np.abs(x).sum())


def full_gradient(a: np.ndarray, y: np.ndarray, x: np.ndarray) -> np.ndarray:
    return a.T @ (a @ x - y) / len(y)


def component_gradient(
    a: np.ndarray, y: np.ndarray, x: np.ndarray, index: int
) -> np.ndarray:
    return a[index] * (a[index] @ x - y[index])


def prox_gradient_mapping_norm(
    a: np.ndarray, y: np.ndarray, x: np.ndarray, step: float
) -> float:
    mapped = soft_threshold(x - step * full_gradient(a, y, x), step * LAMBDA)
    return float(np.linalg.norm((x - mapped) / step))


def reference_fista(
    a: np.ndarray, y: np.ndarray, smooth_lipschitz: float
) -> tuple[np.ndarray, dict[str, float | int]]:
    step = 1.0 / smooth_lipschitz
    x = np.zeros(D)
    z = x.copy()
    t = 1.0
    mapping = math.inf
    iteration = 0
    for iteration in range(1, REFERENCE_MAX_ITER + 1):
        x_next = soft_threshold(
            z - step * full_gradient(a, y, z), step * LAMBDA
        )
        t_next = 0.5 * (1.0 + math.sqrt(1.0 + 4.0 * t * t))
        z = x_next + ((t - 1.0) / t_next) * (x_next - x)
        x = x_next
        t = t_next
        if iteration % 25 == 0:
            mapping = prox_gradient_mapping_norm(a, y, x, step)
            if mapping <= REFERENCE_TOL:
                break
    return x, {
        "iterations": iteration,
        "step": step,
        "mapping_norm": mapping,
        "objective": objective(a, y, x),
    }


def checkpoint(
    rows: list[dict[str, float | int | str]],
    method: str,
    evaluations: int,
    epoch: float,
    a: np.ndarray,
    y: np.ndarray,
    x: np.ndarray,
    optimum: float,
    mapping_step: float,
    direction_variance: float,
) -> None:
    value = objective(a, y, x)
    rows.append(
        {
            "method": method,
            "component_gradient_evaluations": evaluations,
            "epochs": epoch,
            "objective": value,
            "objective_gap": max(value - optimum, 0.0),
            "prox_gradient_mapping_norm": prox_gradient_mapping_norm(
                a, y, x, mapping_step
            ),
            "nonzero_coordinates": int(np.count_nonzero(np.abs(x) > 1e-8)),
            "direction_variance_trace": direction_variance,
        }
    )


def empirical_direction_variance(
    a: np.ndarray, y: np.ndarray, x: np.ndarray
) -> float:
    gradients = a * (a @ x - y)[:, None]
    centered = gradients - gradients.mean(axis=0)
    return float(np.mean(np.sum(centered * centered, axis=1)))


def run_prox_sgd(
    a: np.ndarray,
    y: np.ndarray,
    optimum: float,
    component_lipschitz: float,
    mapping_step: float,
) -> list[dict[str, float | int | str]]:
    rng = np.random.default_rng(SEED + 1)
    x = np.zeros(D)
    step = 0.75 / component_lipschitz
    rows: list[dict[str, float | int | str]] = []
    budget = EPOCHS * N
    checkpoint(
        rows,
        "prox_sgd_b1",
        0,
        0.0,
        a,
        y,
        x,
        optimum,
        mapping_step,
        empirical_direction_variance(a, y, x),
    )
    for evaluation in range(1, budget + 1):
        i = int(rng.integers(N))
        gradient = component_gradient(a, y, x, i)
        x = soft_threshold(x - step * gradient, step * LAMBDA)
        if evaluation % N == 0:
            checkpoint(
                rows,
                "prox_sgd_b1",
                evaluation,
                evaluation / N,
                a,
                y,
                x,
                optimum,
                mapping_step,
                empirical_direction_variance(a, y, x),
            )
    return rows


def run_prox_minibatch(
    a: np.ndarray,
    y: np.ndarray,
    optimum: float,
    component_lipschitz: float,
    mapping_step: float,
) -> list[dict[str, float | int | str]]:
    rng = np.random.default_rng(SEED + 2)
    x = np.zeros(D)
    step = 0.75 / component_lipschitz
    rows: list[dict[str, float | int | str]] = []
    budget = EPOCHS * N
    checkpoint(
        rows,
        f"prox_minibatch_b{BATCH_SIZE}",
        0,
        0.0,
        a,
        y,
        x,
        optimum,
        mapping_step,
        empirical_direction_variance(a, y, x) / BATCH_SIZE,
    )
    evaluations = 0
    while evaluations + BATCH_SIZE <= budget:
        indices = rng.integers(N, size=BATCH_SIZE)
        residual = a[indices] @ x - y[indices]
        gradient = a[indices].T @ residual / BATCH_SIZE
        x = soft_threshold(x - step * gradient, step * LAMBDA)
        evaluations += BATCH_SIZE
        if evaluations % N == 0:
            checkpoint(
                rows,
                f"prox_minibatch_b{BATCH_SIZE}",
                evaluations,
                evaluations / N,
                a,
                y,
                x,
                optimum,
                mapping_step,
                empirical_direction_variance(a, y, x) / BATCH_SIZE,
            )
    return rows


def run_prox_saga(
    a: np.ndarray,
    y: np.ndarray,
    optimum: float,
    component_lipschitz: float,
    mapping_step: float,
) -> list[dict[str, float | int | str]]:
    rng = np.random.default_rng(SEED + 3)
    x = np.zeros(D)
    table = a * (a @ x - y)[:, None]
    table_mean = table.mean(axis=0)
    step = 1.0 / (3.0 * component_lipschitz)
    rows: list[dict[str, float | int | str]] = []
    budget = EPOCHS * N
    evaluations = N
    checkpoint(
        rows,
        "prox_saga",
        evaluations,
        evaluations / N,
        a,
        y,
        x,
        optimum,
        mapping_step,
        0.0,
    )
    while evaluations < budget:
        i = int(rng.integers(N))
        fresh = component_gradient(a, y, x, i)
        estimate = fresh - table[i] + table_mean
        old = table[i].copy()
        x = soft_threshold(x - step * estimate, step * LAMBDA)
        table[i] = fresh
        table_mean += (fresh - old) / N
        evaluations += 1
        if evaluations % N == 0:
            current_components = a * (a @ x - y)[:, None]
            differences = current_components - table
            centered = differences - differences.mean(axis=0)
            saga_variance = float(np.mean(np.sum(centered * centered, axis=1)))
            checkpoint(
                rows,
                "prox_saga",
                evaluations,
                evaluations / N,
                a,
                y,
                x,
                optimum,
                mapping_step,
                saga_variance,
            )
    return rows


def write_svg(rows: list[dict[str, float | int | str]]) -> None:
    fig, ax = plt.subplots(figsize=(7.2, 4.5), constrained_layout=True)
    methods = sorted({str(row["method"]) for row in rows})
    for method in methods:
        subset = [row for row in rows if row["method"] == method]
        x = [int(row["component_gradient_evaluations"]) for row in subset]
        y = [max(float(row["objective_gap"]), 1e-16) for row in subset]
        ax.semilogy(x, y, marker="o", linewidth=1.5, markersize=3.5, label=method)
    ax.set_xlabel("Evaluasi gradien komponen")
    ax.set_ylabel("Kesenjangan objektif (skala log)")
    ax.set_title("Regresi renggang: biaya oracle yang sama")
    ax.grid(True, which="both", alpha=0.28)
    ax.legend()
    fig.savefig(
        RESULT_SVG,
        format="svg",
        metadata={
            "Title": "Kesenjangan objektif terhadap evaluasi gradien komponen",
            "Date": "2026-08-25T00:00:00Z",
            "Description": (
                "Grafik redundan; seluruh nilai tersedia dalam results.csv dan "
                "results.json."
            ),
        },
    )
    plt.close(fig)


def main() -> None:
    rng = np.random.default_rng(SEED)
    a = rng.normal(size=(N, D)) / math.sqrt(D)
    true_x = np.zeros(D)
    support = rng.choice(D, size=TRUE_NONZERO, replace=False)
    true_x[support] = rng.normal(loc=0.0, scale=2.0, size=TRUE_NONZERO)
    y = a @ true_x + NOISE_STD * rng.normal(size=N)

    smooth_lipschitz = float(np.linalg.norm(a, ord=2) ** 2 / N)
    component_lipschitz = float(np.max(np.sum(a * a, axis=1)))
    reference_x, reference = reference_fista(a, y, smooth_lipschitz)
    optimum = float(reference["objective"])
    mapping_step = 1.0 / smooth_lipschitz

    rows = []
    rows.extend(
        run_prox_sgd(a, y, optimum, component_lipschitz, mapping_step)
    )
    rows.extend(
        run_prox_minibatch(a, y, optimum, component_lipschitz, mapping_step)
    )
    rows.extend(
        run_prox_saga(a, y, optimum, component_lipschitz, mapping_step)
    )

    fieldnames = [
        "method",
        "component_gradient_evaluations",
        "epochs",
        "objective",
        "objective_gap",
        "prox_gradient_mapping_norm",
        "nonzero_coordinates",
        "direction_variance_trace",
    ]
    with RESULT_CSV.open("w", encoding="utf-8", newline="") as stream:
        writer = csv.DictWriter(stream, fieldnames=fieldnames, lineterminator="\n")
        writer.writeheader()
        writer.writerows(rows)

    final_rows = {
        method: max(
            (row for row in rows if row["method"] == method),
            key=lambda row: int(row["component_gradient_evaluations"]),
        )
        for method in sorted({str(row["method"]) for row in rows})
    }
    payload = {
        "schema": "o015-original-01-stochastic-composite-lab-v1",
        "result": "pass",
        "configuration": {
            "seed": SEED,
            "samples": N,
            "dimension": D,
            "true_nonzero_coordinates": TRUE_NONZERO,
            "noise_standard_deviation": NOISE_STD,
            "l1_regularization": LAMBDA,
            "epochs": EPOCHS,
            "component_gradient_budget": EPOCHS * N,
            "minibatch_size": BATCH_SIZE,
            "sampling": "with replacement for SGD/minibatch/SAGA index draws",
        },
        "problem": {
            "objective": "0.5/N * ||A x - y||_2^2 + lambda * ||x||_1",
            "smooth_lipschitz": smooth_lipschitz,
            "max_component_lipschitz": component_lipschitz,
            "reference": reference,
            "reference_nonzero_coordinates": int(
                np.count_nonzero(np.abs(reference_x) > 1e-8)
            ),
        },
        "final_rows": final_rows,
        "row_count": len(rows),
        "csv": {"path": RESULT_CSV.name},
        "svg": {
            "path": RESULT_SVG.name,
            "redundant_with_accessible_tables": True,
        },
        "dependencies": {
            "python": __import__("sys").version.split()[0],
            "numpy": np.__version__,
            "matplotlib": matplotlib.__version__,
        },
        "network_access": False,
        "upstream_contact": False,
    }
    RESULT_JSON.write_text(
        json.dumps(payload, ensure_ascii=False, indent=2, sort_keys=True) + "\n",
        encoding="utf-8",
        newline="\n",
    )
    write_svg(rows)

    # Bind generated outputs after every file exists. The JSON deliberately
    # omits its own hash to avoid a self-reference cycle.
    payload["csv"].update(
        {"bytes": RESULT_CSV.stat().st_size, "sha256": sha256(RESULT_CSV)}
    )
    payload["svg"].update(
        {"bytes": RESULT_SVG.stat().st_size, "sha256": sha256(RESULT_SVG)}
    )
    RESULT_JSON.write_text(
        json.dumps(payload, ensure_ascii=False, indent=2, sort_keys=True) + "\n",
        encoding="utf-8",
        newline="\n",
    )
    print(
        json.dumps(
            {
                "result": "pass",
                "rows": len(rows),
                "reference_mapping_norm": reference["mapping_norm"],
                "json_bytes": RESULT_JSON.stat().st_size,
                "json_sha256": sha256(RESULT_JSON),
                "csv_bytes": RESULT_CSV.stat().st_size,
                "csv_sha256": sha256(RESULT_CSV),
                "svg_bytes": RESULT_SVG.stat().st_size,
                "svg_sha256": sha256(RESULT_SVG),
            },
            indent=2,
            sort_keys=True,
        )
    )


if __name__ == "__main__":
    main()

Hasil JSON lengkap

{
  "configuration": {
    "component_gradient_budget": 3840,
    "dimension": 40,
    "epochs": 12,
    "l1_regularization": 0.03,
    "minibatch_size": 16,
    "noise_standard_deviation": 0.08,
    "samples": 320,
    "sampling": "with replacement for SGD/minibatch/SAGA index draws",
    "seed": 20260825,
    "true_nonzero_coordinates": 8
  },
  "csv": {
    "bytes": 4189,
    "path": "results.csv",
    "sha256": "61a6591ad7d1b41230a086482314448871f3697954d4c84133a7a5f4f775d37c"
  },
  "dependencies": {
    "matplotlib": "3.10.9",
    "numpy": "2.4.4",
    "python": "3.13.9"
  },
  "final_rows": {
    "prox_minibatch_b16": {
      "component_gradient_evaluations": 3840,
      "direction_variance_trace": 0.01638661162760481,
      "epochs": 12.0,
      "method": "prox_minibatch_b16",
      "nonzero_coordinates": 10,
      "objective": 0.3177447126633351,
      "objective_gap": 0.002570744875912634,
      "prox_gradient_mapping_norm": 0.009863014116815592
    },
    "prox_saga": {
      "component_gradient_evaluations": 3840,
      "direction_variance_trace": 4.5430827278459796e-07,
      "epochs": 12.0,
      "method": "prox_saga",
      "nonzero_coordinates": 5,
      "objective": 0.3151739698318594,
      "objective_gap": 2.0444369530636664e-09,
      "prox_gradient_mapping_norm": 9.866567454031472e-06
    },
    "prox_sgd_b1": {
      "component_gradient_evaluations": 3840,
      "direction_variance_trace": 0.26136164865160183,
      "epochs": 12.0,
      "method": "prox_sgd_b1",
      "nonzero_coordinates": 33,
      "objective": 0.3643430437640875,
      "objective_gap": 0.04916907597666503,
      "prox_gradient_mapping_norm": 0.021155328208993934
    }
  },
  "network_access": false,
  "problem": {
    "max_component_lipschitz": 1.7390392069736775,
    "objective": "0.5/N * ||A x - y||_2^2 + lambda * ||x||_1",
    "reference": {
      "iterations": 75,
      "mapping_norm": 1.4911593730067174e-15,
      "objective": 0.31517396778742246,
      "step": 22.65203499676275
    },
    "reference_nonzero_coordinates": 5,
    "smooth_lipschitz": 0.044146144050320954
  },
  "result": "pass",
  "row_count": 38,
  "schema": "o015-original-01-stochastic-composite-lab-v1",
  "svg": {
    "bytes": 86616,
    "path": "objective-gap.svg",
    "redundant_with_accessible_tables": true,
    "sha256": "87c772d901ee734356981ee35f19fc3c3ae47fea6f11528edbee6d015a3f2830"
  },
  "upstream_contact": false
}

Hasil CSV lengkap

method,component_gradient_evaluations,epochs,objective,objective_gap,prox_gradient_mapping_norm,nonzero_coordinates,direction_variance_trace
prox_sgd_b1,0,0.0,0.5513362316807581,0.2361622638933356,0.10832855794967476,0,1.1468193719792907
prox_sgd_b1,320,1.0,0.3702175482052296,0.05504358041780716,0.021444123030821837,35,0.20287630148456232
prox_sgd_b1,640,2.0,0.3456910435897478,0.030517075802325322,0.018590943751343902,26,0.2049691821609164
prox_sgd_b1,960,3.0,0.35261241671387245,0.037438448926449985,0.01936197482100853,34,0.2519231892272348
prox_sgd_b1,1280,4.0,0.36811937169959086,0.0529454039121684,0.029796229670094147,34,0.13168723150568945
prox_sgd_b1,1600,5.0,0.3440604597431073,0.028886491955684823,0.01772940293189908,32,0.17837355463918506
prox_sgd_b1,1920,6.0,0.36730400424645354,0.05213003645903108,0.022939657645467362,36,0.1855969433395085
prox_sgd_b1,2240,7.0,0.33967464511660245,0.024500677329179987,0.012560809370328175,28,0.20583985615470013
prox_sgd_b1,2560,8.0,0.33277169799112805,0.017597730203705586,0.013759461627893042,22,0.21181935832129542
prox_sgd_b1,2880,9.0,0.34224173083603737,0.027067763048614912,0.015798406128366645,28,0.27433629954292693
prox_sgd_b1,3200,10.0,0.3539651427066747,0.038791174919252214,0.020535508430316735,35,0.16457694344643045
prox_sgd_b1,3520,11.0,0.34488872564568707,0.029714757858264607,0.016623659246199234,33,0.2108599340100843
prox_sgd_b1,3840,12.0,0.3643430437640875,0.04916907597666503,0.021155328208993934,33,0.26136164865160183
prox_minibatch_b16,0,0.0,0.5513362316807581,0.2361622638933356,0.10832855794967476,0,0.07167621074870567
prox_minibatch_b16,320,1.0,0.47802984093064677,0.1628558731432243,0.08798911404534003,19,0.05572471404755659
prox_minibatch_b16,640,2.0,0.42575094873287517,0.11057698094545271,0.07263472377858442,19,0.04530167691546953
prox_minibatch_b16,960,3.0,0.39309556908426724,0.07792160129684478,0.05967953266400586,27,0.03731134660361215
prox_minibatch_b16,1280,4.0,0.3652506832322026,0.05007671544478015,0.04678905972517255,26,0.029991266926131112
prox_minibatch_b16,1600,5.0,0.34732809753256816,0.0321541297451457,0.038856894448275725,17,0.02655369940668307
prox_minibatch_b16,1920,6.0,0.33857422339713694,0.023400255609714482,0.03232876621638514,15,0.02411665732740852
prox_minibatch_b16,2240,7.0,0.33313130497336096,0.017957337185938504,0.026317750019252795,18,0.021550879809775537
prox_minibatch_b16,2560,8.0,0.3253996490028912,0.01022568121546874,0.021504470211626138,11,0.01951610028110142
prox_minibatch_b16,2880,9.0,0.32155612458903304,0.006382156801610583,0.01623058440910809,12,0.017903354865238353
prox_minibatch_b16,3200,10.0,0.31863928091487426,0.0034653131274517968,0.012937145055556078,7,0.017365712120880016
prox_minibatch_b16,3520,11.0,0.3187931787112053,0.0036192109237828674,0.010395977334385874,17,0.01643895223004758
prox_minibatch_b16,3840,12.0,0.3177447126633351,0.002570744875912634,0.009863014116815592,10,0.01638661162760481
prox_saga,320,1.0,0.5513362316807581,0.2361622638933356,0.10832855794967476,0,0.0
prox_saga,640,2.0,0.3364671079185516,0.02129314013112915,0.030882283903767606,13,0.09782001800634663
prox_saga,960,3.0,0.32103318206917736,0.005859214281754899,0.012180776828082843,18,0.06029196457916808
prox_saga,1280,4.0,0.31574500657605503,0.0005710387886325718,0.005155181368145557,6,0.03248213576359973
prox_saga,1600,5.0,0.3153073845642892,0.00013341677686673492,0.002337202852006731,6,0.012430610167196843
prox_saga,1920,6.0,0.3151831621856891,9.194398266632042e-06,0.0006657881583918369,5,0.003997002859597115
prox_saga,2240,7.0,0.315190635623481,1.6667836058525953e-05,0.0009069062956898701,5,0.001237648754466667
prox_saga,2560,8.0,0.3151752443195945,1.2765321720231704e-06,0.0002559732064124996,5,8.69567909247325e-05
prox_saga,2880,9.0,0.31517410977002475,1.4198260228637238e-07,8.335204162947475e-05,5,2.0228054402838927e-05
prox_saga,3200,10.0,0.3151740826328425,1.1484542006279241e-07,7.642797522666668e-05,5,1.029106808858402e-05
prox_saga,3520,11.0,0.31517398783419104,2.0046768578474428e-08,3.045036972269875e-05,5,2.2866507233178645e-06
prox_saga,3840,12.0,0.3151739698318594,2.0444369530636664e-09,9.866567454031472e-06,5,4.5430827278459796e-07

Hak, atribusi, dan nondukungan

Materi asli dalam tranche ini—termasuk uraian, formulasi penghubung, bukti, algoritma, latihan, petunjuk, solusi, laboratorium, dan dokumentasi—tersedia berdasarkan Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0), melalui laman lisensi resmi.

Kelas dokumen shinybook.cls adalah salinan persis kelas yang dibundel bersama Andreas Habring, Lecture Notes: Convex Optimization, arXiv:2607.11664v1; macros-id.tex adalah adaptasi Indonesia dari macros.tex dalam paket yang sama. Kedua komponen itu tersedia berdasarkan bukti lisensi Creative Commons Attribution 4.0 International (CC BY 4.0) pada tingkat kiriman arXiv, melalui laman lisensi resmi, dan bukan bagian dari lisensi CC BY-SA untuk materi baru. Berkas kelas itu tidak memuat pemberitahuan lisensi terpisah. Prakata Habring menyatakan bahwa templat catatan kuliah tersebut berasal dari Christian Clason; kredit templat itu dipertahankan tanpa menyiratkan dukungan.

Saksi verifikasi yang dirujuk meliputi karya Andreas Habring, Clément W. Royer, Lorenzo Rosasco, Silvia Villa, Bang Công Vũ, Amir Beck, Marc Teboulle, Stephen Becker, Mitchell Krock, Aaron Defazio, Francis Bach, dan Simon Lacoste-Julien. Penyebutan mereka hanya untuk atribusi matematika dan provenans. Tidak seorang pun dari mereka maupun institusinya menyusun, memeriksa, menyetujui, mensponsori, atau mendukung edisi ini.

Catatan aksesibilitas

PDF ini dapat dicari, memakai bahasa dokumen id-ID, dan merupakan permukaan tata letak tetap. HTML semantik dan EPUB reflow menyediakan permukaan baca yang lebih sesuai untuk pembesaran, layar sempit, dan teknologi bantu. Hasil laboratorium tersedia dalam CSV dan JSON sehingga informasi angka tidak bergantung pada grafik.