unit test nn module mse loss and sigmoid
This commit is contained in:
parent
d767fb5e2a
commit
7e3100f796
7 changed files with 123 additions and 9 deletions
|
|
@ -1,2 +1,3 @@
|
|||
from norch.tensor import Tensor
|
||||
from .nn import *
|
||||
from .optim import *
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -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
|
||||
|
|
@ -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
84
tests/test_nn.py
Normal 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))
|
||||
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue