PyTorch Chapter 2.1 Linear Regression

Berkant Tugberk Demirtaş
6 min readJan 9, 2024

--

Daha önceki yazı serilerimizde tensorler konusuna giriş yapıp temel konularla ilgili alıştırmalar yapmıştık. Bugün, öğrendiğimiz bilgileri linear regression modeli kurarak pekiştiriyor olacağız. İlk modelimizi kurmak için heyecanlı mısınız? Haydi linear regression teriminin tanımıyla başlayalım.

Linear Regression

https://web.stanford.edu/class/stats202/notes/Linear-regression/Simple-linear-regression.html

Elimizde linear ilişki olan bir data olduğunu varsayalım. Bu data üzerine olabilecek en iyi line’ı fit edebilirsek, kolaylıkla tahminleme yapabiliriz. Diyelim ki internette ev fiyatlarının olduğu bir veriseti bulduk. Bu veriseti ev fiyatları ile beraber oda sayılarını da içeriyor olsun. Verilere hızlıca göz attığımızda oda sayısı arttıkça fiyatların da arttığını görüyoruz. Burada linear bir ilişki tahmini çıkarıp , linear bir model oluşturup fiyat tahmini yapabiliriz.

Lise veya üniversitede gördüğümüz matematik bilgilerimizi tazelemek istersek, bir line oluşturmak için gereken formül aşağıdaki gibidir;

Bu formül, yapay zeka literatüründe farklı harflerle de karşımıza çıkabilir. Özellikle y = Wx + b şeklinde, w’nin weight’i temsil ettiği, b’nin de bias terimini temsil ettiğini şu an bilmemiz yeterlidir. Formülümüzü ev fiyatlarına uygulayacak olursak, ev fiyatları (y), oda sayısı(x) cinsinden ifade edilir. W ise ağırlık olarak değerlendirilerek, oda sayısına bir kat sayı olarak yazılır. b ise bias olarak denkleme eklenir ve ev fiyatını bu değişkenler üzerinden bulmaya çalışırız. Elimizdeki senaryoda tek bir feature yani tek bir özelliğimiz olduğu için (oda sayısı) elimizde tek bir x değişkeni var. Bu feature’lar arttıkça formüle yeni X’ler ve weight’ler de eklenmiş olacaktır. Konuyu pekiştirdiysek , yapay olarak bir line oluşturup modelimizi kurmaya başlayalım.

Linear Yapay Veri Oluşturma

Bir önceki başlıktaki formülümüzden faydalanarak verimizi oluşturabiliriz.

weight = 0.7
bias = 0.3

# Create

start = 0
end = 1
step = 0.02

X = torch.arange(start, end, step).unsqueeze(dim=1)
y = weight * X + bias

Daha önceki yazılarımızda istediğimiz bir tensorü nasıl oluşturacağımızı öğrenmiştik. Linear Regression başlığında ise oluşturacağımız modelin formülüne kısaca değindik. Yukarıdaki kod parçacığında bu bilgileri birleştirerek ufak bir veri seti oluşturduk. X değişkeni feature’ları, y değişkeni ise target’ları yani tahmin etmemiz gereken değerleri gösteriyor. Oluşturacağımız model weight ve bias değerlerini o kadar iyi öğrenmeli ki bunları kullanarak y değerlerini tahmin edebilsin. Şimdi verimize bir göz atalım.

print(X[:10], y[:10])
print(f"X verisinin shape'i : {X.shape}, y targetinin shape'i {y.shape}")

Kendi oluşturduğumuz X değerlerine ve bu değerlere karşılık Y değerlerine göz atıp oluşturduğumuz verisetinin shape’ini inceledik.

Train/Test Splitting

https://builtin.com/data-science/train-test-split

Yapay zeka problemleri ile uğraşırken elimizdeki verisetini test/train(eğitim) veriseti diye ayırıyor olmak bize önemli bir avantaj sağlar. Oluşturacağımız yapay zeka modelini, train veri seti üzerinde eğitip öğrenmesini sağlar; daha sonra ise test veri seti üzerinde öğrendiği modeli uygulamasını isteriz. Eğer eğitimde bütün veri setini kullanıyor olsaydık modelimiz bütün veriyi göreceği için, daha önce görmediği yeni bir veri geldiğinde nasıl bir performans sergileyeceğini tam olarak ölçemiyor olurduk. Dolayısıyla preprocessing aşamalarından biri olan train/test ayrımını da bu aşamada gerçekleştirmek gerekir.

Peki ama hangi oranda ayırmalıyız? Şimdilik bu problem üzerinde uzunca tartışmadan %80 train, %20 test veri seti olarak ayırmak üzerine adımımızı ilerleteceğiz.


train_split = int(0.8*len(X))
X_train, y_train = X[:train_split], y[:train_split]
X_test, y_test = X[train_split:], y[train_split:]

Yukarıdaki kod içerisinde, verimizin ilk %80'lik kısmını train olarak ayırıp kalan %20'lik kısmını ise test olarak ayırdığımızı görebilirsiniz. Verilerin shape’ine bakarak doğru ayrılıp ayrılmadığını test edebiliriz.

print(f"X veri boyutu: {X.shape}, y veri boyutu: {y.shape}, ")
print(f"Train X veri boyutu: {X_train.shape}, train y veri boyutu: {y_train.shape}, ")
print(f"Test X veri boyutu: {X_test.shape}, test y veri boyutu: {y_test.shape}, ")

Daha önce yapay olarak 50 adet feature ve target verisi oluşturmuştuk. %80/%20 bölümü yaptığımızda ise, train boyutlarımızın 40, test boyutlarımızın 10 olduğunu bu şekilde de doğrulamış olduk. Şimdi modelimize train datalarımızı öğretip, test datalarımızdan sorular sorabiliriz. Fakat bu aşamadan önce verilerimizi görselleştirerek dağılımına bakarak biraz daha bilgi almak isteyebiliriz.

Görselleştirme

import matplotlib.pyplot as plt

def plot_predictions(train_data = X_train,
train_labels = y_train,
test_data = X_test,
test_labels = y_test,
predictions=None):

plt.figure(figsize=(10,7))

# Plot training data in blue

plt.scatter(train_data, train_labels, c="b", s=4, label = "Training data")

# Plot training data in green

plt.scatter(test_data, test_labels, c="g", s=4, label = "Testing data")

if predictions is not None:
# Plot the predictions
plt.scatter(test_data, predictions, c="r", s=4, label= "Predictions")

plt.legend(prop={"size":14})

Matplotlib kütüphanesini kullanarak oluşturduğumuz noktaları plt.scatter() methodu ile çizdiriyoruz. Daha sonra bu fonksiyonu çağırarak, görselimize ulaşabiliriz.

plot_predictions()

Wow! Gerçekten de formülüze ettiğimiz linear ilişkili datamızı başarıyla oluşturmuşuz. Görüldüğü gibi yeşil kısımlar test datamız. Bu demek oluyor ki modelimiz mavi noktaları inceleyerek yeşil noktaları tahmin etmeye çalışacak. Ne kadar doğru tahmin ettiği ise bu modelimizin başarısını belirleyecek.

Modelleme

Linear regression modelini kurabilmek için PyTorch’un kullanımımıza sunduğu methodlara göz atabiliriz. Biz “torch.nn” kütüphanesi kullanarak bloklar halinde modelimizi inşaa edeceğiz. Burada object orinted Python kullanacağımızın bilgisini şimdiden vermek gerekebilir. Okumaya devam etmeden önce bu konuda bilginizin olması gerektiğini söylemek gerekir. Bu kütüphane hakkında daha fazla bilgi almak için resmi PyTorch kaynağına göz atabilirsiniz -> https://pytorch.org/docs/stable/nn.html

from torch import nn

# Create a Linear Regression model class
class LinearRegressionModel(nn.Module): # <- almost everything in PyTorch is a nn.Module (think of this as neural network lego blocks)
def __init__(self):
super().__init__()
self.weights = nn.Parameter(torch.randn(1, # <- start with random weights (this will get adjusted as the model learns)
dtype=torch.float), # <- PyTorch loves float32 by default
requires_grad=True) # <- can we update this value with gradient descent?)

self.bias = nn.Parameter(torch.randn(1, # <- start with random bias (this will get adjusted as the model learns)
dtype=torch.float), # <- PyTorch loves float32 by default
requires_grad=True) # <- can we update this value with gradient descent?))

# Forward defines the computation in the model
def forward(self, x: torch.Tensor) -> torch.Tensor: # <- "x" is the input data (e.g. training/testing features)
return self.weights * x + self.bias # <- this is the linear regression formula (y = m*x + b)

Öncelikle class’ımızı nn.Module’den miras alacak şekilde oluşturuyoruz. Oluşturacağımız bütün PyTorch modellerini bu modül’den miras alarak oluşturuyor olacağız. Daha önce konuştuğumuz üzere modelimiz weight ve bias değerlerini tahminleyerek target değişkenimizi bulmaya çalışacak. Bu değerleri bulmak için farklı yollar kullanılabilir. Öncelikle bu değerleri 0 olarak atayabilir ve sonrasında update edebiliriz, veya random bir noktadan başlayıp update ederek optimum değerlere ulaşmaya çalışabiliriz. Biz, bu başlık altında random bir değerler oluşturarak başlayacağız. Weight ve bias için , daha önceki başlıklarda değindiğimiz torch.randn() methodunu kullanarak 1 elemanlı random bir değer oluşturuyoruz. Daha sonra oluşturduğumuz değerleri nn.Parameter() methoduna veriyoruz. Daha sonra bu methodları açıklıyor olacağız.

Random değerler oluştururken requires_grad diye bir değişkene True değer verdiğimizi görebilirsiniz. requires_grad değişkeni, PyTorch kütüphanesinde kullanılan bir özelliktir ve bir tensorün takip ettiği gradyan bilgilerini kontrol etmeye yarar. Gradyanlar, tensor üzerindeki değerlerin bir fonksiyonunun türevi veya eğimi olarak düşünülebilir. Bu değerleri daha sonra modeli optimize ederken kullanacağımız için takibini tutmamız gerekmektedir.

Son olarak ise bir forward methodu oluşturuyoruz. Bu method oluşturulan weight ve bias değerlerini kullanarak tahminleme yapmaktan sorumludur. Yani sonuçlarımızı bu method üzerinden alıyor olacağız. Her şey yeterince açık mı? Son olarak PyTorch modüllerine biraz daha ayrıntılı göz atalım.

“torch.nn” PyTorch kütüphanesinde bulunan bir alt modüldür ve derin öğrenme (deep learning) için çeşitli araçları, modelleri ve fonksiyonları içerir. Bu modül, sinir ağları (neural networks) oluşturmak, eğitmek ve değerlendirmek için kullanılan temel yapı taşlarını içerir. “torch.nn” modülü, aynı zamanda geniş bir model arşivini de içerir.

“torch.nn.Parameter”, PyTorch kütüphanesindeki bir sınıftır. Ancak, “Parameter” sınıfı, bir modelin öğrenilebilir parametrelerini temsil etmek için özel olarak tasarlanmıştır. Modelin eğitimi sırasında güncellenen ve öğrenilen ağırlıklar, biaslar gibi parametreler “Parameter” sınıfı altında tanımlanır.

Bir tensorü “Parameter”'e dönüştürmek, bu tensorün bir modelin öğrenilebilir parametresi olarak kullanılmasını sağlar. “Parameter” sınıfı, gradient hesaplamaları ve optimizasyon algoritmaları tarafından otomatik olarak takip edilen bir gradyan özelliğine (grad) sahiptir.

Bu konularla beraber daha fazla ileri gitmeden yazıyı burada bitirmek uygun duruyor. Yukarıdaki modüller ile ilgili yazdığım bilgiler Chat-GPT tarafından verilmiştir. Daha fazla bilgi almak için resmi PyTorch sitesine göz atabilirsiniz. Ayrıca bu yazıyı oluştururken ilham aldığım ve kodlarının bir kısmını kullandığım https://www.learnpytorch.io/01_pytorch_workflow/ linkinden daha fazla bilgiye ulaşabilirsiniz.

Bir sonraki yazıda görüşmek üzere!

--

--

No responses yet