import torch
import torch.nn as nn
import numpy as np
from torch.utils.data import DataLoader, TensorDataset, random_split
class LinearRegressor(nn.Module):
def __init__(self, batch_size=1, n_epochs=10, learning_rate=0.01):
super().__init__()
self.n_epochs = n_epochs
self.learning_rate = learning_rate
self.batch_size = batch_size
def forward(self, x):
return self.linear(x)
def fit(self, features_train, labels_train):
n_features = features_train.shape[1]
self.linear = nn.Linear(n_features, 1)
features_train_tensor = torch.from_numpy(features_train).type(torch.float32)
labels_train_tensor = torch.unsqueeze(torch.from_numpy(labels_train.to_numpy()).type(torch.float32), 1)
features_train = TensorDataset(features_train_tensor, labels_train_tensor)
train_loader = DataLoader(features_train, self.batch_size, shuffle=True)
loss_fn = torch.nn.MSELoss()
optimizer = torch.optim.SGD(self.parameters(), self.learning_rate)
for epoch in range(self.n_epochs):
for batch in train_loader:
inputs, labels = batch
optimizer.zero_grad()
outputs = self(inputs)
loss = loss_fn(outputs, labels)
loss.backward()
optimizer.step()
def predict(self, features_test):
features_test_tensor = torch.from_numpy(features_test).type(torch.float32)
features_test = TensorDataset(features_test_tensor)
test_loader = iter(DataLoader(features_test, batch_size=len(features_test)))
with torch.no_grad():
data = test_loader.next()
inputs = data[0]
outputs = self(inputs)
predictions = outputs.data.numpy().flatten()
return predictions
class LinearBinaryClassifier(nn.Module):
def __init__(self, batch_size=1, n_epochs=10, learning_rate=0.01):
super().__init__()
self.n_epochs = n_epochs
self.learning_rate = learning_rate
self.batch_size = batch_size
def forward(self, x):
x = self.linear(x)
out = nn.Sigmoid()(x)
return out
def fit(self, features_train, labels_train):
n_features = features_train.shape[1]
self.linear = nn.Linear(n_features, 1)
features_train_tensor = torch.from_numpy(features_train).type(torch.float32)
labels_train_tensor = torch.unsqueeze(torch.from_numpy(labels_train.to_numpy()).type(torch.float32), 1)
features_train = TensorDataset(features_train_tensor, labels_train_tensor)
train_loader = DataLoader(features_train, self.batch_size, shuffle=True)
loss_fn = nn.BCELoss()
optimizer = torch.optim.SGD(self.parameters(), self.learning_rate)
for epoch in range(self.n_epochs):
for batch in train_loader:
inputs, labels = batch
optimizer.zero_grad()
outputs = self(inputs)
loss = loss_fn(outputs, labels)
loss.backward()
optimizer.step()
def predict_proba(self, features_test):
features_test_tensor = torch.from_numpy(features_test).type(torch.float32)
features_test = TensorDataset(features_test_tensor)
test_loader = iter(DataLoader(features_test, batch_size=len(features_test)))
with torch.no_grad():
data = test_loader.next()
inputs = data[0]
outputs = self(inputs)
predictions = outputs.data.numpy().flatten()
return predictions
class LinearMulticlassClassifier(nn.Module):
def __init__(self, batch_size=1, n_epochs=10, learning_rate=0.01, n_classes=3):
super().__init__()
self.n_epochs = n_epochs
self.learning_rate = learning_rate
self.batch_size = batch_size
self.n_classes = n_classes
def forward(self, x):
x = self.linear(x)
out = nn.Softmax(dim=1)(x)
return out
def fit(self, features_train, labels_train):
n_features = features_train.shape[1]
self.linear = nn.Linear(n_features, self.n_classes)
features_train_tensor = torch.from_numpy(features_train).type(torch.float32)
labels_train_tensor = torch.from_numpy(labels_train.to_numpy()).type(torch.int64)
features_train = TensorDataset(features_train_tensor, labels_train_tensor)
train_loader = DataLoader(features_train, self.batch_size, shuffle=True)
loss_fn = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(self.parameters(), self.learning_rate)
for epoch in range(self.n_epochs):
for batch in train_loader:
inputs, labels = batch
optimizer.zero_grad()
outputs = self(inputs)
loss = loss_fn(outputs, labels)
loss.backward()
optimizer.step()
def predict(self, features_test):
features_test_tensor = torch.from_numpy(features_test).type(torch.float32)
features_test = TensorDataset(features_test_tensor)
test_loader = iter(DataLoader(features_test, batch_size=len(features_test)))
with torch.no_grad():
data = test_loader.next()
inputs = data[0]
outputs = self(inputs)
_, predictions = torch.max(outputs.data, 1)
return predictions