Sıradaki

Döngüyü vektörleştir

Zorluk: Kolay

numpy

Bir dizideki (array) sayıların karelerini toplayan sum_of_squares(x) fonksiyonunu, döngü kullanmadan yaz. Bu hesabı bir for döngüsüyle kolayca yazabilirsin.

Bu problemde vektörleştirmeyi (vectorization) kullanırsın: hesabı array’e bir seferde uygulanan NumPy işlemleriyle yazarsın.

x, şekli (shape) (n,) olan bir array’dir. Hesap iki adımdır:

  1. Her elemanın karesini al.
  2. Kareleri topla.

Formülü şudur:

S=∑i=1nxi2S = \sum_{i=1}^{n} x_i^2

Örneğin x=(3,−4)\mathbf{x} = (3, -4) için S=32+(−4)2=9+16=25S = 3^2 + (-4)^2 = 9 + 16 = 25 olur. Eksi işaret karede kaybolur. Tek bir Python float döndür.

Örnekler

Girdi: x = [1.0, 2.0, 3.0, 4.0]
Çıktı: 30.0

Girdi: x = []
Çıktı: 0.0

Girdi: x = [-3.0, 0.5, -1.5, 2.0, -0.25]
Çıktı: 15.5625

İpucu 1

x ** 2, her elemanın karesini içeren yeni bir array verir. NumPy array’lerinde ** gibi işlemler eleman bazında (element-wise) çalışır. Elemanlar üzerinde dolaşmana gerek yok.

İpucu 2

np.sum, karelerin array’ini tek bir sayıya indirir. Sırayı karıştırma: önce kareler, sonra toplam.

İpucu 3

Döndürmeden önce sonucu float(...) ile sade bir Python float’una çevirebilirsin. Kareleri np.sum ile topla ve sonucu çevir.

Gereksinimler

  • x, (n,) shape’inde, float’lardan oluşan bir array’dir. Boş olabilir (n = 0); boş array’de sonuç 0.0’dır.
  • Dönüş değeri tek bir float: array ya da liste değil. np.sum’ın verdiği np.float64 de kabul edilir. float(...) ile çevirmek zorunda değilsin.
  • Önce kareyi al, sonra topla. Toplamın karesi farklı bir sayıdır: (∑ixi)2\left(\sum_i x_i\right)^2
  • Elemanlar üzerinde döngü (for, while) ya da liste üreteci (list comprehension) kullanma: tek bir NumPy ifadesi yeter.
  • x’i değiştirme. Fonksiyon bittiğinde çağıran kodun array’i aynı kalır.

Karelerin toplamı makine öğrenmesinde sürekli karşına çıkar. Ortalama kare hatada (mean squared error, MSE) her hatanın karesi alınıp toplanır. Bir vektörün uzunluğunun karesi de şu toplamdır:

∑ixi2\sum_i x_i^2

Hesabın kendisi basit. Bu problemin asıl konusu, hesabı nasıl yazdığındır.

Python döngüsü ile NumPy aynı hesabı farklı yapar:

Python döngüsüNumPy
ÇalışmaHer eleman yorumlayıcıdan geçer.Tek çağrı bütün array’i derlenmiş koda verir.
Eleman başına işÇokÇok daha az

Bir milyon elemanlı bir array’de fark genellikle onlarca kat olur. Hesabı elemanlar üzerinde bir döngü olarak değil, bütün array’e uygulanan işlemler olarak yazmaya vectorization denir.

Döngüyle yazılmış bir çözüm de aynı sayıyı verir. Döngünün istenmemesinin nedeni sonuç değil, alışkanlıktır.

Sonraki derslerde kayıp (loss) değerini, tahminleri ve gradyanları binlerce örnek için tek seferde hesaplayacaksın. Hepsi bu biçimde yazılır. Bir hesabı “elemanlar üzerinde dolaş” yerine “tüm array’e şu işlemi uygula” diye düşünebilmek, NumPy ile çalışmanın temelidir.

Daha fazlası için NumPy hızlı başlangıç dersine bak.

Önce kareleri al, sonra topla ve sonucu bir Python float’una çevir:

import numpy as npdef sum_of_squares(x: np.ndarray) -> float:    return float(np.sum(x ** 2))

Sık yapılan hata, karelerin toplamı yerine toplamın karesini almaktır (np.sum(x) ** 2). x=(1,−1)\mathbf{x} = (1, -1) için elemanlar birbirini götürür ve sonuç 00 çıkar. Doğru cevap 1+1=21 + 1 = 2‘dir.

Kare, toplamadan önce her elemana ayrı ayrı uygulanmalıdır.

x @ x de aynı sonucu tek işlemle verir. Bir vektörün kendisiyle iç çarpımı (dot product), karelerin toplamıdır.

Bu problemde bir sorun mu var?

solution.py
import numpy as npdef sum_of_squares(x: np.ndarray) -> float:    """Dizideki elemanların karelerinin toplamını döndürür."""    # Kodunu buraya yaz.    return 0.0

İçindekiler

Geri bildirim

Tür