import torch
from torch import nn
import numpy as np
from termcolor import colored
#array data points: x1, x2
data = np.array([
[1,10,1],
[3,10,0],
[1.8,2.0,0],
[-1,-1,1],
[-2,10,1],
])
#features
x = torch.from_numpy(data[:, [0,1]]).float()
#target/labels
y = torch.from_numpy(data[:, [2]]).float()
#custom values (neuron weights on rows)
w1 = torch.tensor([[0.1000, 0.2000],
[0.1000, 0.2000],
[0.1000, 0.2000],
[0.1000, 0.2000]])
w2 = torch.tensor([[0.1000, 0.2000, 0.3000, 0.4000],
[0.1000, 0.2000, 0.3000, 0.4000],
[0.1000, 0.2000, 0.3000, 0.4000]])
w3 = torch.tensor([[0.1000, 0.2000, 0.3000],
[0.1000, 0.2000, 0.3000]])
w4 = torch.tensor([[0.1000, 0.2000]])
b1 = torch.tensor([[0.1, 0.2, 0.3, 0.4]])
b2 = torch.tensor([[0.1, 0.2, 0.3]])
b3 = torch.tensor([[0.1, 0.2]])
b4 = torch.tensor([[0.1]])
class NN:
def __init__(self, n_input, n_hidden1, n_hidden2, n_hidden3, n_output):
self.w1 = torch.randn(n_input, n_hidden1, dtype=torch.float, requires_grad=True)
self.w2 = torch.randn(n_hidden1, n_hidden2, dtype=torch.float, requires_grad=True)
self.w3 = torch.randn(n_hidden2, n_hidden3, dtype=torch.float, requires_grad=True)
self.w4 = torch.randn(n_hidden3, n_output, dtype=torch.float, requires_grad=True)
self.b1 = torch.randn(1, n_hidden1, dtype=torch.float, requires_grad=True)
self.b2 = torch.randn(1, n_hidden2, dtype=torch.float, requires_grad=True)
self.b3 = torch.randn(1, n_hidden3, dtype=torch.float, requires_grad=True)
self.b4 = torch.randn(1, n_output, dtype=torch.float, requires_grad=True)
def forward(self,x):
o = torch.nn.Sigmoid()(torch.mm(w1,x.T)+(b1.T))
print("I",o)
o = torch.nn.Sigmoid()(torch.mm(w2,o)+(b2.T))
print("II",o)
o = torch.nn.Sigmoid()(torch.mm(w3,o)+(b3.T))
print("III",o)
o = torch.nn.Sigmoid()(torch.mm(w4,o)+(b4.T))
print("IV",o)
return o
net = NN(2,4,3,2,1)
#custom weights
net.w1 = w1; net.w2 = w2; net.w3 = w3; net.w4 = w4
net.b1 = b1; net.b2 = b2; net.b3 = b3; net.b4 = b4
print(colored(net.forward(x).T, 'red'))
I tensor([[0.9002, 0.9168, 0.6637, 0.4502, 0.8699],
[0.9089, 0.9241, 0.6857, 0.4750, 0.8808],
[0.9168, 0.9309, 0.7068, 0.5000, 0.8909],
[0.9241, 0.9370, 0.7271, 0.5250, 0.9002]])
II tensor([[0.7343, 0.7370, 0.6913, 0.6457, 0.7292],
[0.7533, 0.7559, 0.7123, 0.6682, 0.7485],
[0.7714, 0.7739, 0.7323, 0.6900, 0.7668]])
III tensor([[0.6354, 0.6358, 0.6298, 0.6237, 0.6348],
[0.6583, 0.6586, 0.6528, 0.6468, 0.6576]])
IV tensor([[0.5733, 0.5733, 0.5729, 0.5724, 0.5732]])
tensor([[0.5733],
[0.5733],
[0.5729],
[0.5724],
[0.5732]])
# relaive to values in "Network weights matrices multiplication study (III)":
# weights = weights.T
# having the explicit network definition above, where
# Linear sum = w * x.T + b
# row - features columns - weights
# ( w1 w2 ... ) * ( x1 ... ) = (x1w1+x2w2 ...)
# ... x2 ... ...
#
# nn.Linear will use weights, bias (NOT transposed) :
# Linear sum = W * x + b
class Network(nn.Module):
def __init__(self):
super().__init__()
self.linear1 = nn.Linear(2,4)
self.linear2 = nn.Linear(4,3)
self.linear3 = nn.Linear(3,2)
self.linear4 = nn.Linear(2,1)
self.activation = nn.Sigmoid()
def forward(self,x):
o = torch.nn.Sigmoid()(self.linear1(x))
o = torch.nn.Sigmoid()(self.linear2(o))
o = torch.nn.Sigmoid()(self.linear3(o))
o = torch.nn.Sigmoid()(self.linear4(o))
return o
net = Network()
#print(net)
#custom weights
net.linear1.load_state_dict( {'weight': w1, 'bias': b1[0]} )
net.linear2.load_state_dict( {'weight': w2, 'bias': b2[0]} )
net.linear3.load_state_dict( {'weight': w3, 'bias': b3[0]} )
net.linear4.load_state_dict( {'weight': w4, 'bias': b4[0]} )
#or
net.load_state_dict( {
'linear1.weight': w1, 'linear1.bias': b1[0],
'linear2.weight': w2, 'linear2.bias': b2[0],
'linear3.weight': w3, 'linear3.bias': b3[0],
'linear4.weight': w4, 'linear4.bias': b4[0],
} )
print(net.state_dict())
print(colored(net(x), 'red'))
OrderedDict([('linear1.weight', tensor([[0.1000, 0.2000],
[0.1000, 0.2000],
[0.1000, 0.2000],
[0.1000, 0.2000]])), ('linear1.bias', tensor([0.1000, 0.2000, 0.3000, 0.4000])), ('linear2.weight', tensor([[0.1000, 0.2000, 0.3000, 0.4000],
[0.1000, 0.2000, 0.3000, 0.4000],
[0.1000, 0.2000, 0.3000, 0.4000]])), ('linear2.bias', tensor([0.1000, 0.2000, 0.3000])), ('linear3.weight', tensor([[0.1000, 0.2000, 0.3000],
[0.1000, 0.2000, 0.3000]])), ('linear3.bias', tensor([0.1000, 0.2000])), ('linear4.weight', tensor([[0.1000, 0.2000]])), ('linear4.bias', tensor([0.1000]))])
tensor([[0.5733],
[0.5733],
[0.5729],
[0.5724],
[0.5732]], grad_fn=<SigmoidBackward>)
net = nn.Sequential(nn.Linear(2, 4),
nn.Sigmoid(),
nn.Linear(4, 3),
nn.Sigmoid(),
nn.Linear(3, 2),
nn.Sigmoid(),
nn.Linear(2, 1),
nn.Sigmoid()
)
print(net)
#custom weights
net[0].load_state_dict( {'weight': w1, 'bias': b1[0]} )
net[2].load_state_dict( {'weight': w2, 'bias': b2[0]} )
net[4].load_state_dict( {'weight': w3, 'bias': b3[0]} )
net[6].load_state_dict( {'weight': w4, 'bias': b4[0]} )
#or
net.load_state_dict( {
'0.weight': w1, '0.bias': b1[0],
'2.weight': w2, '2.bias': b2[0],
'4.weight': w3, '4.bias': b3[0],
'6.weight': w4, '6.bias': b4[0],
} )
print(net.state_dict())
print(colored(net(x), 'red'))
Sequential(
(0): Linear(in_features=2, out_features=4, bias=True)
(1): Sigmoid()
(2): Linear(in_features=4, out_features=3, bias=True)
(3): Sigmoid()
(4): Linear(in_features=3, out_features=2, bias=True)
(5): Sigmoid()
(6): Linear(in_features=2, out_features=1, bias=True)
(7): Sigmoid()
)
OrderedDict([('0.weight', tensor([[0.1000, 0.2000],
[0.1000, 0.2000],
[0.1000, 0.2000],
[0.1000, 0.2000]])), ('0.bias', tensor([0.1000, 0.2000, 0.3000, 0.4000])), ('2.weight', tensor([[0.1000, 0.2000, 0.3000, 0.4000],
[0.1000, 0.2000, 0.3000, 0.4000],
[0.1000, 0.2000, 0.3000, 0.4000]])), ('2.bias', tensor([0.1000, 0.2000, 0.3000])), ('4.weight', tensor([[0.1000, 0.2000, 0.3000],
[0.1000, 0.2000, 0.3000]])), ('4.bias', tensor([0.1000, 0.2000])), ('6.weight', tensor([[0.1000, 0.2000]])), ('6.bias', tensor([0.1000]))])
tensor([[0.5733],
[0.5733],
[0.5729],
[0.5724],
[0.5732]], grad_fn=<SigmoidBackward>)