In [2]:
import torch

Single layer network


In [9]:
def activation(x):
    """ sigmoid activation function
        
        Arguments
        ---------
        x: torch.Tensor
    
    """
    return 1 / (1 + torch.exp(-x))

In [32]:
torch.manual_seed(7)

features = torch.randn((1, 5))

weights = torch.rand_like(features)

bias = torch.randn((1, 1))

In [41]:
activation(torch.sum(features * weights) + bias)


Out[41]:
tensor([[0.6140]])

In [58]:
# more efficient than use * and sum
activation(torch.mm(features, weights.view((5, 1))) + bias)


Out[58]:
tensor([[0.6140]])

In [59]:
print(weights)

print(weights.t())

# return a new tensor with same data in memory, sometimes a clone, as it copies data to another part of memory
print(weights.reshape((5, 1)))

# return the same tensor with different shape. sometimes, return less or more value if the shape is not matched
print(weights.resize_((5, 1)))

# 100% return a new tensor with the same data without messing with the memory. will return error if shape is not matched
print(weights.view((5, 1)))


tensor([[0.2868],
        [0.2063],
        [0.4451],
        [0.3593],
        [0.7204]])
tensor([[0.2868, 0.2063, 0.4451, 0.3593, 0.7204]])
tensor([[0.2868],
        [0.2063],
        [0.4451],
        [0.3593],
        [0.7204]])
tensor([[0.2868],
        [0.2063],
        [0.4451],
        [0.3593],
        [0.7204]])
tensor([[0.2868],
        [0.2063],
        [0.4451],
        [0.3593],
        [0.7204]])

Multilayer networks


In [76]:
torch.manual_seed(7)

features = torch.randn((1, 3))

n_input = features.shape[1]
n_hidden = 2
n_output = 1

W1 = torch.randn(n_input, n_hidden)
W2 = torch.randn(n_hidden, n_output)

B1 = torch.randn((1, n_hidden))
B2 = torch.randn((1, n_output))

In [79]:
H1 = activation(torch.mm(features, W1) + B1)
H2 = activation(torch.mm(H1, W2) + B2)

In [80]:
H2


Out[80]:
tensor([[0.3171]])

Numpy to Torch and back


In [82]:
import numpy as np

In [92]:
a = np.random.rand(4, 3)
print(a)


[[0.71828501 0.64917534 0.46701439]
 [0.78901262 0.46355998 0.74960835]
 [0.2584754  0.12586124 0.68107892]
 [0.55671805 0.97806068 0.70196968]]

In [93]:
b = torch.from_numpy(a)
print(b)


tensor([[0.7183, 0.6492, 0.4670],
        [0.7890, 0.4636, 0.7496],
        [0.2585, 0.1259, 0.6811],
        [0.5567, 0.9781, 0.7020]], dtype=torch.float64)

In [94]:
b.numpy()


Out[94]:
array([[0.71828501, 0.64917534, 0.46701439],
       [0.78901262, 0.46355998, 0.74960835],
       [0.2584754 , 0.12586124, 0.68107892],
       [0.55671805, 0.97806068, 0.70196968]])

memory is shared so data will change if you change the values in the other


In [95]:
b.mul_(2)


Out[95]:
tensor([[1.4366, 1.2984, 0.9340],
        [1.5780, 0.9271, 1.4992],
        [0.5170, 0.2517, 1.3622],
        [1.1134, 1.9561, 1.4039]], dtype=torch.float64)

In [96]:
a


Out[96]:
array([[1.43657002, 1.29835067, 0.93402878],
       [1.57802523, 0.92711996, 1.4992167 ],
       [0.51695079, 0.25172249, 1.36215783],
       [1.11343611, 1.95612135, 1.40393935]])

In [ ]: