Commit b5f1378c authored by Alison Carrera's avatar Alison Carrera
Browse files

Fixed algorithm for imbalanced dataset.

parent bf7f95bb
...@@ -6,10 +6,16 @@ ...@@ -6,10 +6,16 @@
``` ```
!pip install --upgrade onn !pip install --upgrade onn
``` ```
%% Cell type:code id: tags:
```
!pip install -U imbalanced-learn
```
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
##Importing Dependencies ##Importing Dependencies
%% Cell type:code id: tags: %% Cell type:code id: tags:
...@@ -18,11 +24,12 @@ ...@@ -18,11 +24,12 @@
from onn.OnlineNeuralNetwork import ONN from onn.OnlineNeuralNetwork import ONN
from onn.OnlineNeuralNetwork import ONN_THS from onn.OnlineNeuralNetwork import ONN_THS
from sklearn.datasets import make_classification, make_circles from sklearn.datasets import make_classification, make_circles
from sklearn.model_selection import train_test_split from sklearn.model_selection import train_test_split
import torch import torch
from sklearn.metrics import accuracy_score from sklearn.metrics import accuracy_score, balanced_accuracy_score
from imblearn.datasets import make_imbalance
import numpy as np import numpy as np
``` ```
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
...@@ -56,11 +63,11 @@ ...@@ -56,11 +63,11 @@
for i in range(len(X_train)): for i in range(len(X_train)):
onn_network.partial_fit(np.asarray([X_train[i, :]]), np.asarray([y_train[i]])) onn_network.partial_fit(np.asarray([X_train[i, :]]), np.asarray([y_train[i]]))
if i % 1000 == 0: if i % 1000 == 0:
predictions = onn_network.predict(X_test) predictions = onn_network.predict(X_test)
print("Online Accuracy: {}".format(accuracy_score(y_test, predictions))) print("Online Accuracy: {}".format(balanced_accuracy_score(y_test, predictions)))
``` ```
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
# Learning in batch with CUDA # Learning in batch with CUDA
...@@ -103,11 +110,11 @@ ...@@ -103,11 +110,11 @@
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` ```
predictions = onn_network.predict(X_test) predictions = onn_network.predict(X_test)
print("Accuracy: {}".format(accuracy_score(y_test, predictions))) print("Accuracy: {}".format(balanced_accuracy_score(y_test, predictions)))
``` ```
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
#Using contextual bandit - ONN_THS #Using contextual bandit - ONN_THS
...@@ -165,11 +172,11 @@ ...@@ -165,11 +172,11 @@
if i % 2000 == 1999: if i % 2000 == 1999:
pred = [] pred = []
print("======================================================") print("======================================================")
for i in range(len(X_linear_test)): for i in range(len(X_linear_test)):
pred.append(gp.predict(np.asarray([X_linear_test[i, :]]))[0]) pred.append(gp.predict(np.asarray([X_linear_test[i, :]]))[0])
print("Accuracy: " + str(accuracy_score(Y_linear_test, pred))) print("Accuracy: " + str(balanced_accuracy_score(Y_linear_test, pred)))
print("======================================================") print("======================================================")
print('Finished Training') print('Finished Training')
``` ```
...@@ -190,16 +197,98 @@ ...@@ -190,16 +197,98 @@
if i % 2000 == 1999: if i % 2000 == 1999:
pred = [] pred = []
print("======================================================") print("======================================================")
for i in range(len(X_linear_test)): for i in range(len(X_linear_test)):
pred.append(gp.predict(np.asarray([X_non_linear_test[i, :]]))[0]) pred.append(gp.predict(np.asarray([X_non_linear_test[i, :]]))[0])
print("Accuracy: " + str(accuracy_score(Y_non_linear_test, pred))) print("Accuracy: " + str(balanced_accuracy_score(Y_non_linear_test, pred)))
print("======================================================") print("======================================================")
print('Finished Training') print('Finished Training')
``` ```
%% Cell type:markdown id: tags:
# Imbalanced Dataset
%% Cell type:code id: tags:
```
X, Y = make_classification(n_samples=110000, n_features=20, n_classes=10, n_informative=8, n_redundant=0, n_clusters_per_class=1, class_sep=900)
```
%% Cell type:code id: tags:
```
X_t, Y_t = make_imbalance(X, Y, sampling_strategy={0: 800, 1: 5000, 2: 10000, 3: 10000, 4: 1000, 5: 1000, 6: 500, 7: 10000, 8: 5000, 9:5000})
```
%% Cell type:code id: tags:
```
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.2)
X_train_t, X_test_t, y_train_t, y_test_t = train_test_split(X_t, Y_t, test_size=0.2)
```
%% Cell type:code id: tags:
```
gp = ONN_THS(20, 5, 100, 10)
```
%% Cell type:code id: tags:
```
for i in range(len(X_train)):
x = np.asarray([X_train[i, :]])
y = np.asarray([y_train[i]])
arm, exp = gp.predict(x)
if arm == y[0]:
gp.partial_fit(x, y, exp)
if i % 2000 == 1999:
pred = []
print("======================================================")
for i in range(len(X_test)):
pred.append(gp.predict(np.asarray([X_test[i, :]]))[0])
print("Accuracy: " + str(balanced_accuracy_score(y_test, pred)))
print("======================================================")
print('Finished Training')
```
%% Cell type:code id: tags:
```
gp = ONN_THS(20, 5, 100, 10)
```
%% Cell type:code id: tags:
```
for i in range(len(X_train_t)):
x = np.asarray([X_train_t[i, :]])
y = np.asarray([y_train_t[i]])
arm, exp = gp.predict(x)
if arm == y[0]:
gp.partial_fit(x, y, exp)
if i % 2000 == 1999:
pred = []
print("======================================================")
for i in range(len(X_test_t)):
pred.append(gp.predict(np.asarray([X_test_t[i, :]]))[0])
print("Accuracy: " + str(balanced_accuracy_score(y_test_t, pred)))
print("======================================================")
print('Finished Training')
```
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` ```
``` ```
......
...@@ -7,6 +7,7 @@ import torch ...@@ -7,6 +7,7 @@ import torch
import torch.nn as nn import torch.nn as nn
import torch.nn.functional as F import torch.nn.functional as F
from torch.nn.parameter import Parameter from torch.nn.parameter import Parameter
from mab import algs
class ONN(nn.Module): class ONN(nn.Module):
...@@ -17,27 +18,34 @@ class ONN(nn.Module): ...@@ -17,27 +18,34 @@ class ONN(nn.Module):
if torch.cuda.is_available() and use_cuda: if torch.cuda.is_available() and use_cuda:
print("Using CUDA :]") print("Using CUDA :]")
self.device = torch.device("cuda:0" if torch.cuda.is_available() and use_cuda else "cpu") self.device = torch.device(
"cuda:0" if torch.cuda.is_available() and use_cuda else "cpu")
self.features_size = features_size self.features_size = features_size
self.max_num_hidden_layers = max_num_hidden_layers self.max_num_hidden_layers = max_num_hidden_layers
self.qtd_neuron_per_hidden_layer = qtd_neuron_per_hidden_layer self.qtd_neuron_per_hidden_layer = qtd_neuron_per_hidden_layer
self.n_classes = n_classes self.n_classes = n_classes
self.batch_size = batch_size self.batch_size = batch_size
self.b = Parameter(torch.tensor(b), requires_grad=False).to(self.device) self.b = Parameter(torch.tensor(
self.n = Parameter(torch.tensor(n), requires_grad=False).to(self.device) b), requires_grad=False).to(self.device)
self.s = Parameter(torch.tensor(s), requires_grad=False).to(self.device) self.n = Parameter(torch.tensor(
n), requires_grad=False).to(self.device)
self.s = Parameter(torch.tensor(
s), requires_grad=False).to(self.device)
self.hidden_layers = [] self.hidden_layers = []
self.output_layers = [] self.output_layers = []
self.hidden_layers.append(nn.Linear(features_size, qtd_neuron_per_hidden_layer)) self.hidden_layers.append(
nn.Linear(features_size, qtd_neuron_per_hidden_layer))
for i in range(max_num_hidden_layers - 1): for i in range(max_num_hidden_layers - 1):
self.hidden_layers.append(nn.Linear(qtd_neuron_per_hidden_layer, qtd_neuron_per_hidden_layer)) self.hidden_layers.append(
nn.Linear(qtd_neuron_per_hidden_layer, qtd_neuron_per_hidden_layer))
for i in range(max_num_hidden_layers): for i in range(max_num_hidden_layers):
self.output_layers.append(nn.Linear(qtd_neuron_per_hidden_layer, n_classes)) self.output_layers.append(
nn.Linear(qtd_neuron_per_hidden_layer, n_classes))
self.hidden_layers = nn.ModuleList(self.hidden_layers).to(self.device) self.hidden_layers = nn.ModuleList(self.hidden_layers).to(self.device)
self.output_layers = nn.ModuleList(self.output_layers).to(self.device) self.output_layers = nn.ModuleList(self.output_layers).to(self.device)
...@@ -65,7 +73,8 @@ class ONN(nn.Module): ...@@ -65,7 +73,8 @@ class ONN(nn.Module):
for out in predictions_per_layer: for out in predictions_per_layer:
criterion = nn.CrossEntropyLoss().to(self.device) criterion = nn.CrossEntropyLoss().to(self.device)
loss = criterion(out.view(self.batch_size, self.n_classes), Y.view(self.batch_size).long()) loss = criterion(out.view(self.batch_size, self.n_classes), Y.view(
self.batch_size).long())
losses_per_layer.append(loss) losses_per_layer.append(loss)
w = [] w = []
...@@ -73,23 +82,29 @@ class ONN(nn.Module): ...@@ -73,23 +82,29 @@ class ONN(nn.Module):
for i in range(len(losses_per_layer)): for i in range(len(losses_per_layer)):
losses_per_layer[i].backward(retain_graph=True) losses_per_layer[i].backward(retain_graph=True)
self.output_layers[i].weight.data -= self.n * self.alpha[i] * self.output_layers[i].weight.grad.data self.output_layers[i].weight.data -= self.n * \
self.output_layers[i].bias.data -= self.n * self.alpha[i] * self.output_layers[i].bias.grad.data self.alpha[i] * self.output_layers[i].weight.grad.data
self.output_layers[i].bias.data -= self.n * \
self.alpha[i] * self.output_layers[i].bias.grad.data
w.append(self.alpha[i] * self.hidden_layers[i].weight.grad.data) w.append(self.alpha[i] * self.hidden_layers[i].weight.grad.data)
b.append(self.alpha[i] * self.hidden_layers[i].bias.grad.data) b.append(self.alpha[i] * self.hidden_layers[i].bias.grad.data)
self.zero_grad() self.zero_grad()
for i in range(1, len(losses_per_layer)): for i in range(1, len(losses_per_layer)):
self.hidden_layers[i].weight.data -= self.n * torch.sum(torch.cat(w[i:])) self.hidden_layers[i].weight.data -= self.n * \
self.hidden_layers[i].bias.data -= self.n * torch.sum(torch.cat(b[i:])) torch.sum(torch.cat(w[i:]))
self.hidden_layers[i].bias.data -= self.n * \
torch.sum(torch.cat(b[i:]))
for i in range(len(losses_per_layer)): for i in range(len(losses_per_layer)):
self.alpha[i] *= torch.pow(self.b, losses_per_layer[i]) self.alpha[i] *= torch.pow(self.b, losses_per_layer[i])
self.alpha[i] = torch.max(self.alpha[i], self.s / self.max_num_hidden_layers) self.alpha[i] = torch.max(
self.alpha[i], self.s / self.max_num_hidden_layers)
z_t = torch.sum(self.alpha) z_t = torch.sum(self.alpha)
self.alpha = Parameter(self.alpha / z_t, requires_grad=False).to(self.device) self.alpha = Parameter(
self.alpha / z_t, requires_grad=False).to(self.device)
if show_loss: if show_loss:
real_output = torch.sum(torch.mul( real_output = torch.sum(torch.mul(
...@@ -115,7 +130,8 @@ class ONN(nn.Module): ...@@ -115,7 +130,8 @@ class ONN(nn.Module):
hidden_connections.append(x) hidden_connections.append(x)
for i in range(1, self.max_num_hidden_layers): for i in range(1, self.max_num_hidden_layers):
hidden_connections.append(F.relu(self.hidden_layers[i](hidden_connections[i - 1]))) hidden_connections.append(
F.relu(self.hidden_layers[i](hidden_connections[i - 1])))
output_class = [] output_class = []
...@@ -128,11 +144,13 @@ class ONN(nn.Module): ...@@ -128,11 +144,13 @@ class ONN(nn.Module):
def validate_input_X(self, data): def validate_input_X(self, data):
if len(data.shape) != 2: if len(data.shape) != 2:
raise Exception("Wrong dimension for this X data. It should have only two dimensions.") raise Exception(
"Wrong dimension for this X data. It should have only two dimensions.")
def validate_input_Y(self, data): def validate_input_Y(self, data):
if len(data.shape) != 1: if len(data.shape) != 1:
raise Exception("Wrong dimension for this Y data. It should have only one dimensions.") raise Exception(
"Wrong dimension for this Y data. It should have only one dimensions.")
def partial_fit_(self, X_data, Y_data, show_loss=True): def partial_fit_(self, X_data, Y_data, show_loss=True):
self.validate_input_X(X_data) self.validate_input_X(X_data)
...@@ -174,25 +192,23 @@ class ONN_THS(ONN): ...@@ -174,25 +192,23 @@ class ONN_THS(ONN):
super().__init__(features_size, max_num_hidden_layers, qtd_neuron_per_hidden_layer, n_classes, b=b, n=n, s=s, super().__init__(features_size, max_num_hidden_layers, qtd_neuron_per_hidden_layer, n_classes, b=b, n=n, s=s,
use_cuda=use_cuda) use_cuda=use_cuda)
self.e = Parameter(torch.tensor(e), requires_grad=False) self.e = Parameter(torch.tensor(e), requires_grad=False)
self.arms_values = Parameter(torch.arange(n_classes), requires_grad=False) self.arms_values = Parameter(
self.n_impressions = Parameter(torch.ones(len(e)), requires_grad=False) torch.arange(n_classes), requires_grad=False)
self.n_rewards = Parameter(torch.ones(len(e)), requires_grad=False) self.explorations_mab = []
for i in range(n_classes):
self.explorations_mab.append(algs.ThompsomSampling(len(e)))
def partial_fit(self, X_data, Y_data, exp_factor, show_loss=True): def partial_fit(self, X_data, Y_data, exp_factor, show_loss=True):
self.partial_fit_(X_data, Y_data, show_loss) self.partial_fit_(X_data, Y_data, show_loss)
self.n_rewards[exp_factor] += 1 self.explorations_mab[Y_data[0]].reward(exp_factor)
def predict(self, X_data): def predict(self, X_data):
pred = self.predict_(X_data)[0] pred = self.predict_(X_data)[0]
rewards_0 = self.n_impressions - self.n_rewards exp_factor = self.explorations_mab[pred].select()[0]
rewards_0[rewards_0 <= 0] = 1 if np.random.uniform() < self.e[exp_factor]:
theta_value = np.random.beta(self.n_rewards, rewards_0)
ranked_arms = np.flip(np.argsort(theta_value), axis=0)
chosen_arm = ranked_arms[0].item()
self.n_impressions[chosen_arm] += 1
if np.random.uniform() < self.e[chosen_arm]:
removed_arms = self.arms_values.clone().numpy().tolist() removed_arms = self.arms_values.clone().numpy().tolist()
removed_arms.remove(pred) removed_arms.remove(pred)
return random.choice(removed_arms), chosen_arm return random.choice(removed_arms), exp_factor
return pred, chosen_arm return pred, exp_factor
...@@ -6,13 +6,13 @@ with open(path.join(this_directory, 'README.md'), encoding='utf-8') as f: ...@@ -6,13 +6,13 @@ with open(path.join(this_directory, 'README.md'), encoding='utf-8') as f:
long_description = f.read() long_description = f.read()
setup(name='onn', setup(name='onn',
version='0.1.6', version='0.1.8',
description='Online Neural Network', description='Online Neural Network',
url='https://github.com/alison-carrera/onn', url='https://github.com/alison-carrera/onn',
author='Alison Carrera', author='Alison Carrera',
author_email='alison.carrera2007@gmail.com', author_email='alison.carrera2007@gmail.com',
packages=find_packages(), packages=find_packages(),
install_requires=['numpy', 'torch'], install_requires=['numpy', 'torch', 'mabalgs'],
long_description=long_description, long_description=long_description,
long_description_content_type='text/markdown', long_description_content_type='text/markdown',
license='Apache 2.0', license='Apache 2.0',
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment