Merge pull request #41 from lucasdelimanogueira/tmp

unit test nn module mse loss and sigmoid
This commit is contained in:
lucasdelimanogueira 2024-05-07 18:13:42 -03:00 committed by GitHub
commit 52b92e3668
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 123 additions and 9 deletions

View file

@ -1,2 +1,3 @@
from norch.tensor import Tensor
from .nn import *
from .optim import *

View file

@ -22,4 +22,4 @@ class MSELoss(Loss):
assert labels.shape == predictions.shape, \
"Labels and predictions shape does not match: {} and {}".format(labels.shape, predictions.shape)
return ((predictions - labels) **2).sum()
return ((predictions - labels) ** 2).sum() / predictions.numel

View file

@ -29,6 +29,10 @@ class Tensor:
self.ndim = len(shape)
self.device = device
self.numel = 1
for s in self.shape:
self.numel *= s
self.requires_grad = requires_grad
self.grad = None
self.grad_fn = None
@ -84,6 +88,7 @@ class Tensor:
result_data.shape = self.shape.copy()
result_data.ndim = self.ndim
result_data.device = self.device
result_data.numel = self.numel
return result_data
@ -100,7 +105,8 @@ class Tensor:
result_data.shape = self.shape.copy()
result_data.ndim = self.ndim
result_data.device = self.device
result_data.numel = self.numel
return result_data
def reshape(self, new_shape):
@ -117,6 +123,7 @@ class Tensor:
result_data.shape = new_shape.copy()
result_data.ndim = len(new_shape)
result_data.device = self.device
result_data.numel = self.numel
result_data.requires_grad = self.requires_grad
if result_data.requires_grad:
@ -229,7 +236,8 @@ class Tensor:
result_data.shape = self.shape.copy()
result_data.ndim = self.ndim
result_data.device = self.device
result_data.numel = self.numel
result_data.requires_grad = self.requires_grad or other.requires_grad
if result_data.requires_grad:
result_data.grad_fn = AddBackward(self, other)
@ -253,7 +261,8 @@ class Tensor:
result_data.shape = self.shape.copy()
result_data.ndim = self.ndim
result_data.device = self.device
result_data.numel = self.numel
result_data.requires_grad = self.requires_grad or other.requires_grad
if result_data.requires_grad:
result_data.grad_fn = AddBackward(other, self)
@ -277,6 +286,7 @@ class Tensor:
result_data.shape = self.shape.copy()
result_data.ndim = self.ndim
result_data.device = self.device
result_data.numel = self.numel
result_data.requires_grad = self.requires_grad or other.requires_grad
if result_data.requires_grad:
@ -301,6 +311,7 @@ class Tensor:
result_data.shape = self.shape.copy()
result_data.ndim = self.ndim
result_data.device = self.device
result_data.numel = self.numel
result_data.requires_grad = self.requires_grad or other.requires_grad
if result_data.requires_grad:
@ -314,7 +325,8 @@ class Tensor:
result_data.shape = self.shape.copy()
result_data.ndim = self.ndim
result_data.device = self.device
result_data.numel = self.numel
Tensor._C.scalar_mul_tensor.argtypes = [ctypes.POINTER(CTensor), ctypes.c_float]
Tensor._C.scalar_mul_tensor.restype = ctypes.POINTER(CTensor)
@ -339,6 +351,7 @@ class Tensor:
result_data.shape = self.shape.copy()
result_data.ndim = self.ndim
result_data.device = self.device
result_data.numel = self.numel
result_data.requires_grad = self.requires_grad or other.requires_grad
if result_data.requires_grad:
@ -371,6 +384,10 @@ class Tensor:
result_data.shape = [other.shape[0], self.shape[0], other.shape[2]]
result_data.ndim = 3
result_data.device = self.device
result_data.numel = 1
for s in result_data.shape:
result_data.numel *= s
elif self.ndim == 3 and other.ndim == 3:
#broadcasted 3D x 3D matmul
@ -385,7 +402,8 @@ class Tensor:
result_data.shape = [other.shape[0], self.shape[1], other.shape[2]]
result_data.ndim = 3
result_data.device = self.device
for s in result_data.shape:
result_data.numel *= s
else:
#2D matmul
if self.ndim != 2 or other.ndim != 2:
@ -404,6 +422,8 @@ class Tensor:
result_data.shape = [self.shape[0], other.shape[1]]
result_data.ndim = 2
result_data.device = self.device
for s in result_data.shape:
result_data.numel *= s
result_data.requires_grad = self.requires_grad or other.requires_grad
if result_data.requires_grad:
@ -423,7 +443,8 @@ class Tensor:
result_data.shape = self.shape.copy()
result_data.ndim = self.ndim
result_data.device = self.device
result_data.numel = self.numel
result_data.requires_grad = self.requires_grad
if result_data.requires_grad:
result_data.grad_fn = PowBackward(self, other)
@ -442,7 +463,8 @@ class Tensor:
result_data.shape = self.shape.copy()
result_data.ndim = self.ndim
result_data.device = self.device
result_data.numel = self.numel
result_data.requires_grad = self.requires_grad
if result_data.requires_grad:
result_data.grad_fn = PowBackward(other, self)
@ -462,7 +484,8 @@ class Tensor:
result_data.shape = self.shape.copy()
result_data.ndim = self.ndim
result_data.device = self.device
result_data.numel = self.numel
result_data.requires_grad = self.requires_grad
if result_data.requires_grad:
result_data.grad_fn = DivisionBackward(self, other)
@ -478,6 +501,7 @@ class Tensor:
result_data.shape = self.shape.copy()
result_data.ndim = self.ndim
result_data.device = self.device
result_data.numel = self.numel
result_data.requires_grad = self.requires_grad or other.requires_grad
if result_data.requires_grad:
@ -500,6 +524,7 @@ class Tensor:
result_data.shape = self.shape.copy()
result_data.ndim = self.ndim
result_data.device = self.device
result_data.numel = self.numel
result_data.requires_grad = self.requires_grad
if result_data.requires_grad:
@ -519,6 +544,7 @@ class Tensor:
result_data.shape = self.shape.copy()
result_data.ndim = self.ndim
result_data.device = self.device
result_data.numel = self.numel
result_data.requires_grad = self.requires_grad
if result_data.requires_grad:
@ -537,6 +563,7 @@ class Tensor:
result_data.shape = [1]
result_data.ndim = 1
result_data.device = self.device
result_data.numel = 1
result_data.requires_grad = self.requires_grad
if result_data.requires_grad:
@ -562,6 +589,7 @@ class Tensor:
result_data.shape[axis2] = self.shape[axis1]
result_data.ndim = self.ndim
result_data.device = self.device
result_data.numel = self.numel
result_data.requires_grad = self.requires_grad
if result_data.requires_grad:
@ -582,6 +610,7 @@ class Tensor:
result_data.shape = self.shape.copy()[::-1]
result_data.ndim = self.ndim
result_data.device = self.device
result_data.numel = self.numel
result_data.requires_grad = self.requires_grad
if result_data.requires_grad:

84
tests/test_nn.py Normal file
View file

@ -0,0 +1,84 @@
import unittest
import norch
from norch import utils
import torch
import os
class TestNNModule(unittest.TestCase):
def setUp(self):
self.device = os.environ.get('device')
if self.device is None or self.device != 'cuda':
self.device = 'cpu'
def test_mse_loss(self):
"""
Test the MSELoss
"""
loss_fn_norch = norch.nn.MSELoss()
loss_fn_torch = torch.nn.MSELoss()
# Test case 1: Predictions and labels are equal
predictions_norch = norch.Tensor([1.1, 2, 3, 4])
labels_norch = norch.Tensor([1.1, 2, 3, 4])
loss_norch = loss_fn_norch.forward(predictions_norch, labels_norch)
loss_torch_result = utils.to_torch(loss_norch)
predictions_torch = torch.tensor([1.1, 2, 3, 4])
labels_torch = torch.tensor([1.1, 2, 3, 4])
loss_torch_expected = loss_fn_torch(predictions_torch, labels_torch)
self.assertTrue(utils.compare_torch(loss_torch_result, loss_torch_expected))
# Test case 2: Predictions and labels are different
predictions_norch = norch.Tensor([1.1, 2, 3, 4])
labels_norch = norch.Tensor([4, 3, 2.1, 1])
loss_norch = loss_fn_norch.forward(predictions_norch, labels_norch)
loss_torch_result = utils.to_torch(loss_norch)
predictions_torch = torch.tensor([1.1, 2, 3, 4])
labels_torch = torch.tensor([4, 3, 2.1, 1])
loss_torch_expected = loss_fn_torch(predictions_torch, labels_torch)
print(loss_torch_result, loss_torch_expected)
self.assertTrue(utils.compare_torch(loss_torch_result, loss_torch_expected))
def test_sigmoid_activation(self):
"""
Test Sigmoid activation function
"""
sigmoid_fn_norch = norch.nn.Sigmoid()
sigmoid_fn_torch = torch.nn.Sigmoid()
# Test case 1: Positive input
x = norch.Tensor([1, 2, 3])
sigmoid_norch = sigmoid_fn_norch.forward(x)
sigmoid_torch_result = utils.to_torch(sigmoid_norch)
x = torch.tensor([1, 2, 3])
sigmoid_torch_expected = sigmoid_fn_torch.forward(x)
self.assertTrue(utils.compare_torch(sigmoid_torch_result, sigmoid_torch_expected))
# Test case 1: Negative input
x = norch.Tensor([-1, 2, -3])
sigmoid_norch = sigmoid_fn_norch.forward(x)
sigmoid_torch_result = utils.to_torch(sigmoid_norch)
x = torch.tensor([-1, 2, -3])
sigmoid_torch_expected = sigmoid_fn_torch.forward(x)
self.assertTrue(utils.compare_torch(sigmoid_torch_result, sigmoid_torch_expected))
# Test case 1: Zero input
x = norch.Tensor([0, 0, 0])
sigmoid_norch = sigmoid_fn_norch.forward(x)
sigmoid_torch_result = utils.to_torch(sigmoid_norch)
x = torch.tensor([0, 0, 0])
sigmoid_torch_expected = sigmoid_fn_torch.forward(x)
self.assertTrue(utils.compare_torch(sigmoid_torch_result, sigmoid_torch_expected))