<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://sonsuzus.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://sonsuzus.github.io/" rel="alternate" type="text/html" /><updated>2026-08-08T10:13:19+00:00</updated><id>https://sonsuzus.github.io/feed.xml</id><title type="html">SonsuzUs</title><subtitle>Programlama ve Yazılım</subtitle><author><name>Sonsuz Us</name></author><entry><title type="html">Büyük Dil Modelleri ve İstem Mühendisliği: Yapay Zekâya Doğru Soruyu Sormak</title><link href="https://sonsuzus.github.io/posts/buyuk-dil-modelleri-ve-istem-muhendisligi-yapay-zekaya-dogru-soruyu-sormak/" rel="alternate" type="text/html" title="Büyük Dil Modelleri ve İstem Mühendisliği: Yapay Zekâya Doğru Soruyu Sormak" /><published>2026-08-08T00:00:00+00:00</published><updated>2026-08-08T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/buyuk-dil-modelleri-ve-istem-muhendisligi-yapay-zekaya-dogru-soruyu-sormak</id><content type="html" xml:base="https://sonsuzus.github.io/posts/buyuk-dil-modelleri-ve-istem-muhendisligi-yapay-zekaya-dogru-soruyu-sormak/"><![CDATA[<p>Bir büyük dil modeliyle sohbet etmek bazen her şeyi bilen bir kütüphaneciyle, bazen de özgüveni bilgisinden yüksek bir stajyerle konuşmaya benzer. Sonuçların arasındaki bu fark yalnızca modelin büyüklüğünden değil; eğitim verisinden, ince ayar yönteminden, bağlam penceresinden ve yazdığımız istemin kalitesinden doğar. Milyarlarca parametre etkileyici görünse de modeli gerçekten kullanışlı yapan şey, bu dev matematik makinesinin nasıl yönlendirildiğini anlamaktır.</p>

<p>``</p>

<h2 id="llm-aslında-ne-yapar">LLM aslında ne yapar?</h2>

<p>Büyük Dil Modelleri, metni insanlar gibi “anlamaya” çalışmaktan önce sıradaki parçayı tahmin eder. Metin, <strong>token</strong> adı verilen kelime, hece veya karakter parçalarına ayrılır. Model, önceki token’ları kullanarak bir sonraki token’ın olasılık dağılımını hesaplar:</p>

\[P(w_t \mid w_1, w_2, ..., w_{t-1})\]

<p>Örneğin “Bugün hava çok” ifadesinden sonra “güzel” token’ına yüksek olasılık verilebilir. Bu işlem art arda tekrarlandığında paragraflar, kodlar ve hatta şiirler ortaya çıkar. Yani sihirli görünen sohbet, temelde olağanüstü gelişmiş bir otomatik tamamlama sürecidir.</p>

<p>Modelin parametreleri, sinir ağındaki öğrenilebilir sayısal ağırlıklardır. Eğitim sırasında tahmin ile gerçek token arasındaki hata ölçülür. Yaygın kayıp fonksiyonu kabaca şöyledir:</p>

\[L = - \sum_t \log P(w_t \mid w_{&lt;t})\]

<p>Geri yayılım ve gradyan inişi, bu kaybı azaltacak biçimde milyarlarca ağırlığı günceller. Transformer mimarisindeki <strong>attention</strong> mekanizması ise cümlenin hangi parçalarının birbirleriyle ilişkili olduğunu belirler. Böylece model, uzak kelimeler arasındaki bağlantıları yakalayabilir.</p>

<h2 id="ön-eğitim-ince-ayar-ve-rag-farkı">Ön eğitim, ince ayar ve RAG farkı</h2>

<p>Her problemi modele yeniden ezberletmek gerekmez. İhtiyaca göre farklı uyarlama yöntemleri kullanılabilir:</p>

<table>
  <thead>
    <tr>
      <th>Yöntem</th>
      <th>Ne değişir?</th>
      <th>Güçlü yanı</th>
      <th>Uygun senaryo</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Ön eğitim</td>
      <td>Tüm model ağırlıkları</td>
      <td>Genel dil yeteneği kazandırır</td>
      <td>Temel model geliştirme</td>
    </tr>
    <tr>
      <td>Fine-tuning</td>
      <td>Ağırlıkların tümü veya bir kısmı</td>
      <td>Davranışı kalıcı biçimde özelleştirir</td>
      <td>Sınıflandırma, kurum dili</td>
    </tr>
    <tr>
      <td>RAG</td>
      <td>Model yerine bağlam zenginleşir</td>
      <td>Güncel ve kaynaklı bilgi sağlar</td>
      <td>Doküman arama, destek botu</td>
    </tr>
    <tr>
      <td>Prompting</td>
      <td>Yalnızca giriş metni</td>
      <td>Hızlı ve düşük maliyetlidir</td>
      <td>Günlük görevler, prototipler</td>
    </tr>
  </tbody>
</table>

<p>Fine-tuning sürecinde kaliteli giriş-çıkış örnekleri hazırlanır. Ardından düşük öğrenme oranıyla eğitim yapılır ve model daha önce görmediği doğrulama verisiyle sınanır. Veri azsa LoRA gibi parametre-verimli yöntemler tercih edilebilir. LoRA, dev modelin tamamını değiştirmek yerine küçük ek matrisler öğrenerek maliyeti düşürür.</p>

<h2 id="i̇yi-bir-istem-nasıl-yazılır">İyi bir istem nasıl yazılır?</h2>

<p>“Bana yazılımı anlat” istemi belirsizdir. Model hedef kitleyi, kapsamı ve çıktı biçimini tahmin etmek zorunda kalır. Sağlam bir istem genellikle dört bileşen içerir:</p>

<ol>
  <li><strong>Rol:</strong> Modelin hangi uzman gibi davranacağı.</li>
  <li><strong>Görev:</strong> Tam olarak ne üretileceği.</li>
  <li><strong>Bağlam:</strong> Kullanılacak bilgi ve sınırlamalar.</li>
  <li><strong>Çıktı biçimi:</strong> Tablo, JSON, liste veya kod gibi format.</li>
</ol>

<p>Örneğin API üzerinden yapılandırılmış bir istem şöyle hazırlanabilir:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">prompt</span> <span class="o">=</span> <span class="sh">"""</span><span class="s">
Rolün: Kıdemli Python geliştiricisi.
Görev: Aşağıdaki fonksiyondaki performans sorunlarını bul.
Kısıtlar: Davranışı değiştirme, en fazla üç öneri sun.
Çıktı: Sorun, neden ve düzeltilmiş kod başlıklarını kullan.
Kod:
{code}
</span><span class="sh">"""</span>

<span class="n">response</span> <span class="o">=</span> <span class="n">client</span><span class="p">.</span><span class="n">responses</span><span class="p">.</span><span class="nf">create</span><span class="p">(</span>
    <span class="n">model</span><span class="o">=</span><span class="sh">"</span><span class="s">uygun-model</span><span class="sh">"</span><span class="p">,</span>
    <span class="nb">input</span><span class="o">=</span><span class="n">prompt</span><span class="p">.</span><span class="nf">format</span><span class="p">(</span><span class="n">code</span><span class="o">=</span><span class="n">source_code</span><span class="p">)</span>
<span class="p">)</span>
</code></pre></div></div>

<p>Bu kod, modele yalnızca soru sormaz; rol, sınır ve beklenen yapıyı da bildirir. Üretim ortamında kullanıcı verisi doğrudan isteme ekleniyorsa prompt injection saldırılarına karşı doğrulama ve yetkilendirme uygulanmalıdır.</p>

<h2 id="daha-güvenilir-sonuçlar-için-küçük-taktikler">Daha güvenilir sonuçlar için küçük taktikler</h2>

<p>Karmaşık işleri tek seferde istemek yerine görevi aşamalara bölmek başarıyı artırır. Birkaç kaliteli örnek vermek <strong>few-shot prompting</strong>, hiç örnek vermeden açık talimat kullanmak ise <strong>zero-shot prompting</strong> olarak adlandırılır. Modelden bilinmeyen noktaları belirtmesini, varsayımlarını listelemesini ve mümkünse kaynak göstermesini istemek de halüsinasyon riskini azaltır.</p>

<p>Sonuç olarak LLM, niyet okuyan bir kahin değil; bağlamdan olasılık üreten güçlü bir sistemdir. Fine-tuning davranışı uzmanlaştırır, RAG güncel bilgiyi taşır, iyi prompting ise tüm bu kapasitenin doğru kapıya yönelmesini sağlar. Yapay zekâ çağında yalnızca cevabı bilmek değil, doğru soruyu tasarlamak da temel bir mühendislik becerisidir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="LLM" /><category term="İstem Mühendisliği" /><category term="Fine-Tuning" /><summary type="html"><![CDATA[Bir büyük dil modeliyle sohbet etmek bazen her şeyi bilen bir kütüphaneciyle, bazen de özgüveni bilgisinden yüksek bir stajyerle konuşmaya benzer. Sonuçların arasındaki bu fark yalnızca modelin büyüklüğünden değil; eğitim verisinden, ince ayar yönteminden, bağlam penceresinden ve yazdığımız istemin kalitesinden doğar. Milyarlarca parametre etkileyici görünse de modeli gerçekten kullanışlı yapan şey, bu dev matematik makinesinin nasıl yönlendirildiğini anlamaktır.]]></summary></entry><entry><title type="html">C ile Epoll Tabanlı Bloklamayan Web Sunucusu Yazmak</title><link href="https://sonsuzus.github.io/posts/c-ile-epoll-tabanli-bloklamayan-web-sunucusu-yazmak/" rel="alternate" type="text/html" title="C ile Epoll Tabanlı Bloklamayan Web Sunucusu Yazmak" /><published>2026-08-08T00:00:00+00:00</published><updated>2026-08-08T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/c-ile-epoll-tabanli-bloklamayan-web-sunucusu-yazmak</id><content type="html" xml:base="https://sonsuzus.github.io/posts/c-ile-epoll-tabanli-bloklamayan-web-sunucusu-yazmak/"><![CDATA[<p>Bir web sunucusunun aynı anda binlerce istemciyle konuşabilmesi, her bağlantıya ayrı bir iş parçacığı tahsis etmekten çok daha akıllı bir yaklaşım gerektirir. Bu projede Linux üzerinde <code class="language-plaintext highlighter-rouge">epoll</code>, BSD ve macOS tarafında ise benzer görev üstlenen <code class="language-plaintext highlighter-rouge">kqueue</code> mantığını inceleyerek bloklamayan, olay güdümlü ve küçük ama öğretici bir HTTP sunucusunun temelini kuracağız.
``</p>

<h2 id="neden-klasik-yaklaşım-yetmez">Neden klasik yaklaşım yetmez?</h2>

<p>En basit sunucular <code class="language-plaintext highlighter-rouge">accept()</code> ile bağlantı kabul eder, ardından <code class="language-plaintext highlighter-rouge">read()</code> çağrısıyla veri bekler. Ancak bu fonksiyonlar bloklayan kipte çalışırsa yavaş bir istemci tüm yürütme akışını durdurabilir. Her bağlantı için yeni bir thread açmak sorunu kısmen çözer; fakat binlerce thread bellek tüketir, zamanlayıcıyı yorar ve bağlam değiştirme maliyeti oluşturur.</p>

<p>Yaklaşık bellek tüketimini şöyle düşünebiliriz:</p>

\[M \approx N \times S\]

<p>Burada $N$ bağlantı veya thread sayısını, $S$ ise her thread’in stack boyutunu temsil eder. 10.000 thread ve 1 MB stack kullanıldığında teorik ihtiyaç yaklaşık 10 GB olur. Olay döngüsünde ise az sayıda thread, binlerce soketi izleyebilir.</p>

<table>
  <thead>
    <tr>
      <th>Model</th>
      <th style="text-align: right">Ölçeklenebilirlik</th>
      <th style="text-align: right">Bellek maliyeti</th>
      <th style="text-align: right">Programlama zorluğu</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Bağlantı başına thread</td>
      <td style="text-align: right">Orta</td>
      <td style="text-align: right">Yüksek</td>
      <td style="text-align: right">Düşük</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">select</code> / <code class="language-plaintext highlighter-rouge">poll</code></td>
      <td style="text-align: right">Orta</td>
      <td style="text-align: right">Orta</td>
      <td style="text-align: right">Orta</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">epoll</code> / <code class="language-plaintext highlighter-rouge">kqueue</code></td>
      <td style="text-align: right">Yüksek</td>
      <td style="text-align: right">Düşük</td>
      <td style="text-align: right">Yüksek</td>
    </tr>
  </tbody>
</table>

<p><code class="language-plaintext highlighter-rouge">select</code> her turda tüm dosya tanıtıcılarını tararken <code class="language-plaintext highlighter-rouge">epoll_wait</code>, yalnızca hazır olayları döndürür. Basitleştirilmiş maliyet karşılaştırması <code class="language-plaintext highlighter-rouge">select</code> için $O(N)$, hazır olay sayısı $K$ olan bir olay döngüsü için yaklaşık $O(K)$ şeklindedir.</p>

<h2 id="soketleri-bloklamayan-kipe-almak">Soketleri bloklamayan kipe almak</h2>

<p>Linux soketini <code class="language-plaintext highlighter-rouge">O_NONBLOCK</code> bayrağıyla yapılandırırız. Böylece hemen tamamlanamayan <code class="language-plaintext highlighter-rouge">accept</code>, <code class="language-plaintext highlighter-rouge">read</code> veya <code class="language-plaintext highlighter-rouge">write</code> işlemleri programı uyutmak yerine <code class="language-plaintext highlighter-rouge">EAGAIN</code> hatası döndürür.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">static</span> <span class="kt">int</span> <span class="nf">make_nonblocking</span><span class="p">(</span><span class="kt">int</span> <span class="n">fd</span><span class="p">)</span> <span class="p">{</span>
    <span class="kt">int</span> <span class="n">flags</span> <span class="o">=</span> <span class="n">fcntl</span><span class="p">(</span><span class="n">fd</span><span class="p">,</span> <span class="n">F_GETFL</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">flags</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
    <span class="k">return</span> <span class="n">fcntl</span><span class="p">(</span><span class="n">fd</span><span class="p">,</span> <span class="n">F_SETFL</span><span class="p">,</span> <span class="n">flags</span> <span class="o">|</span> <span class="n">O_NONBLOCK</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Bu küçük yardımcı, hem dinleme soketine hem de kabul edilen istemci soketlerine uygulanmalıdır.</p>

<h2 id="epoll-olay-döngüsü">Epoll olay döngüsü</h2>

<p>Dinleme soketi oluşturulup <code class="language-plaintext highlighter-rouge">bind()</code> ve <code class="language-plaintext highlighter-rouge">listen()</code> çağrıları tamamlandıktan sonra bir epoll örneği açılır:</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="n">epfd</span> <span class="o">=</span> <span class="n">epoll_create1</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>

<span class="k">struct</span> <span class="n">epoll_event</span> <span class="n">ev</span> <span class="o">=</span> <span class="p">{</span>
    <span class="p">.</span><span class="n">events</span> <span class="o">=</span> <span class="n">EPOLLIN</span><span class="p">,</span>
    <span class="p">.</span><span class="n">data</span><span class="p">.</span><span class="n">fd</span> <span class="o">=</span> <span class="n">server_fd</span>
<span class="p">};</span>
<span class="n">epoll_ctl</span><span class="p">(</span><span class="n">epfd</span><span class="p">,</span> <span class="n">EPOLL_CTL_ADD</span><span class="p">,</span> <span class="n">server_fd</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">ev</span><span class="p">);</span>

<span class="k">for</span> <span class="p">(;;)</span> <span class="p">{</span>
    <span class="k">struct</span> <span class="n">epoll_event</span> <span class="n">events</span><span class="p">[</span><span class="mi">1024</span><span class="p">];</span>
    <span class="kt">int</span> <span class="n">count</span> <span class="o">=</span> <span class="n">epoll_wait</span><span class="p">(</span><span class="n">epfd</span><span class="p">,</span> <span class="n">events</span><span class="p">,</span> <span class="mi">1024</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">);</span>

    <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">count</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="kt">int</span> <span class="n">fd</span> <span class="o">=</span> <span class="n">events</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">data</span><span class="p">.</span><span class="n">fd</span><span class="p">;</span>

        <span class="k">if</span> <span class="p">(</span><span class="n">fd</span> <span class="o">==</span> <span class="n">server_fd</span><span class="p">)</span> <span class="p">{</span>
            <span class="n">accept_clients</span><span class="p">(</span><span class="n">server_fd</span><span class="p">,</span> <span class="n">epfd</span><span class="p">);</span>
        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">events</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">events</span> <span class="o">&amp;</span> <span class="n">EPOLLIN</span><span class="p">)</span> <span class="p">{</span>
            <span class="n">handle_request</span><span class="p">(</span><span class="n">fd</span><span class="p">,</span> <span class="n">epfd</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">accept_clients</code> fonksiyonu tek bağlantı kabul edip dönmemelidir. Edge-triggered kullanımda <code class="language-plaintext highlighter-rouge">accept()</code> çağrısı <code class="language-plaintext highlighter-rouge">EAGAIN</code> verene kadar döngü sürmelidir. Aynı kural <code class="language-plaintext highlighter-rouge">read()</code> için de geçerlidir; aksi hâlde sokette veri kalmasına rağmen yeni bildirim alınmayabilir.</p>

<h2 id="http-yanıtı-ve-kısmi-yazmalar">HTTP yanıtı ve kısmi yazmalar</h2>

<p>Minimal bir yanıt şu biçimdedir:</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">response</span> <span class="o">=</span>
    <span class="s">"HTTP/1.1 200 OK</span><span class="se">\r\n</span><span class="s">"</span>
    <span class="s">"Content-Length: 13</span><span class="se">\r\n</span><span class="s">"</span>
    <span class="s">"Connection: close</span><span class="se">\r\n</span><span class="s">"</span>
    <span class="s">"</span><span class="se">\r\n</span><span class="s">"</span>
    <span class="s">"Merhaba HTTP!"</span><span class="p">;</span>
</code></pre></div></div>

<p>Bloklamayan <code class="language-plaintext highlighter-rouge">send()</code> yanıtın yalnızca bir bölümünü yazabilir. Bu nedenle her bağlantı için tampon, gönderilen bayt sayısı ve ayrıştırma durumu tutulmalıdır. Yazma tamamlanamazsa soket <code class="language-plaintext highlighter-rouge">EPOLLOUT</code> olayına kaydedilir; tamamlanınca bu ilgi kaldırılır. Sürekli <code class="language-plaintext highlighter-rouge">EPOLLOUT</code> izlemek işlemciyi gereksiz yere meşgul eder.</p>

<h2 id="epoll-ve-kqueue-farkı">Epoll ve kqueue farkı</h2>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>epoll</th>
      <th>kqueue</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Platform</td>
      <td>Linux</td>
      <td>BSD, macOS</td>
    </tr>
    <tr>
      <td>Okuma olayı</td>
      <td><code class="language-plaintext highlighter-rouge">EPOLLIN</code></td>
      <td><code class="language-plaintext highlighter-rouge">EVFILT_READ</code></td>
    </tr>
    <tr>
      <td>Yazma olayı</td>
      <td><code class="language-plaintext highlighter-rouge">EPOLLOUT</code></td>
      <td><code class="language-plaintext highlighter-rouge">EVFILT_WRITE</code></td>
    </tr>
    <tr>
      <td>Edge-triggered seçenek</td>
      <td><code class="language-plaintext highlighter-rouge">EPOLLET</code></td>
      <td><code class="language-plaintext highlighter-rouge">EV_CLEAR</code></td>
    </tr>
  </tbody>
</table>

<p>Taşınabilirlik için olay kayıtlarını soyutlayan küçük bir arayüz yazılabilir. Güvenli bir gerçek dünya sunucusunda ayrıca zaman aşımı kuyruğu, maksimum istek boyutu, HTTP ayrıştırıcısı, TLS, sinyal yönetimi ve bağlantı başına geri basınç bulunmalıdır. Böylece oyuncak sunucu, internetin huysuz istemcilerine karşı dayanıklı bir altyapıya dönüşür.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Proje" /><category term="C" /><category term="epoll" /><category term="asenkron-programlama" /><summary type="html"><![CDATA[Bir web sunucusunun aynı anda binlerce istemciyle konuşabilmesi, her bağlantıya ayrı bir iş parçacığı tahsis etmekten çok daha akıllı bir yaklaşım gerektirir. Bu projede Linux üzerinde epoll, BSD ve macOS tarafında ise benzer görev üstlenen kqueue mantığını inceleyerek bloklamayan, olay güdümlü ve küçük ama öğretici bir HTTP sunucusunun temelini kuracağız.]]></summary></entry><entry><title type="html">Cebirsel Veri Tipleriyle Mini Derleyici: Örüntü Eşlemeden Bayt Koduna</title><link href="https://sonsuzus.github.io/posts/cebirsel-veri-tipleriyle-mini-derleyici-oruntu-eslemeden-bayt-koduna/" rel="alternate" type="text/html" title="Cebirsel Veri Tipleriyle Mini Derleyici: Örüntü Eşlemeden Bayt Koduna" /><published>2026-08-08T00:00:00+00:00</published><updated>2026-08-08T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/cebirsel-veri-tipleriyle-mini-derleyici-oruntu-eslemeden-bayt-koduna</id><content type="html" xml:base="https://sonsuzus.github.io/posts/cebirsel-veri-tipleriyle-mini-derleyici-oruntu-eslemeden-bayt-koduna/"><![CDATA[<p>Bir programlama dilinin nasıl çalıştığını anlamanın en eğlenceli yollarından biri, küçük ama gerçek bir derleyici yazmaktır. Bu projede Haskell benzeri, cebirsel veri tiplerini ve örüntü eşlemeyi destekleyen bir dili yığın tabanlı sanal makine komutlarına çevireceğiz. Hedefimiz yeni bir Haskell üretmek değil; sözdizimi ağacı, tipler, örüntüler ve kod üretimi arasındaki ilişkiyi elle tutulur hâle getirmek.
``</p>

<h2 id="dilimizin-temel-modeli">Dilimizin temel modeli</h2>

<p>Cebirsel veri tipi, mevcut tipleri <strong>toplam</strong> ve <strong>çarpım</strong> işlemleriyle birleştirir. Örneğin <code class="language-plaintext highlighter-rouge">Bool</code>, iki olası değerden oluştuğu için toplam tipidir:</p>

\[Bool = True + False\]

<p><code class="language-plaintext highlighter-rouge">Pair Int Bool</code> ise iki değeri birlikte taşıdığı için çarpım tipidir:</p>

\[|Pair\ Int\ Bool| = |Int| \times |Bool|\]

<p>Bu bakış açısı yalnızca matematiksel süs değildir. Derleyici, bir <code class="language-plaintext highlighter-rouge">case</code> ifadesinin tüm olasılıkları kapsayıp kapsamadığını bu yapı üzerinden inceleyebilir.</p>

<table>
  <thead>
    <tr>
      <th>Kavram</th>
      <th>Anlamı</th>
      <th>Dilimizdeki örnek</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Toplam tipi</td>
      <td>Alternatiflerden biri seçilir</td>
      <td><code class="language-plaintext highlighter-rouge">Maybe a = None | Some a</code></td>
    </tr>
    <tr>
      <td>Çarpım tipi</td>
      <td>Değerler birlikte taşınır</td>
      <td><code class="language-plaintext highlighter-rouge">Point = Point Int Int</code></td>
    </tr>
    <tr>
      <td>Örüntü</td>
      <td>Değeri parçalayarak sınar</td>
      <td><code class="language-plaintext highlighter-rouge">Some x -&gt; x</code></td>
    </tr>
    <tr>
      <td>Kaplayıcılık</td>
      <td>Tüm kurucuların ele alınması</td>
      <td><code class="language-plaintext highlighter-rouge">None</code> ve <code class="language-plaintext highlighter-rouge">Some</code> dalları</td>
    </tr>
  </tbody>
</table>

<h2 id="soyut-sözdizimi-ağacı">Soyut sözdizimi ağacı</h2>

<p>Kaynak kodu doğrudan makine komutlarına çevirmek yerine önce bir AST oluştururuz. AST, boşluk ve parantez gibi ayrıntıları atarak programın anlamını saklar.</p>

<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">data</span> <span class="kt">Expr</span>
  <span class="o">=</span> <span class="kt">LitInt</span> <span class="kt">Int</span>
  <span class="o">|</span> <span class="kt">Var</span> <span class="kt">Name</span>
  <span class="o">|</span> <span class="kt">Add</span> <span class="kt">Expr</span> <span class="kt">Expr</span>
  <span class="o">|</span> <span class="kt">Con</span> <span class="kt">Name</span> <span class="p">[</span><span class="kt">Expr</span><span class="p">]</span>
  <span class="o">|</span> <span class="kt">Case</span> <span class="kt">Expr</span> <span class="p">[</span><span class="kt">Branch</span><span class="p">]</span>

<span class="kr">data</span> <span class="kt">Pattern</span>
  <span class="o">=</span> <span class="kt">PWildcard</span>
  <span class="o">|</span> <span class="kt">PVar</span> <span class="kt">Name</span>
  <span class="o">|</span> <span class="kt">PCon</span> <span class="kt">Name</span> <span class="p">[</span><span class="kt">Pattern</span><span class="p">]</span>

<span class="kr">data</span> <span class="kt">Branch</span> <span class="o">=</span> <span class="kt">Branch</span> <span class="kt">Pattern</span> <span class="kt">Expr</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">Con</code> veri kurucusu oluşturur; <code class="language-plaintext highlighter-rouge">PCon</code> ise aynı kurucuyu örüntü içinde arar. Örneğin <code class="language-plaintext highlighter-rouge">Some 42</code>, <code class="language-plaintext highlighter-rouge">Con Some [LitInt 42]</code> biçiminde temsil edilir. Bu ayrım önemlidir: ifade bir değer <strong>üretirken</strong>, örüntü mevcut değeri <strong>sorgular</strong>.</p>

<h2 id="örüntüleri-derlemek">Örüntüleri derlemek</h2>

<p>Sanal makinemizin yığın kullandığını varsayalım. Her cebirsel değer, kurucu etiketi ve alanlarından oluşsun. <code class="language-plaintext highlighter-rouge">Some 7</code> kabaca <code class="language-plaintext highlighter-rouge">(Some, [7])</code> şeklinde düşünülebilir.</p>

<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">data</span> <span class="kt">Instr</span>
  <span class="o">=</span> <span class="kt">PushInt</span> <span class="kt">Int</span>
  <span class="o">|</span> <span class="kt">Load</span> <span class="kt">Name</span>
  <span class="o">|</span> <span class="kt">Build</span> <span class="kt">Name</span> <span class="kt">Int</span>
  <span class="o">|</span> <span class="kt">TestTag</span> <span class="kt">Name</span> <span class="kt">Label</span>
  <span class="o">|</span> <span class="kt">Unpack</span> <span class="kt">Int</span>
  <span class="o">|</span> <span class="kt">Jump</span> <span class="kt">Label</span>
  <span class="o">|</span> <span class="kt">Mark</span> <span class="kt">Label</span>
  <span class="o">|</span> <span class="kt">FailMatch</span>
</code></pre></div></div>

<p>Bir örüntüyü derleyen fonksiyon, başarısızlık durumunda gidilecek etiketi alır:</p>

<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">compilePattern</span> <span class="o">::</span> <span class="kt">Pattern</span> <span class="o">-&gt;</span> <span class="kt">Label</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="kt">Instr</span><span class="p">]</span>
<span class="n">compilePattern</span> <span class="kt">PWildcard</span> <span class="kr">_</span> <span class="o">=</span> <span class="kt">[]</span>
<span class="n">compilePattern</span> <span class="p">(</span><span class="kt">PVar</span> <span class="n">name</span><span class="p">)</span> <span class="kr">_</span> <span class="o">=</span> <span class="p">[</span><span class="kt">Bind</span> <span class="n">name</span><span class="p">]</span>
<span class="n">compilePattern</span> <span class="p">(</span><span class="kt">PCon</span> <span class="n">tag</span> <span class="n">fields</span><span class="p">)</span> <span class="n">fail</span> <span class="o">=</span>
  <span class="p">[</span><span class="kt">TestTag</span> <span class="n">tag</span> <span class="n">fail</span><span class="p">,</span> <span class="kt">Unpack</span> <span class="p">(</span><span class="n">length</span> <span class="n">fields</span><span class="p">)]</span>
  <span class="o">++</span> <span class="n">concatMap</span> <span class="p">(`</span><span class="n">compilePattern</span><span class="p">`</span> <span class="n">fail</span><span class="p">)</span> <span class="n">fields</span>
</code></pre></div></div>

<p>Buradaki fikir kısa ama güçlüdür: <code class="language-plaintext highlighter-rouge">TestTag</code>, değerin kurucusunu kontrol eder; uyuşmazsa sonraki dala sıçrar. <code class="language-plaintext highlighter-rouge">Unpack</code>, kurucunun alanlarını yığına açar. Alt örüntüler daha sonra aynı yöntemle özyinelemeli olarak işlenir.</p>

<h2 id="case-ifadesinin-kod-üretimi"><code class="language-plaintext highlighter-rouge">case</code> ifadesinin kod üretimi</h2>

<p>Her dal için bir sonraki dal etiketi ve ortak bir bitiş etiketi üretiriz:</p>

<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">compileCase</span> <span class="n">scrutinee</span> <span class="n">branches</span> <span class="o">=</span>
  <span class="n">compileExpr</span> <span class="n">scrutinee</span> <span class="o">++</span> <span class="n">go</span> <span class="n">branches</span>
  <span class="kr">where</span>
    <span class="n">go</span> <span class="kt">[]</span> <span class="o">=</span> <span class="p">[</span><span class="kt">FailMatch</span><span class="p">]</span>
    <span class="n">go</span> <span class="p">(</span><span class="kt">Branch</span> <span class="n">pat</span> <span class="n">body</span> <span class="o">:</span> <span class="n">rest</span><span class="p">)</span> <span class="o">=</span>
      <span class="kr">let</span> <span class="n">next</span> <span class="o">=</span> <span class="n">freshLabel</span><span class="nb">()</span>
          <span class="n">done</span> <span class="o">=</span> <span class="n">caseEndLabel</span>
      <span class="kr">in</span>  <span class="p">[</span><span class="kt">Dup</span><span class="p">]</span>
       <span class="o">++</span> <span class="n">compilePattern</span> <span class="n">pat</span> <span class="n">next</span>
       <span class="o">++</span> <span class="p">[</span><span class="kt">Pop</span><span class="p">]</span>
       <span class="o">++</span> <span class="n">compileExpr</span> <span class="n">body</span>
       <span class="o">++</span> <span class="p">[</span><span class="kt">Jump</span> <span class="n">done</span><span class="p">,</span> <span class="kt">Mark</span> <span class="n">next</span><span class="p">]</span>
       <span class="o">++</span> <span class="n">go</span> <span class="n">rest</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">Dup</code>, aynı değerin sonraki dalda tekrar denenebilmesini sağlar. Başarılı dal gövdesini çalıştırıp sona atlar; hiçbir dal eşleşmezse <code class="language-plaintext highlighter-rouge">FailMatch</code> devreye girer. Gerçek bir derleyicide etiket üretimi saf bir <code class="language-plaintext highlighter-rouge">State</code> monadıyla yönetilebilir.</p>

<h2 id="kaplayıcılık-ve-son-dokunuşlar">Kaplayıcılık ve son dokunuşlar</h2>

<p>Çalışma zamanındaki <code class="language-plaintext highlighter-rouge">FailMatch</code> yararlıdır, fakat hatayı derleme aşamasında bulmak daha iyidir. <code class="language-plaintext highlighter-rouge">Maybe a</code> üzerinde yalnızca <code class="language-plaintext highlighter-rouge">Some x</code> dalı varsa eksik kurucu kümesi şöyledir:</p>

\[Eksik = \{None, Some\} - \{Some\} = \{None\}\]

<p>İlk sürümde yalnızca üst seviye kurucuları karşılaştırabilir, joker örüntüsü görüldüğünde kümeyi tamamen kapsanmış sayabiliriz. Sonraki adımlarda iç içe örüntüler, tip çıkarımı, gereksiz dal uyarıları ve kuyruk çağrısı optimizasyonu eklenebilir. Böylece küçük derleyicimiz, birkaç veri tanımından başlayıp fonksiyonel dillerin kalbindeki önemli fikirlere uzanan sevimli bir laboratuvara dönüşür.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Proje" /><category term="fonksiyonel-programlama" /><category term="derleyici" /><category term="örüntü-eşleme" /><summary type="html"><![CDATA[Bir programlama dilinin nasıl çalıştığını anlamanın en eğlenceli yollarından biri, küçük ama gerçek bir derleyici yazmaktır. Bu projede Haskell benzeri, cebirsel veri tiplerini ve örüntü eşlemeyi destekleyen bir dili yığın tabanlı sanal makine komutlarına çevireceğiz. Hedefimiz yeni bir Haskell üretmek değil; sözdizimi ağacı, tipler, örüntüler ve kod üretimi arasındaki ilişkiyi elle tutulur hâle getirmek.]]></summary></entry><entry><title type="html">Cep Telefonu Sensörleriyle Adım Sayma ve Aktivite Sınıflandırma</title><link href="https://sonsuzus.github.io/posts/cep-telefonu-sensorleriyle-adim-sayma-ve-aktivite-siniflandirma/" rel="alternate" type="text/html" title="Cep Telefonu Sensörleriyle Adım Sayma ve Aktivite Sınıflandırma" /><published>2026-08-08T00:00:00+00:00</published><updated>2026-08-08T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/cep-telefonu-sensorleriyle-adim-sayma-ve-aktivite-siniflandirma</id><content type="html" xml:base="https://sonsuzus.github.io/posts/cep-telefonu-sensorleriyle-adim-sayma-ve-aktivite-siniflandirma/"><![CDATA[<p>Telefonunuz cebinizde sessizce duruyor gibi görünse de ivmeölçer sensörü her saniye onlarca ölçüm üretir. Bu ham veriyi doğru biçimde işlediğimizde kaç adım atıldığını hesaplayabilir; kullanıcının yürüdüğünü, koştuğunu veya hareketsiz kaldığını tahmin edebiliriz. Bu projede gürültülü sensör değerlerini anlamlı aktivite bilgisine dönüştüren uçtan uca bir sistem kuracağız.
``</p>

<h2 id="ham-ivmeölçer-verisini-anlamak">Ham ivmeölçer verisini anlamak</h2>

<p>İvmeölçer, telefonun üç eksendeki ivmesini ölçer: $a_x$, $a_y$ ve $a_z$. Değerler genellikle $m/s^2$ cinsindendir. Telefon masada hareketsiz olsa bile sensör sıfır göstermez; çünkü yerçekimi ivmesi olan yaklaşık $9.81\,m/s^2$ ölçüme dahildir.</p>

<p>Telefonun cebimizdeki yönü sürekli değişebileceği için eksenleri ayrı ayrı kullanmak kırılgan bir çözümdür. Bunun yerine toplam ivme büyüklüğünü hesaplayabiliriz:</p>

\[a = \sqrt{a_x^2 + a_y^2 + a_z^2}\]

<p>Bu değer telefonun yönünden büyük ölçüde bağımsızdır. Dinamik hareketi görmek için yerçekimi bileşeni çıkarılabilir:</p>

\[a_d = a - g\]

<p>Burada $g \approx 9.81\,m/s^2$ kabul edilir. Daha güvenilir uygulamalarda sabit çıkarma yerine alçak geçiren filtreyle tahmin edilen yerçekimi kullanılır.</p>

<table>
  <thead>
    <tr>
      <th>İşlem</th>
      <th>Amaç</th>
      <th>Uygun yöntem</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Gürültü azaltma</td>
      <td>Sensördeki küçük titreşimleri temizlemek</td>
      <td>Alçak geçiren filtre</td>
    </tr>
    <tr>
      <td>Yerçekimi ayırma</td>
      <td>Gerçek vücut hareketini bulmak</td>
      <td>Yüksek geçiren filtre</td>
    </tr>
    <tr>
      <td>Yön bağımsızlığı</td>
      <td>Telefon konumunun etkisini azaltmak</td>
      <td>Vektör büyüklüğü</td>
    </tr>
    <tr>
      <td>Pencereleme</td>
      <td>Sinyali analiz edilebilir parçalara bölmek</td>
      <td>2–5 saniyelik pencereler</td>
    </tr>
  </tbody>
</table>

<h2 id="adımları-tepe-noktalarıyla-saymak">Adımları tepe noktalarıyla saymak</h2>

<p>Yürürken her adım, filtrelenmiş ivme sinyalinde belirgin bir tepe oluşturur. Ancak her tepeyi adım kabul edersek telefonu sallamak bile maraton koşmuşuz gibi görünebilir. Bu nedenle üç koşul kullanılır: minimum tepe yüksekliği, iki tepe arasındaki minimum süre ve tepenin belirginliği.</p>

<p>Normal yürüyüş frekansı çoğunlukla $1$–$2.5$ Hz aralığındadır. Dolayısıyla iki adım arasında örneğin en az $0.3$ saniye bulunmasını isteyebiliriz. Eşiklerin kişiye ve telefon konumuna göre ayarlanması sonuçları iyileştirir.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">numpy</span> <span class="k">as</span> <span class="n">np</span>
<span class="kn">from</span> <span class="n">scipy.signal</span> <span class="kn">import</span> <span class="n">butter</span><span class="p">,</span> <span class="n">filtfilt</span><span class="p">,</span> <span class="n">find_peaks</span>

<span class="k">def</span> <span class="nf">analyze_steps</span><span class="p">(</span><span class="n">ax</span><span class="p">,</span> <span class="n">ay</span><span class="p">,</span> <span class="n">az</span><span class="p">,</span> <span class="n">sample_rate</span><span class="o">=</span><span class="mi">50</span><span class="p">):</span>
    <span class="c1"># Telefon yönünden bağımsız toplam ivme büyüklüğü
</span>    <span class="n">magnitude</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">sqrt</span><span class="p">(</span><span class="n">ax</span><span class="o">**</span><span class="mi">2</span> <span class="o">+</span> <span class="n">ay</span><span class="o">**</span><span class="mi">2</span> <span class="o">+</span> <span class="n">az</span><span class="o">**</span><span class="mi">2</span><span class="p">)</span>

    <span class="c1"># Yürüme ritmini koruyan 0.5–3 Hz bant geçiren filtre
</span>    <span class="n">nyquist</span> <span class="o">=</span> <span class="n">sample_rate</span> <span class="o">/</span> <span class="mi">2</span>
    <span class="n">b</span><span class="p">,</span> <span class="n">a</span> <span class="o">=</span> <span class="nf">butter</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="p">[</span><span class="mf">0.5</span> <span class="o">/</span> <span class="n">nyquist</span><span class="p">,</span> <span class="mi">3</span> <span class="o">/</span> <span class="n">nyquist</span><span class="p">],</span> <span class="n">btype</span><span class="o">=</span><span class="sh">'</span><span class="s">band</span><span class="sh">'</span><span class="p">)</span>
    <span class="n">filtered</span> <span class="o">=</span> <span class="nf">filtfilt</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="n">magnitude</span><span class="p">)</span>

    <span class="c1"># En az 0.3 saniye aralıklı ve belirgin tepeleri bul
</span>    <span class="n">peaks</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="nf">find_peaks</span><span class="p">(</span>
        <span class="n">filtered</span><span class="p">,</span>
        <span class="n">distance</span><span class="o">=</span><span class="nf">int</span><span class="p">(</span><span class="mf">0.3</span> <span class="o">*</span> <span class="n">sample_rate</span><span class="p">),</span>
        <span class="n">prominence</span><span class="o">=</span><span class="mf">0.4</span>
    <span class="p">)</span>
    <span class="k">return</span> <span class="nf">len</span><span class="p">(</span><span class="n">peaks</span><span class="p">),</span> <span class="n">filtered</span><span class="p">,</span> <span class="n">peaks</span>
</code></pre></div></div>

<p>Bu fonksiyon önce büyüklüğü hesaplar, ardından yürüyüş dışındaki çok yavaş ve çok hızlı değişimleri süzer. <code class="language-plaintext highlighter-rouge">find_peaks</code>, belirgin ritmik tepelerin indekslerini döndürür; tepe sayısı da yaklaşık adım sayısıdır.</p>

<h2 id="aktivite-türünü-sınıflandırmak">Aktivite türünü sınıflandırmak</h2>

<p>Aktivite sınıflandırması için sinyal, örtüşmeli zaman pencerelerine bölünür. Her pencereden ortalama, standart sapma, maksimum değer, enerji ve baskın frekans gibi özellikler çıkarılır. Örneğin sinyal enerjisi şöyle hesaplanabilir:</p>

\[E = \frac{1}{N}\sum_{i=1}^{N}a_i^2\]

<table>
  <thead>
    <tr>
      <th>Aktivite</th>
      <th style="text-align: right">Standart sapma</th>
      <th style="text-align: right">Baskın frekans</th>
      <th style="text-align: right">Enerji</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Hareketsiz</td>
      <td style="text-align: right">Düşük</td>
      <td style="text-align: right">Belirsiz</td>
      <td style="text-align: right">Düşük</td>
    </tr>
    <tr>
      <td>Yürüme</td>
      <td style="text-align: right">Orta</td>
      <td style="text-align: right">1–2.5 Hz</td>
      <td style="text-align: right">Orta</td>
    </tr>
    <tr>
      <td>Koşma</td>
      <td style="text-align: right">Yüksek</td>
      <td style="text-align: right">2–4 Hz</td>
      <td style="text-align: right">Yüksek</td>
    </tr>
  </tbody>
</table>

<p>Bu özellikler Random Forest, SVM veya küçük bir sinir ağına verilebilir. Başlangıç için Random Forest; ölçeklemeye daha az duyarlı, hızlı ve yorumlanabilir olduğu için iyi bir seçimdir. Eğitim verisini farklı kişilerden, telefon konumlarından ve hızlardan toplamak kritik önemdedir. Aksi hâlde model kullanıcıyı değil, yalnızca belirli bir cebi ezberleyebilir!</p>

<p>Başarıyı değerlendirirken adım sayımı için ortalama mutlak hata; sınıflandırma için doğruluk, F1 skoru ve karmaşıklık matrisi kullanılmalıdır. Son aşamada işlemleri kısa pencerelerle gerçek zamanlı çalıştırarak pil tüketimi ile doğruluk arasında dengeli bir mobil aktivite takipçisi elde edebiliriz.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Proje" /><category term="ivmeölçer" /><category term="makine öğrenmesi" /><category term="sinyal işleme" /><summary type="html"><![CDATA[Telefonunuz cebinizde sessizce duruyor gibi görünse de ivmeölçer sensörü her saniye onlarca ölçüm üretir. Bu ham veriyi doğru biçimde işlediğimizde kaç adım atıldığını hesaplayabilir; kullanıcının yürüdüğünü, koştuğunu veya hareketsiz kaldığını tahmin edebiliriz. Bu projede gürültülü sensör değerlerini anlamlı aktivite bilgisine dönüştüren uçtan uca bir sistem kuracağız.]]></summary></entry><entry><title type="html">CNN ile Görsel Algı: Piksellerden Kenar, Doku ve Şekillere</title><link href="https://sonsuzus.github.io/posts/cnn-ile-gorsel-algi-piksellerden-kenar-doku-ve-sekillere/" rel="alternate" type="text/html" title="CNN ile Görsel Algı: Piksellerden Kenar, Doku ve Şekillere" /><published>2026-08-08T00:00:00+00:00</published><updated>2026-08-08T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/cnn-ile-gorsel-algi-piksellerden-kenar-doku-ve-sekillere</id><content type="html" xml:base="https://sonsuzus.github.io/posts/cnn-ile-gorsel-algi-piksellerden-kenar-doku-ve-sekillere/"><![CDATA[<p>Bir bilgisayar için fotoğraf, sevimli bir kedi veya kırmızı bir otomobil değil; yalnızca sayılardan oluşan çok boyutlu bir matristir. Evrişimli Sinir Ağları, yani CNN’ler, bu sayı yığınını anlamlandırarak kenarları, dokuları, şekilleri ve sonunda nesneleri keşfeder. Bunu yaparken görüntünün mekânsal yapısını koruyan evrişim filtrelerinden ve gereksiz ayrıntıları azaltan havuzlama işlemlerinden yararlanır.</p>

<p>``</p>

<h2 id="görüntü-bilgisayara-nasıl-görünür">Görüntü bilgisayara nasıl görünür?</h2>

<p>Gri tonlamalı bir görüntü $H \times W$ boyutlu bir matris, renkli görüntü ise genellikle $H \times W \times 3$ boyutlu bir tensördür. Son boyuttaki üç kanal kırmızı, yeşil ve maviyi temsil eder. Klasik tam bağlı ağlarda her piksel her nörona bağlanır; bu yaklaşım büyük görüntülerde devasa sayıda parametre üretir ve pikseller arasındaki komşuluk ilişkisini göz ardı eder.</p>

<p>CNN ise küçük bir filtreyi görüntü üzerinde gezdirir. Böylece hem daha az parametre kullanır hem de aynı özelliği görüntünün farklı bölgelerinde arayabilir. Bir kedinin kulağı sağda da olsa solda da olsa aynı filtre tarafından yakalanabilir.</p>

<h2 id="evrişim-görüntü-üzerinde-gezinen-büyüteç">Evrişim: Görüntü üzerinde gezinen büyüteç</h2>

<p>Evrişim katmanındaki filtre, örneğin $3 \times 3$ boyutunda öğrenilebilir bir ağırlık matrisidir. Filtre her konumda görüntünün ilgili bölgesiyle eleman bazında çarpılır ve sonuçlar toplanır:</p>

\[Y(i,j)=\sum_m\sum_n X(i+m,j+n)K(m,n)+b\]

<p>Burada $X$ giriş görüntüsünü, $K$ filtreyi, $b$ bias değerini ve $Y$ üretilen özellik haritasını gösterir. İlk katmanlar çoğunlukla yatay veya dikey kenarları öğrenir. Daha derin katmanlar bu basit bilgileri birleştirerek köşe, doku, göz, tekerlek veya kanat gibi daha karmaşık örüntüler oluşturur.</p>

<p>Çıktı boyutu yaklaşık olarak şu formülle hesaplanır:</p>

\[O=\left\lfloor\frac{N+2P-K}{S}\right\rfloor+1\]

<p>$N$ giriş boyutu, $K$ filtre boyutu, $P$ padding ve $S$ stride değeridir. Padding görüntünün kenarlarına boşluk eklerken stride filtrenin kaç piksel atlayacağını belirler.</p>

<table>
  <thead>
    <tr>
      <th>Kavram</th>
      <th>Görevi</th>
      <th>Etkisi</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Filtre</td>
      <td>Yerel özellikleri arar</td>
      <td>Kenar ve doku haritaları üretir</td>
    </tr>
    <tr>
      <td>Stride</td>
      <td>Filtrenin adımını belirler</td>
      <td>Boyutu ve hesaplama maliyetini değiştirir</td>
    </tr>
    <tr>
      <td>Padding</td>
      <td>Kenarlara değer ekler</td>
      <td>Mekânsal boyutu koruyabilir</td>
    </tr>
    <tr>
      <td>Aktivasyon</td>
      <td>Doğrusal olmayanlık ekler</td>
      <td>Karmaşık örüntülerin öğrenilmesini sağlar</td>
    </tr>
  </tbody>
</table>

<h2 id="havuzlama-önemli-bilgiyi-sıkıştırmak">Havuzlama: Önemli bilgiyi sıkıştırmak</h2>

<p>Pooling katmanı öğrenilebilir filtre taşımaz. Belirli bir pencere içindeki değerleri özetler. Max pooling en büyük değeri seçerken average pooling ortalamayı alır. Örneğin $2 \times 2$ max pooling, dört değerden en güçlü aktivasyonu saklar. Böylece özellik haritası küçülür, hesaplama hızlanır ve küçük konum değişikliklerine karşı dayanıklılık artar.</p>

<table>
  <thead>
    <tr>
      <th>Yöntem</th>
      <th>Seçim biçimi</th>
      <th>Kullanım karakteri</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Max Pooling</td>
      <td>En büyük değer</td>
      <td>Belirgin özellikleri korur</td>
    </tr>
    <tr>
      <td>Average Pooling</td>
      <td>Değerlerin ortalaması</td>
      <td>Daha yumuşak özet üretir</td>
    </tr>
    <tr>
      <td>Global Average Pooling</td>
      <td>Kanalın tamamının ortalaması</td>
      <td>Sınıflandırma öncesi parametreleri azaltır</td>
    </tr>
  </tbody>
</table>

<h2 id="pytorch-ile-küçük-bir-cnn">PyTorch ile küçük bir CNN</h2>

<p>Aşağıdaki model, renkli $32 \times 32$ görüntüleri on sınıftan birine ayırabilecek temel bir mimari kurar:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">torch.nn</span> <span class="k">as</span> <span class="n">nn</span>

<span class="k">class</span> <span class="nc">MiniCNN</span><span class="p">(</span><span class="n">nn</span><span class="p">.</span><span class="n">Module</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="n">self</span><span class="p">):</span>
        <span class="nf">super</span><span class="p">().</span><span class="nf">__init__</span><span class="p">()</span>
        <span class="n">self</span><span class="p">.</span><span class="n">features</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="nc">Sequential</span><span class="p">(</span>
            <span class="n">nn</span><span class="p">.</span><span class="nc">Conv2d</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">16</span><span class="p">,</span> <span class="n">kernel_size</span><span class="o">=</span><span class="mi">3</span><span class="p">,</span> <span class="n">padding</span><span class="o">=</span><span class="mi">1</span><span class="p">),</span>
            <span class="n">nn</span><span class="p">.</span><span class="nc">ReLU</span><span class="p">(),</span>
            <span class="n">nn</span><span class="p">.</span><span class="nc">MaxPool2d</span><span class="p">(</span><span class="mi">2</span><span class="p">),</span>
            <span class="n">nn</span><span class="p">.</span><span class="nc">Conv2d</span><span class="p">(</span><span class="mi">16</span><span class="p">,</span> <span class="mi">32</span><span class="p">,</span> <span class="n">kernel_size</span><span class="o">=</span><span class="mi">3</span><span class="p">,</span> <span class="n">padding</span><span class="o">=</span><span class="mi">1</span><span class="p">),</span>
            <span class="n">nn</span><span class="p">.</span><span class="nc">ReLU</span><span class="p">(),</span>
            <span class="n">nn</span><span class="p">.</span><span class="nc">MaxPool2d</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
        <span class="p">)</span>
        <span class="n">self</span><span class="p">.</span><span class="n">classifier</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="nc">Linear</span><span class="p">(</span><span class="mi">32</span> <span class="o">*</span> <span class="mi">8</span> <span class="o">*</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">10</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">forward</span><span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="n">x</span><span class="p">):</span>
        <span class="n">x</span> <span class="o">=</span> <span class="n">self</span><span class="p">.</span><span class="nf">features</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
        <span class="n">x</span> <span class="o">=</span> <span class="n">x</span><span class="p">.</span><span class="nf">flatten</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">self</span><span class="p">.</span><span class="nf">classifier</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
</code></pre></div></div>

<p>İlk evrişim katmanı RGB görüntüden 16 özellik haritası çıkarır. ReLU negatif değerleri sıfırlayarak modele doğrusal olmayanlık kazandırır. İki havuzlama işlemi görüntüyü $32 \times 32$ boyutundan $8 \times 8$ boyutuna indirir. Son katman ise çıkarılan özellikleri sınıf puanlarına dönüştürür.</p>

<p>CNN’lerin asıl gücü hiyerarşik öğrenmedir: erken katmanlar kenarları, orta katmanlar dokuları ve parçaları, derin katmanlar ise bütün nesneleri temsil eder. Bu nedenle CNN’ler yüz tanıma, tıbbi görüntü analizi, otonom sürüş ve kalite kontrol gibi alanlarda dijital dünyanın keskin gözleri hâline gelmiştir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="CNN" /><category term="Görüntü İşleme" /><category term="Derin Öğrenme" /><summary type="html"><![CDATA[Bir bilgisayar için fotoğraf, sevimli bir kedi veya kırmızı bir otomobil değil; yalnızca sayılardan oluşan çok boyutlu bir matristir. Evrişimli Sinir Ağları, yani CNN’ler, bu sayı yığınını anlamlandırarak kenarları, dokuları, şekilleri ve sonunda nesneleri keşfeder. Bunu yaparken görüntünün mekânsal yapısını koruyan evrişim filtrelerinden ve gereksiz ayrıntıları azaltan havuzlama işlemlerinden yararlanır.]]></summary></entry><entry><title type="html">Conway’in Hayat Oyunu’na Turbo Takmak: Hashlife Algoritması</title><link href="https://sonsuzus.github.io/posts/conwayin-hayat-oyununa-turbo-takmak-hashlife-algoritmasi/" rel="alternate" type="text/html" title="Conway’in Hayat Oyunu’na Turbo Takmak: Hashlife Algoritması" /><published>2026-08-08T00:00:00+00:00</published><updated>2026-08-08T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/conwayin-hayat-oyununa-turbo-takmak-hashlife-algoritmasi</id><content type="html" xml:base="https://sonsuzus.github.io/posts/conwayin-hayat-oyununa-turbo-takmak-hashlife-algoritmasi/"><![CDATA[<p>Conway’in Hayat Oyunu basit kurallardan şaşırtıcı derecede karmaşık yapılar üretir. Ancak milyonlarca hücreden oluşan bir evreni klasik yöntemle simüle etmek, her nesilde bütün ızgarayı taramak anlamına gelir. Glider filoları büyüdükçe işlemciniz de küçük bir yaşam krizi geçirebilir! Hashlife, tekrar eden uzay-zaman desenlerini tanıyıp sonuçlarını önbelleğe alarak devasa ve seyrek evrenlerde inanılmaz sıçramalar yapar.
``</p>
<h2 id="önce-oyunun-matematiği">Önce oyunun matematiği</h2>

<p>Her hücre canlı veya ölüdür. Hücrenin bir sonraki durumu, sekiz komşusundaki canlı hücre sayısına bağlıdır. $x_t(p) \in {0,1}$ hücrenin durumunu, $n_t(p)$ ise canlı komşu sayısını göstersin:</p>

\[x_{t+1}(p)=
\begin{cases}
1, &amp; n_t(p)=3 \\
1, &amp; x_t(p)=1 \land n_t(p)=2 \\
0, &amp; \text{diğer durumlarda}
\end{cases}\]

<p>Klasik simülasyon, genişliği $W$, yüksekliği $H$ olan bir alan için her nesilde yaklaşık $O(WH)$ iş yapar. Hashlife’ın gücü ise tek bir sabit karmaşıklık formülünden değil; daha önce gördüğü alt evrenleri tekrar hesaplamamasından gelir.</p>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th>Uzay gösterimi</th>
      <th>Zaman ilerletme</th>
      <th>Güçlü olduğu durum</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Dizi tabanlı</td>
      <td>Tüm hücreler</td>
      <td>Birer nesil</td>
      <td>Küçük, yoğun alanlar</td>
    </tr>
    <tr>
      <td>Seyrek küme</td>
      <td>Yalnızca canlı hücreler</td>
      <td>Birer nesil</td>
      <td>Dağınık ve hareketli desenler</td>
    </tr>
    <tr>
      <td>Hashlife</td>
      <td>Paylaşılan dört ağaç</td>
      <td>Üstel sıçramalar</td>
      <td>Büyük, tekrarlı ve seyrek evrenler</td>
    </tr>
  </tbody>
</table>

<h2 id="izgara-yerine-dört-ağaç">Izgara yerine dört ağaç</h2>

<p>Hashlife, evreni kenar uzunluğu $2^k$ olan karelere böler. Her kare; kuzeybatı, kuzeydoğu, güneybatı ve güneydoğu çocuklarından oluşan bir <strong>quadtree</strong> düğümüdür. Aynı dört çocuğa sahip düğümler yalnızca bir kez saklanır. Buna hash-consing denir.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Node</span><span class="p">:</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="n">level</span><span class="p">,</span> <span class="n">nw</span><span class="p">,</span> <span class="n">ne</span><span class="p">,</span> <span class="n">sw</span><span class="p">,</span> <span class="n">se</span><span class="p">):</span>
        <span class="n">self</span><span class="p">.</span><span class="n">level</span> <span class="o">=</span> <span class="n">level</span>
        <span class="n">self</span><span class="p">.</span><span class="n">children</span> <span class="o">=</span> <span class="p">(</span><span class="n">nw</span><span class="p">,</span> <span class="n">ne</span><span class="p">,</span> <span class="n">sw</span><span class="p">,</span> <span class="n">se</span><span class="p">)</span>
        <span class="n">self</span><span class="p">.</span><span class="n">population</span> <span class="o">=</span> <span class="nf">sum</span><span class="p">(</span><span class="n">c</span><span class="p">.</span><span class="n">population</span> <span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="n">self</span><span class="p">.</span><span class="n">children</span><span class="p">)</span>
        <span class="n">self</span><span class="p">.</span><span class="n">result</span> <span class="o">=</span> <span class="bp">None</span>

<span class="n">node_cache</span> <span class="o">=</span> <span class="p">{}</span>

<span class="k">def</span> <span class="nf">make_node</span><span class="p">(</span><span class="n">level</span><span class="p">,</span> <span class="n">nw</span><span class="p">,</span> <span class="n">ne</span><span class="p">,</span> <span class="n">sw</span><span class="p">,</span> <span class="n">se</span><span class="p">):</span>
    <span class="n">key</span> <span class="o">=</span> <span class="p">(</span><span class="n">level</span><span class="p">,</span> <span class="nf">id</span><span class="p">(</span><span class="n">nw</span><span class="p">),</span> <span class="nf">id</span><span class="p">(</span><span class="n">ne</span><span class="p">),</span> <span class="nf">id</span><span class="p">(</span><span class="n">sw</span><span class="p">),</span> <span class="nf">id</span><span class="p">(</span><span class="n">se</span><span class="p">))</span>
    <span class="k">if</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">node_cache</span><span class="p">:</span>
        <span class="n">node_cache</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="nc">Node</span><span class="p">(</span><span class="n">level</span><span class="p">,</span> <span class="n">nw</span><span class="p">,</span> <span class="n">ne</span><span class="p">,</span> <span class="n">sw</span><span class="p">,</span> <span class="n">se</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">node_cache</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
</code></pre></div></div>

<p>Bu fabrika fonksiyonu eşdeğer bölgelerin aynı nesneyi paylaşmasını sağlar. Gerçek uygulamada <code class="language-plaintext highlighter-rouge">id</code> yerine çocuk düğümlerin kararlı kimlikleri veya doğrudan nesne referansları kullanılabilir. <code class="language-plaintext highlighter-rouge">population == 0</code> kontrolüyle tamamen boş bölgeler anında atlanır.</p>

<h2 id="zamanı-neden-katlayabiliyoruz">Zamanı neden katlayabiliyoruz?</h2>

<p>Bir seviyedeki düğümün merkez bölgesinin $2^{k-2}$ nesil sonraki sonucu hesaplanıp düğümde saklanır. Bunun mümkün olmasının nedeni bilgi yayılım hızıdır: Bir hücrenin etkisi her nesilde en fazla bir hücre uzaklaşabilir. Dış kenarlardan yeterince uzak merkez bölge, belirlenen süre boyunca düğüm dışındaki hücrelerden etkilenmez.</p>

<p>Algoritma, çakışan dokuz alt bölge oluşturur; bunların sonuçlarını özyinelemeli hesaplar ve merkezdeki dört sonucu birleştirir. Aynı alt desen yeniden görüldüğünde simülasyon yapmak yerine önbellekteki gelecek doğrudan döndürülür.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">advance</span><span class="p">(</span><span class="n">node</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">node</span><span class="p">.</span><span class="n">result</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">node</span><span class="p">.</span><span class="n">result</span>
    <span class="k">if</span> <span class="n">node</span><span class="p">.</span><span class="n">population</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
        <span class="n">node</span><span class="p">.</span><span class="n">result</span> <span class="o">=</span> <span class="nf">empty_node</span><span class="p">(</span><span class="n">node</span><span class="p">.</span><span class="n">level</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">node</span><span class="p">.</span><span class="n">result</span>
    <span class="k">if</span> <span class="n">node</span><span class="p">.</span><span class="n">level</span> <span class="o">==</span> <span class="mi">2</span><span class="p">:</span>
        <span class="n">node</span><span class="p">.</span><span class="n">result</span> <span class="o">=</span> <span class="nf">evolve_base_case</span><span class="p">(</span><span class="n">node</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">node</span><span class="p">.</span><span class="n">result</span>

    <span class="n">regions</span> <span class="o">=</span> <span class="nf">overlapping_subnodes</span><span class="p">(</span><span class="n">node</span><span class="p">)</span>
    <span class="n">futures</span> <span class="o">=</span> <span class="p">[</span><span class="nf">advance</span><span class="p">(</span><span class="n">region</span><span class="p">)</span> <span class="k">for</span> <span class="n">region</span> <span class="ow">in</span> <span class="n">regions</span><span class="p">]</span>
    <span class="n">node</span><span class="p">.</span><span class="n">result</span> <span class="o">=</span> <span class="nf">combine_center</span><span class="p">(</span><span class="n">futures</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">node</span><span class="p">.</span><span class="n">result</span>
</code></pre></div></div>

<p>Kod, Hashlife’ın temel fikrini gösterir: sonucu biliyorsan kullan, bölge boşsa kısa devre yap, küçükse doğrudan hesapla, büyükse parçalayıp birleştir.</p>

<h2 id="pratik-mühendislik-notları">Pratik mühendislik notları</h2>

<p>Evren kökünün çevresine boşluk eklemek önemlidir; desen sınıra yaklaşırsa kök iki kat büyütülmelidir. Ayrıca bellek önbelleği sınırsız bırakılmamalı, erişilmeyen düğümler çöp toplama veya yaş tabanlı temizleme ile kaldırılmalıdır.</p>

<p>Hashlife her durumda sihirli değildir. Rastgele gürültülü desenlerde tekrar az olduğundan hash tabloları ek maliyet yaratabilir. Buna karşılık durağan yapılar, osilatörler ve uzun mesafe yol alan glider’lar bol tekrar üretir. Doğru evrende Hashlife yalnızca daha hızlı koşmaz; milyonlarca nesli tek tek yaşamadan geleceğe adeta ışınlanır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="hashlife" /><category term="conway-hayat-oyunu" /><category term="algoritma" /><summary type="html"><![CDATA[Conway’in Hayat Oyunu basit kurallardan şaşırtıcı derecede karmaşık yapılar üretir. Ancak milyonlarca hücreden oluşan bir evreni klasik yöntemle simüle etmek, her nesilde bütün ızgarayı taramak anlamına gelir. Glider filoları büyüdükçe işlemciniz de küçük bir yaşam krizi geçirebilir! Hashlife, tekrar eden uzay-zaman desenlerini tanıyıp sonuçlarını önbelleğe alarak devasa ve seyrek evrenlerde inanılmaz sıçramalar yapar.]]></summary></entry><entry><title type="html">Derin Öğrenmeye Giriş: Katmanlar, Soyut Özellikler ve GPU Gücü</title><link href="https://sonsuzus.github.io/posts/derin-ogrenmeye-giris-katmanlar-soyut-ozellikler-ve-gpu-gucu/" rel="alternate" type="text/html" title="Derin Öğrenmeye Giriş: Katmanlar, Soyut Özellikler ve GPU Gücü" /><published>2026-08-08T00:00:00+00:00</published><updated>2026-08-08T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/derin-ogrenmeye-giris-katmanlar-soyut-ozellikler-ve-gpu-gucu</id><content type="html" xml:base="https://sonsuzus.github.io/posts/derin-ogrenmeye-giris-katmanlar-soyut-ozellikler-ve-gpu-gucu/"><![CDATA[<p>Bir bilgisayara kediyi tanımayı öğretmek istediğimizi düşünelim. Geleneksel yaklaşımda sivri kulak, bıyık ve kuyruk gibi özellikleri tek tek tarif etmemiz gerekebilir. Derin öğrenmede ise modele yeterli sayıda örnek gösteririz; hangi ayrıntıların önemli olduğunu katmanlar boyunca kendisi keşfeder. İşin büyülü görünen, fakat matematik ve bol miktarda hesaplama gücüne dayanan kısmı tam olarak budur.</p>

<p>``</p>

<h2 id="derin-öğrenme-neden-derin">Derin öğrenme neden “derin”?</h2>

<p>Yapay sinir ağları, girdileri belirli ağırlıklarla işleyen yapay nöronlardan oluşur. Tek bir nöronun temel işlemi şöyle gösterilebilir:</p>

\[z = \sum_{i=1}^{n} w_i x_i + b\]

<p>Burada $x_i$ girdileri, $w_i$ öğrenilen ağırlıkları, $b$ ise bias değerini temsil eder. Sonuç genellikle ReLU gibi doğrusal olmayan bir aktivasyon fonksiyonundan geçirilir:</p>

\[\operatorname{ReLU}(z)=\max(0,z)\]

<p>Bir ağın “derin” olması, giriş ile çıkış arasında birden fazla gizli katman bulunması anlamına gelir. Katman sayısı arttıkça model, özellikleri hiyerarşik biçimde birleştirebilir. Bir görüntü ağının ilk katmanları kenarları, sonraki katmanları dokuları, daha ilerideki katmanları ise göz, tekerlek veya yüz gibi soyut yapıları öğrenebilir.</p>

<table>
  <thead>
    <tr>
      <th>Mimari düzeyi</th>
      <th>Öğrenilebilen özellik</th>
      <th>Görüntü örneği</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>İlk katmanlar</td>
      <td>Kenar, yön ve renk geçişi</td>
      <td>Dikey çizgi</td>
    </tr>
    <tr>
      <td>Orta katmanlar</td>
      <td>Doku ve basit şekil</td>
      <td>Kürk veya daire</td>
    </tr>
    <tr>
      <td>Derin katmanlar</td>
      <td>Nesne parçaları</td>
      <td>Kulak veya göz</td>
    </tr>
    <tr>
      <td>Çıkış katmanı</td>
      <td>Sınıf veya tahmin</td>
      <td>Kedi olasılığı</td>
    </tr>
  </tbody>
</table>

<p>Bu özellikler geliştirici tarafından elle yazılmaz. Eğitim sırasında tahmin hatası geriye yayılım ile katmanlara dağıtılır. Ağırlıklar, kayıp fonksiyonunu azaltacak yönde güncellenir:</p>

\[w \leftarrow w-\eta\frac{\partial L}{\partial w}\]

<p>Buradaki $L$ kayıp fonksiyonu, $\eta$ ise öğrenme oranıdır. Kısacası ağ, hatalarından ders çıkarır; ancak bunu kahve molası vermeden milyonlarca kez yapar.</p>

<h2 id="gpu-neden-bu-kadar-önemli">GPU neden bu kadar önemli?</h2>

<p>Derin ağların eğitimi çok sayıda matris çarpımı gerektirir. CPU az sayıda güçlü çekirdekle genel amaçlı işlemlerde başarılıdır. GPU ise binlerce daha küçük çekirdeği sayesinde aynı türden matematiksel işlemleri paralel çalıştırabilir.</p>

<table>
  <thead>
    <tr>
      <th>Donanım</th>
      <th>Güçlü olduğu alan</th>
      <th>Derin öğrenmedeki rolü</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>CPU</td>
      <td>Sıralı işlemler ve uygulama mantığı</td>
      <td>Veri hazırlama, küçük modeller</td>
    </tr>
    <tr>
      <td>GPU</td>
      <td>Yoğun paralel hesaplama</td>
      <td>Eğitim ve hızlı çıkarım</td>
    </tr>
    <tr>
      <td>TPU/NPU</td>
      <td>Yapay zekâya özel işlemler</td>
      <td>Büyük ölçekli veya mobil modeller</td>
    </tr>
  </tbody>
</table>

<p>GPU seçiminde yalnızca işlem hızı değil, VRAM kapasitesi de önemlidir. Model parametreleri, ara aktivasyonlar ve gradyanlar bellekte tutulur. Bellek yetmediğinde batch boyutu küçültülebilir, karma hassasiyet kullanılabilir veya model birkaç GPU’ya dağıtılabilir. Daha büyük GPU her zaman daha akıllı model demek değildir; bazen yalnızca elektrik faturasının daha atletik olması demektir.</p>

<h2 id="pytorch-ile-cihaz-seçimi">PyTorch ile cihaz seçimi</h2>

<p>Aşağıdaki örnek, varsa CUDA destekli GPU’yu seçer ve basit bir ağı ilgili cihaza taşır:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">torch</span>
<span class="kn">from</span> <span class="n">torch</span> <span class="kn">import</span> <span class="n">nn</span>

<span class="n">device</span> <span class="o">=</span> <span class="n">torch</span><span class="p">.</span><span class="nf">device</span><span class="p">(</span><span class="sh">'</span><span class="s">cuda</span><span class="sh">'</span> <span class="k">if</span> <span class="n">torch</span><span class="p">.</span><span class="n">cuda</span><span class="p">.</span><span class="nf">is_available</span><span class="p">()</span> <span class="k">else</span> <span class="sh">'</span><span class="s">cpu</span><span class="sh">'</span><span class="p">)</span>

<span class="n">model</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="nc">Sequential</span><span class="p">(</span>
    <span class="n">nn</span><span class="p">.</span><span class="nc">Linear</span><span class="p">(</span><span class="mi">784</span><span class="p">,</span> <span class="mi">256</span><span class="p">),</span>
    <span class="n">nn</span><span class="p">.</span><span class="nc">ReLU</span><span class="p">(),</span>
    <span class="n">nn</span><span class="p">.</span><span class="nc">Linear</span><span class="p">(</span><span class="mi">256</span><span class="p">,</span> <span class="mi">10</span><span class="p">)</span>
<span class="p">).</span><span class="nf">to</span><span class="p">(</span><span class="n">device</span><span class="p">)</span>

<span class="n">sample</span> <span class="o">=</span> <span class="n">torch</span><span class="p">.</span><span class="nf">randn</span><span class="p">(</span><span class="mi">64</span><span class="p">,</span> <span class="mi">784</span><span class="p">).</span><span class="nf">to</span><span class="p">(</span><span class="n">device</span><span class="p">)</span>
<span class="n">predictions</span> <span class="o">=</span> <span class="nf">model</span><span class="p">(</span><span class="n">sample</span><span class="p">)</span>
<span class="nf">print</span><span class="p">(</span><span class="n">device</span><span class="p">,</span> <span class="n">predictions</span><span class="p">.</span><span class="n">shape</span><span class="p">)</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">to(device)</code> çağrısı hem modelin hem de verinin aynı donanıma taşınmasını sağlar. Aksi hâlde PyTorch, CPU ve GPU tensörlerini birlikte işleyemediği için hata üretir.</p>

<h2 id="avantajlar-ve-sınırlar">Avantajlar ve sınırlar</h2>

<p>Derin öğrenme; görüntü tanıma, doğal dil işleme, ses analizi ve üretken yapay zekâda elle özellik çıkarma ihtiyacını azaltır. Büyük ve karmaşık verilerde klasik yöntemlerden daha yüksek başarı sağlayabilir. Ayrıca önceden eğitilmiş modeller, transfer öğrenme ile daha küçük veri kümelerine uyarlanabilir.</p>

<p>Buna karşılık derin mimariler çok veri, enerji, zaman ve dikkatli hiperparametre ayarı ister. Katman eklemek başarıyı otomatik olarak artırmaz; aşırı öğrenme, kaybolan gradyan ve yüksek gecikme gibi sorunlar doğabilir. En iyi yaklaşım, probleme yetecek kadar derin bir model seçmek ve donanım gücünü ölçüm sonuçlarına göre kullanmaktır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="derin öğrenme" /><category term="yapay sinir ağları" /><category term="GPU" /><summary type="html"><![CDATA[Bir bilgisayara kediyi tanımayı öğretmek istediğimizi düşünelim. Geleneksel yaklaşımda sivri kulak, bıyık ve kuyruk gibi özellikleri tek tek tarif etmemiz gerekebilir. Derin öğrenmede ise modele yeterli sayıda örnek gösteririz; hangi ayrıntıların önemli olduğunu katmanlar boyunca kendisi keşfeder. İşin büyülü görünen, fakat matematik ve bol miktarda hesaplama gücüne dayanan kısmı tam olarak budur.]]></summary></entry><entry><title type="html">GAN ve Difüzyon Modelleri: Rekabetten Gürültüye Üretken Yapay Zekâ</title><link href="https://sonsuzus.github.io/posts/gan-ve-difuzyon-modelleri-rekabetten-gurultuye-uretken-yapay-zeka/" rel="alternate" type="text/html" title="GAN ve Difüzyon Modelleri: Rekabetten Gürültüye Üretken Yapay Zekâ" /><published>2026-08-08T00:00:00+00:00</published><updated>2026-08-08T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/gan-ve-difuzyon-modelleri-rekabetten-gurultuye-uretken-yapay-zeka</id><content type="html" xml:base="https://sonsuzus.github.io/posts/gan-ve-difuzyon-modelleri-rekabetten-gurultuye-uretken-yapay-zeka/"><![CDATA[<p>Bir yapay zekânın sıfırdan insan yüzü çizdiğini, kısa bir melodi bestelediğini veya birkaç kelimelik komuttan video ürettiğini düşünün. Bu sihrin arkasında çoğunlukla iki güçlü yaklaşım bulunur: birbirini alt etmeye çalışan ağlardan oluşan <strong>Üretken Çekişmeli Ağlar (GAN)</strong> ve gürültüyü adım adım temizleyen <strong>difüzyon modelleri</strong>. İkisi de öğrendiği veri dağılımından yeni örnekler üretir; ancak hedefe giderken tamamen farklı yollar izler.</p>

<p>``</p>

<h2 id="gan-sahtekâr-ile-dedektifin-oyunu">GAN: Sahtekâr ile dedektifin oyunu</h2>

<p>GAN, 2014 yılında Ian Goodfellow ve çalışma arkadaşları tarafından tanıtıldı. Yapı, iki sinir ağından oluşur:</p>

<ul>
  <li><strong>Üretici (Generator):</strong> Rastgele gürültüyü gerçekçi bir örneğe dönüştürmeye çalışır.</li>
  <li><strong>Ayırt edici (Discriminator):</strong> Karşısındaki örneğin gerçek veriden mi yoksa üreticiden mi geldiğini tahmin eder.</li>
</ul>

<p>Üreticiyi sahte tablo yapan bir ressama, ayırt ediciyi ise sanat uzmanına benzetebiliriz. Ressam geliştikçe uzman daha dikkatli olur; uzman geliştikçe ressam daha başarılı sahte eserler üretmek zorunda kalır.</p>

<p>Bu rekabetin klasik amaç fonksiyonu şöyledir:</p>

\[\min_G \max_D V(D,G)=\mathbb{E}_{x\sim p_{data}}[\log D(x)] + \mathbb{E}_{z\sim p_z}[\log(1-D(G(z)))]\]

<p>Burada $G(z)$ üreticinin gürültüden oluşturduğu örneği, $D(x)$ ise bir örneğin gerçek olma olasılığını gösterir. İdeal dengede ayırt edici artık gerçeği sahteden ayıramaz ve her örnek için yaklaşık $0.5$ sonucu verir.</p>

<p>GAN eğitiminin sadeleştirilmiş PyTorch benzeri akışı şöyledir:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Önce ayırt edici, gerçek ve sahte örnekleri tanımayı öğrenir.
</span><span class="n">noise</span> <span class="o">=</span> <span class="n">torch</span><span class="p">.</span><span class="nf">randn</span><span class="p">(</span><span class="n">batch_size</span><span class="p">,</span> <span class="n">latent_size</span><span class="p">)</span>
<span class="n">fake_images</span> <span class="o">=</span> <span class="nf">generator</span><span class="p">(</span><span class="n">noise</span><span class="p">)</span>

<span class="n">d_loss</span> <span class="o">=</span> <span class="nf">discriminator_loss</span><span class="p">(</span>
    <span class="nf">discriminator</span><span class="p">(</span><span class="n">real_images</span><span class="p">),</span>
    <span class="nf">discriminator</span><span class="p">(</span><span class="n">fake_images</span><span class="p">.</span><span class="nf">detach</span><span class="p">())</span>
<span class="p">)</span>
<span class="n">d_loss</span><span class="p">.</span><span class="nf">backward</span><span class="p">()</span>
<span class="n">d_optimizer</span><span class="p">.</span><span class="nf">step</span><span class="p">()</span>

<span class="c1"># Ardından üretici, ayırt ediciyi kandıracak şekilde güncellenir.
</span><span class="n">g_loss</span> <span class="o">=</span> <span class="nf">generator_loss</span><span class="p">(</span><span class="nf">discriminator</span><span class="p">(</span><span class="n">fake_images</span><span class="p">))</span>
<span class="n">g_loss</span><span class="p">.</span><span class="nf">backward</span><span class="p">()</span>
<span class="n">g_optimizer</span><span class="p">.</span><span class="nf">step</span><span class="p">()</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">detach()</code> kullanımı önemlidir: Ayırt edici eğitilirken gradyanların üreticiye akmasını engeller. Sonraki aşamada ise üretici, ayırt edicinin geri bildiriminden doğrudan yararlanır.</p>

<h2 id="difüzyon-gürültüden-düzene-yolculuk">Difüzyon: Gürültüden düzene yolculuk</h2>

<p>Difüzyon modelleri farklı bir oyun oynar. Eğitim sırasında temiz veriye aşamalı olarak Gauss gürültüsü eklenir. İleri süreç yaklaşık olarak şu şekilde ifade edilir:</p>

\[x_t=\sqrt{\bar{\alpha}_t}x_0+\sqrt{1-\bar{\alpha}_t}\epsilon\]

<p>Burada $x_0$ temiz örnek, $x_t$ gürültülü örnek ve $\epsilon$ rastgele gürültüdür. Sinir ağı, belirli bir adımdaki gürültüyü tahmin etmeyi öğrenir. Üretim aşamasında tamamen rastgele bir görüntüden başlanır ve tahmin edilen gürültü defalarca çıkarılır. Bulanık lekeler önce şekillere, ardından ayrıntılı bir görsele dönüşür.</p>

<p>Basitleştirilmiş örnekleme döngüsü şöyledir:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Üretim tamamen rastgele gürültüyle başlar.
</span><span class="n">x</span> <span class="o">=</span> <span class="n">torch</span><span class="p">.</span><span class="nf">randn</span><span class="p">(</span><span class="n">image_shape</span><span class="p">)</span>

<span class="k">for</span> <span class="n">timestep</span> <span class="ow">in</span> <span class="nf">reversed</span><span class="p">(</span><span class="nf">range</span><span class="p">(</span><span class="n">total_steps</span><span class="p">)):</span>
    <span class="n">predicted_noise</span> <span class="o">=</span> <span class="nf">model</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">timestep</span><span class="p">)</span>
    <span class="n">x</span> <span class="o">=</span> <span class="n">scheduler</span><span class="p">.</span><span class="nf">remove_noise</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">predicted_noise</span><span class="p">,</span> <span class="n">timestep</span><span class="p">)</span>

<span class="c1"># x artık modelin ürettiği temiz örnektir.
</span></code></pre></div></div>

<p>Gerçek sistemlerde zaman adımı kodlamaları, U-Net mimarileri, dikkat mekanizmaları ve özel gürültü zamanlayıcıları kullanılır. Metin komutları da gömleme vektörlerine çevrilerek üretim sürecini yönlendirebilir.</p>

<h2 id="gan-mı-difüzyon-mu">GAN mı, difüzyon mu?</h2>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>GAN</th>
      <th>Difüzyon modeli</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Temel mantık</td>
      <td>İki ağın rekabeti</td>
      <td>Gürültüyü aşamalı temizleme</td>
    </tr>
    <tr>
      <td>Eğitim kararlılığı</td>
      <td>Hassas ve dengesiz olabilir</td>
      <td>Genellikle daha kararlı</td>
    </tr>
    <tr>
      <td>Üretim hızı</td>
      <td>Tek geçişle hızlı</td>
      <td>Çok sayıda adım nedeniyle yavaş</td>
    </tr>
    <tr>
      <td>Çeşitlilik</td>
      <td>Mod çökmesi yaşayabilir</td>
      <td>Veri çeşitliliğini iyi kapsar</td>
    </tr>
    <tr>
      <td>Görsel kalite</td>
      <td>Keskin sonuçlar</td>
      <td>Ayrıntılı ve yüksek kaliteli sonuçlar</td>
    </tr>
    <tr>
      <td>Kontrol edilebilirlik</td>
      <td>Ek mimariler gerektirebilir</td>
      <td>Metin ve koşullarla güçlü kontrol</td>
    </tr>
  </tbody>
</table>

<p>GAN’ler gerçek zamanlı yüz dönüştürme, görüntü iyileştirme ve hızlı sentez için hâlâ değerlidir. Difüzyon modelleri ise metinden görsel, ses ve video üretiminde öne çıkar. Kısacası GAN bir düello, difüzyon ise sabırlı bir restorasyon sürecidir. Hangisinin seçileceği; hız, kalite, donanım maliyeti ve üretim üzerindeki kontrol ihtiyacına bağlıdır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="GAN" /><category term="Difüzyon Modelleri" /><category term="Üretken Yapay Zekâ" /><summary type="html"><![CDATA[Bir yapay zekânın sıfırdan insan yüzü çizdiğini, kısa bir melodi bestelediğini veya birkaç kelimelik komuttan video ürettiğini düşünün. Bu sihrin arkasında çoğunlukla iki güçlü yaklaşım bulunur: birbirini alt etmeye çalışan ağlardan oluşan Üretken Çekişmeli Ağlar (GAN) ve gürültüyü adım adım temizleyen difüzyon modelleri. İkisi de öğrendiği veri dağılımından yeni örnekler üretir; ancak hedefe giderken tamamen farklı yollar izler.]]></summary></entry><entry><title type="html">Kelimeleri Sayılardan Anlama: NLP ve Word Embeddings Rehberi</title><link href="https://sonsuzus.github.io/posts/kelimeleri-sayilardan-anlama-nlp-ve-word-embeddings-rehberi/" rel="alternate" type="text/html" title="Kelimeleri Sayılardan Anlama: NLP ve Word Embeddings Rehberi" /><published>2026-08-08T00:00:00+00:00</published><updated>2026-08-08T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/kelimeleri-sayilardan-anlama-nlp-ve-word-embeddings-rehberi</id><content type="html" xml:base="https://sonsuzus.github.io/posts/kelimeleri-sayilardan-anlama-nlp-ve-word-embeddings-rehberi/"><![CDATA[<p>İnsanlar için “kedi”, “köpek” ve “uçak” kelimelerini ayırmak kolaydır: İlk ikisi hayvandır, üçüncüsü ise gökyüzünde dolaşan metal bir araçtır. Bilgisayar açısından bakıldığındayse hepsi yalnızca karakter dizileridir. Doğal Dil İşleme (NLP), bu karakterlerin ardındaki anlamı makinelerin işleyebileceği matematiksel temsillere dönüştürür. Kelime gömme yöntemleri de tam burada devreye girerek kelimelere sayısal birer kimlik değil, anlamsal birer koordinat kazandırır.
``</p>

<h2 id="bilgisayar-kelimeleri-nasıl-görür">Bilgisayar kelimeleri nasıl görür?</h2>

<p>En temel yaklaşım, her kelimeyi sözlükteki konumuna göre temsil eden <strong>one-hot encoding</strong> yöntemidir. Örneğin sözlüğümüzde üç kelime varsa “kedi” şu şekilde gösterilebilir:</p>

\[kedi = [1, 0, 0]\]

<p>“köpek” ise:</p>

\[köpek = [0, 1, 0]\]

<p>Bu vektörler farklı kelimeleri ayırır ancak aralarındaki anlam ilişkisini taşımaz. Matematiksel olarak “kedi” ile “köpek”, “kedi” ile “uçak” kadar uzaktır. Ayrıca sözlük yüz binlerce kelime içeriyorsa vektörler gereksiz derecede büyük ve seyrek olur.</p>

<p>Word embeddings, her kelimeyi genellikle 50–300 boyutlu yoğun bir vektörle temsil eder. Eğitim sırasında benzer bağlamlarda kullanılan kelimeler vektör uzayında birbirine yaklaşır. Bu fikir, dağılımsal anlambilimin meşhur özetine dayanır: <strong>Bir kelimeyi, birlikte bulunduğu kelimelerden tanırsın.</strong></p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>One-hot</th>
      <th>Word Embedding</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Boyut</td>
      <td>Sözlük büyüklüğü</td>
      <td>Sabit ve daha küçük</td>
    </tr>
    <tr>
      <td>Yapı</td>
      <td>Seyrek</td>
      <td>Yoğun</td>
    </tr>
    <tr>
      <td>Anlamsal ilişki</td>
      <td>Yok</td>
      <td>Var</td>
    </tr>
    <tr>
      <td>Öğrenilebilirlik</td>
      <td>Sabit temsil</td>
      <td>Veriden öğrenilir</td>
    </tr>
  </tbody>
</table>

<h2 id="word2vec-komşuna-bak-kelimeyi-tanı">Word2Vec: Komşuna bak, kelimeyi tanı</h2>

<p>Word2Vec, kelimelerin yakın çevresinden yararlanır ve iki temel mimari sunar:</p>

<ul>
  <li><strong>CBOW</strong>, çevredeki kelimelerden merkezdeki kelimeyi tahmin eder.</li>
  <li><strong>Skip-gram</strong>, merkez kelimeden çevredeki kelimeleri tahmin eder.</li>
</ul>

<p>“Minik kedi koltukta uyudu” cümlesinde CBOW, “minik” ve “koltukta” kelimelerinden “kedi”yi bulmaya çalışabilir. Skip-gram ise “kedi” verildiğinde çevresindeki sözcükleri tahmin eder. Büyük veri kümelerinde Skip-gram, nadir kelimeleri öğrenmekte çoğu zaman daha başarılıdır.</p>

<p>İki vektörün anlamsal yakınlığı sıklıkla kosinüs benzerliğiyle ölçülür:</p>

\[cos(\theta) = \frac{A \cdot B}{||A||\,||B||}\]

<p>Sonuç 1’e yaklaştıkça yönler ve dolayısıyla anlamlar daha benzerdir. Ünlü vektör aritmetiği örneği de şöyledir:</p>

\[kral - erkek + kadın \approx kraliçe\]

<h2 id="glove-büyük-resmin-istatistiği">GloVe: Büyük resmin istatistiği</h2>

<p><strong>GloVe</strong>, yalnızca yerel kelime pencerelerine odaklanmak yerine bütün metindeki ortak görülme sayılarını kullanır. Bir kelimenin başka kelimelerle kaç kez yan yana geldiğini içeren eş-oluşum matrisi oluşturulur. Model, bu küresel istatistikleri düşük boyutlu vektörlere sıkıştırır.</p>

<table>
  <thead>
    <tr>
      <th>Yöntem</th>
      <th>Temel bilgi kaynağı</th>
      <th>Güçlü yanı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Word2Vec</td>
      <td>Yerel bağlam pencereleri</td>
      <td>Hızlı ve sezgisel eğitim</td>
    </tr>
    <tr>
      <td>GloVe</td>
      <td>Küresel eş-oluşum istatistikleri</td>
      <td>Genel dağılımı iyi yakalama</td>
    </tr>
  </tbody>
</table>

<h2 id="python-ile-hazır-vektörleri-kullanmak">Python ile hazır vektörleri kullanmak</h2>

<p>Aşağıdaki örnek, Gensim üzerinden hazır GloVe vektörlerini yükler ve “computer” kelimesine yakın sözcükleri getirir:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">gensim.downloader</span> <span class="k">as</span> <span class="n">api</span>

<span class="c1"># Önceden eğitilmiş 50 boyutlu GloVe modelini indirir.
</span><span class="n">model</span> <span class="o">=</span> <span class="n">api</span><span class="p">.</span><span class="nf">load</span><span class="p">(</span><span class="sh">"</span><span class="s">glove-wiki-gigaword-50</span><span class="sh">"</span><span class="p">)</span>

<span class="c1"># Vektör uzayındaki en yakın kelimeleri listeler.
</span><span class="k">for</span> <span class="n">word</span><span class="p">,</span> <span class="n">score</span> <span class="ow">in</span> <span class="n">model</span><span class="p">.</span><span class="nf">most_similar</span><span class="p">(</span><span class="sh">"</span><span class="s">computer</span><span class="sh">"</span><span class="p">,</span> <span class="n">topn</span><span class="o">=</span><span class="mi">5</span><span class="p">):</span>
    <span class="nf">print</span><span class="p">(</span><span class="n">word</span><span class="p">,</span> <span class="nf">round</span><span class="p">(</span><span class="n">score</span><span class="p">,</span> <span class="mi">3</span><span class="p">))</span>
</code></pre></div></div>

<p>Model, “software” veya “computers” gibi sözcükleri yüksek benzerlik puanlarıyla döndürebilir. Ancak klasik Word2Vec ve GloVe modellerinde her kelimenin yalnızca tek vektörü vardır. Bu nedenle “yüz” kelimesinin insan yüzü ve sayı anlamları bağlama göre ayrılamaz. BERT gibi bağlamsal modeller bu sınırlamayı giderse de kelime gömmeler; arama, öneri sistemleri, duygu analizi ve metin sınıflandırma projelerinde hâlâ hızlı, öğretici ve güçlü bir başlangıç noktasıdır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="NLP" /><category term="Word2Vec" /><category term="GloVe" /><summary type="html"><![CDATA[İnsanlar için “kedi”, “köpek” ve “uçak” kelimelerini ayırmak kolaydır: İlk ikisi hayvandır, üçüncüsü ise gökyüzünde dolaşan metal bir araçtır. Bilgisayar açısından bakıldığındayse hepsi yalnızca karakter dizileridir. Doğal Dil İşleme (NLP), bu karakterlerin ardındaki anlamı makinelerin işleyebileceği matematiksel temsillere dönüştürür. Kelime gömme yöntemleri de tam burada devreye girerek kelimelere sayısal birer kimlik değil, anlamsal birer koordinat kazandırır.]]></summary></entry><entry><title type="html">Metinlerin Ruh Hâlini Okuyan Temel Bir Duygu Analizi Motoru</title><link href="https://sonsuzus.github.io/posts/metinlerin-ruh-halini-okuyan-temel-bir-duygu-analizi-motoru/" rel="alternate" type="text/html" title="Metinlerin Ruh Hâlini Okuyan Temel Bir Duygu Analizi Motoru" /><published>2026-08-08T00:00:00+00:00</published><updated>2026-08-08T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/metinlerin-ruh-halini-okuyan-temel-bir-duygu-analizi-motoru</id><content type="html" xml:base="https://sonsuzus.github.io/posts/metinlerin-ruh-halini-okuyan-temel-bir-duygu-analizi-motoru/"><![CDATA[<p>Bir bilgisayarın “Bu uygulamaya bayıldım!” ile “Bir daha asla kullanmam!” arasındaki farkı anlayabilmesi kulağa sihir gibi gelebilir. Oysa temel seviyede bir duygu analizi motoru; metni temizleme, kelimeleri puanlama ve sonuçları birleştirme adımlarından oluşur. Bu projede makine öğrenmesine dalmadan, sözlük tabanlı ve açıklanabilir bir doğal dil işleme motoru geliştireceğiz.</p>

<p>``</p>

<h2 id="duygu-analizi-nedir">Duygu analizi nedir?</h2>

<p>Duygu analizi, bir metindeki öznel tutumu genellikle <strong>pozitif</strong>, <strong>negatif</strong> veya <strong>nötr</strong> olarak sınıflandırma işlemidir. Müşteri yorumları, sosyal medya gönderileri ve destek talepleri bu yöntemle otomatik olarak incelenebilir.</p>

<p>En basit yaklaşımda her duygu kelimesine sayısal bir değer veririz. Örneğin “harika” kelimesi $+2$, “iyi” kelimesi $+1$, “kötü” kelimesi $-1$ ve “berbat” kelimesi $-2$ puan alabilir. Metnin toplam skoru şöyle hesaplanır:</p>

\[S = \sum_{i=1}^{n} w_i\]

<p>Burada $w_i$, metindeki $i$. kelimenin duygu puanıdır. Sonuç $S&gt;0$ ise pozitif, $S&lt;0$ ise negatif, $S=0$ ise nötr kabul edilir.</p>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th>Avantajı</th>
      <th>Dezavantajı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Sözlük tabanlı</td>
      <td>Basit ve açıklanabilir</td>
      <td>Bağlamı sınırlı anlar</td>
    </tr>
    <tr>
      <td>Makine öğrenmesi</td>
      <td>Yeni örüntüleri öğrenebilir</td>
      <td>Etiketli veri gerektirir</td>
    </tr>
    <tr>
      <td>Derin öğrenme</td>
      <td>Karmaşık bağlamları yakalar</td>
      <td>Daha fazla veri ve kaynak ister</td>
    </tr>
  </tbody>
</table>

<h2 id="metni-işlemeye-hazırlamak">Metni işlemeye hazırlamak</h2>

<p>Kullanıcılar aynı düşünceyi farklı biçimlerde yazabilir: “HARİKA!”, “harika” ve “Harika…” bilgisayar için başlangıçta farklı dizelerdir. Bu nedenle metni küçük harfe çevirmeli, noktalama işaretlerini temizlemeli ve kelimelere ayırmalıyız. Bu işleme <strong>normalizasyon</strong> denir.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">re</span>

<span class="k">def</span> <span class="nf">metni_hazirla</span><span class="p">(</span><span class="n">metin</span><span class="p">):</span>
    <span class="n">metin</span> <span class="o">=</span> <span class="n">metin</span><span class="p">.</span><span class="nf">lower</span><span class="p">()</span>
    <span class="n">metin</span> <span class="o">=</span> <span class="n">re</span><span class="p">.</span><span class="nf">sub</span><span class="p">(</span><span class="sa">r</span><span class="sh">'</span><span class="s">[^a-zçğıöşü\s]</span><span class="sh">'</span><span class="p">,</span> <span class="sh">''</span><span class="p">,</span> <span class="n">metin</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">metin</span><span class="p">.</span><span class="nf">split</span><span class="p">()</span>
</code></pre></div></div>

<p>Bu fonksiyon, gereksiz karakterleri kaldırarak karşılaştırılabilir bir kelime listesi üretir. Gerçek projelerde kök bulma ve yazım düzeltme de eklenebilir.</p>

<h2 id="duygu-motorunu-oluşturmak">Duygu motorunu oluşturmak</h2>

<p>Şimdi küçük bir sözlük tanımlayıp kelimelerin puanlarını toplayabiliriz. Ayrıca “değil” gibi olumsuzluk ifadeleri kendisinden sonraki kelimenin anlamını tersine çevirebilir. Örneğin “iyi değil” ifadesini doğrudan pozitif saymak büyük bir hata olur.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">duygu_sozlugu</span> <span class="o">=</span> <span class="p">{</span>
    <span class="sh">'</span><span class="s">harika</span><span class="sh">'</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span>
    <span class="sh">'</span><span class="s">mükemmel</span><span class="sh">'</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span>
    <span class="sh">'</span><span class="s">iyi</span><span class="sh">'</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span>
    <span class="sh">'</span><span class="s">sevdim</span><span class="sh">'</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span>
    <span class="sh">'</span><span class="s">kötü</span><span class="sh">'</span><span class="p">:</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span>
    <span class="sh">'</span><span class="s">berbat</span><span class="sh">'</span><span class="p">:</span> <span class="o">-</span><span class="mi">2</span><span class="p">,</span>
    <span class="sh">'</span><span class="s">nefret</span><span class="sh">'</span><span class="p">:</span> <span class="o">-</span><span class="mi">2</span>
<span class="p">}</span>

<span class="n">olumsuzluklar</span> <span class="o">=</span> <span class="p">{</span><span class="sh">'</span><span class="s">değil</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">yok</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">asla</span><span class="sh">'</span><span class="p">}</span>

<span class="k">def</span> <span class="nf">duygu_analizi</span><span class="p">(</span><span class="n">metin</span><span class="p">):</span>
    <span class="n">kelimeler</span> <span class="o">=</span> <span class="nf">metni_hazirla</span><span class="p">(</span><span class="n">metin</span><span class="p">)</span>
    <span class="n">skor</span> <span class="o">=</span> <span class="mi">0</span>
    <span class="n">ters_cevir</span> <span class="o">=</span> <span class="bp">False</span>

    <span class="k">for</span> <span class="n">kelime</span> <span class="ow">in</span> <span class="n">kelimeler</span><span class="p">:</span>
        <span class="k">if</span> <span class="n">kelime</span> <span class="ow">in</span> <span class="n">olumsuzluklar</span><span class="p">:</span>
            <span class="n">ters_cevir</span> <span class="o">=</span> <span class="bp">True</span>
            <span class="k">continue</span>

        <span class="n">puan</span> <span class="o">=</span> <span class="n">duygu_sozlugu</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="n">kelime</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">ters_cevir</span> <span class="ow">and</span> <span class="n">puan</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
            <span class="n">puan</span> <span class="o">*=</span> <span class="o">-</span><span class="mi">1</span>
            <span class="n">ters_cevir</span> <span class="o">=</span> <span class="bp">False</span>
        <span class="n">skor</span> <span class="o">+=</span> <span class="n">puan</span>

    <span class="k">if</span> <span class="n">skor</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
        <span class="k">return</span> <span class="sh">'</span><span class="s">pozitif</span><span class="sh">'</span><span class="p">,</span> <span class="n">skor</span>
    <span class="k">if</span> <span class="n">skor</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">:</span>
        <span class="k">return</span> <span class="sh">'</span><span class="s">negatif</span><span class="sh">'</span><span class="p">,</span> <span class="n">skor</span>
    <span class="k">return</span> <span class="sh">'</span><span class="s">nötr</span><span class="sh">'</span><span class="p">,</span> <span class="n">skor</span>
</code></pre></div></div>

<p>Fonksiyon bilinmeyen kelimelere sıfır puan verir. Olumsuzluk görülürse sıradaki duygu kelimesinin işareti değiştirilir. Böylece motor yalnızca kelime saymak yerine küçük de olsa bağlam takibi yapar.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nf">print</span><span class="p">(</span><span class="nf">duygu_analizi</span><span class="p">(</span><span class="sh">'</span><span class="s">Ürün harika, gerçekten sevdim!</span><span class="sh">'</span><span class="p">))</span>
<span class="c1"># ('pozitif', 3)
</span>
<span class="nf">print</span><span class="p">(</span><span class="nf">duygu_analizi</span><span class="p">(</span><span class="sh">'</span><span class="s">Hizmet iyi değil.</span><span class="sh">'</span><span class="p">))</span>
<span class="c1"># ('negatif', -1)
</span></code></pre></div></div>

<h2 id="başarıyı-nasıl-ölçeriz">Başarıyı nasıl ölçeriz?</h2>

<p>Motoru değerlendirmek için önceden etiketlenmiş test cümleleri hazırlanabilir. Doğruluk oranı şu formülle bulunur:</p>

\[Doğruluk = \frac{Doğru\ Tahmin}{Toplam\ Tahmin}\]

<p>Ancak alaycılık, deyimler ve alan bağımlı kelimeler sistemi şaşırtabilir. “Telefon ateş ediyor” olumlu bir övgüyken gerçek bir yangın metninde olumsuzdur. Motoru geliştirmek için sözlüğe ağırlık artırıcı “çok”, “aşırı” gibi ifadeler eklenebilir; emojiler puanlanabilir ve sonuçlar bir veri kümesiyle test edilebilir. Böylece küçük sözlük, zamanla daha becerikli bir dijital duygu dedektifine dönüşür.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Proje" /><category term="doğal dil işleme" /><category term="duygu analizi" /><category term="Python" /><summary type="html"><![CDATA[Bir bilgisayarın “Bu uygulamaya bayıldım!” ile “Bir daha asla kullanmam!” arasındaki farkı anlayabilmesi kulağa sihir gibi gelebilir. Oysa temel seviyede bir duygu analizi motoru; metni temizleme, kelimeleri puanlama ve sonuçları birleştirme adımlarından oluşur. Bu projede makine öğrenmesine dalmadan, sözlük tabanlı ve açıklanabilir bir doğal dil işleme motoru geliştireceğiz.]]></summary></entry></feed>