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

Fixed algorithm for imbalanced dataset.

parent bf7f95bb
This diff is collapsed.
......@@ -7,6 +7,7 @@ import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.nn.parameter import Parameter
from mab import algs
class ONN(nn.Module):
......@@ -17,27 +18,34 @@ class ONN(nn.Module):
if torch.cuda.is_available() and use_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.max_num_hidden_layers = max_num_hidden_layers
self.qtd_neuron_per_hidden_layer = qtd_neuron_per_hidden_layer
self.n_classes = n_classes
self.batch_size = batch_size
self.b = Parameter(torch.tensor(b), 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.b = Parameter(torch.tensor(
b), 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.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):
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):
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.output_layers = nn.ModuleList(self.output_layers).to(self.device)
......@@ -65,7 +73,8 @@ class ONN(nn.Module):
for out in predictions_per_layer:
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)
w = []
......@@ -73,23 +82,29 @@ class ONN(nn.Module):
for i in range(len(losses_per_layer)):
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].bias.data -= self.n * self.alpha[i] * self.output_layers[i].bias.grad.data
self.output_layers[i].weight.data -= self.n * \
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)
b.append(self.alpha[i] * self.hidden_layers[i].bias.grad.data)
self.zero_grad()
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].bias.data -= self.n * torch.sum(torch.cat(b[i:]))
self.hidden_layers[i].weight.data -= self.n * \
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)):
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)
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:
real_output = torch.sum(torch.mul(
......@@ -115,7 +130,8 @@ class ONN(nn.Module):
hidden_connections.append(x)
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 = []
......@@ -128,11 +144,13 @@ class ONN(nn.Module):
def validate_input_X(self, data):
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):
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):
self.validate_input_X(X_data)
......@@ -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,
use_cuda=use_cuda)
self.e = Parameter(torch.tensor(e), requires_grad=False)
self.arms_values = Parameter(torch.arange(n_classes), requires_grad=False)
self.n_impressions = Parameter(torch.ones(len(e)), requires_grad=False)
self.n_rewards = Parameter(torch.ones(len(e)), requires_grad=False)
self.arms_values = Parameter(
torch.arange(n_classes), 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):
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):
pred = self.predict_(X_data)[0]
rewards_0 = self.n_impressions - self.n_rewards
rewards_0[rewards_0 <= 0] = 1
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]:
exp_factor = self.explorations_mab[pred].select()[0]
if np.random.uniform() < self.e[exp_factor]:
removed_arms = self.arms_values.clone().numpy().tolist()
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:
long_description = f.read()
setup(name='onn',
version='0.1.6',
version='0.1.8',
description='Online Neural Network',
url='https://github.com/alison-carrera/onn',
author='Alison Carrera',
author_email='alison.carrera2007@gmail.com',
packages=find_packages(),
install_requires=['numpy', 'torch'],
install_requires=['numpy', 'torch', 'mabalgs'],
long_description=long_description,
long_description_content_type='text/markdown',
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