Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I'm having trouble initializing a MATLAB class

I'm new to object-oriented programming with MATLAB and I'm having trouble initializing a class I'm building. I'm building a neural network from scratch, and I'm using the following class called network with an initialization function called layers:

classdef network

properties
    sizes
    biases
    weights
    nLayers
end

methods
    function [ ] = layers(self)
        self.nLayers = length(self.sizes);
        self.biases{1} = zeros(self.sizes(1));
        for i = 2:self.nLayers
            self.biases{i} = zeros(self.sizes(i), 1);
            for j = 1:self.sizes(i)
                bias(j, 1) = normRand(0);
            end
            self.biases{i} = bias(1:j, 1);
        end
        for i = 2:self.nLayers
            for j = 1:self.sizes(i)
                 for k = 1:self.sizes(i-1)
                     weight(j, k) = normRand(0);
                 end
            end
            self.weights{i} = weight(1:j, 1:k);
        end
    end

So after I create a variable net of class network and set the sizes as below:

>> net = network; net.sizes = [2 3 2 4]

net = 

  network with properties:

  sizes: [2 3 2 4]
 biases: []
weights: []
nLayers: []

I run the layers function, but nothing updates.

>> net.layers
>> net

net = 

  network with properties:

  sizes: [2 3 2 4]
 biases: []
weights: []
nLayers: []

What's confusing to me is that if I set a break point at the end of the layers function, I get these results in debugging mode:

>> net.layers
29          end
K>> self

self = 

  network with properties:

  sizes: [2 3 2 4]
 biases: {[2×2 double]  [3×1 double]  [2×1 double]  [4×1 double]}
weights: {[]  [3×2 double]  [2×3 double]  [4×2 double]}
nLayers: 4

Which is the result I'm looking for. Any idea as to what I'm doing wrong? Also, does anyone know of a way to pass an input to a class so that I could create my network like: net = network(sizes) ?

Also, I understand that python is much better for neural networks and that even java would be a better alternative. I'm doing this as a learning exercise and am not really interested in anyone's opinion on which language is best for this.

Thanks

like image 484
Adam Johnston Avatar asked May 17 '26 00:05

Adam Johnston


2 Answers

Matlab has two types of classes - value classes and handle classes. By default, Matlab's classes are value classes, which means that Matlab operates on a copy of the object, rather than a reference to it. In the example, the layers method is operating on a copy of the object and the net object is not updated as you observed.

This article explains the differences in detail: https://www.mathworks.com/help/matlab/matlab_oop/comparing-handle-and-value-classes.html

There are two solutions to the problem:

1) Keep using a value class and return the modified object from the layers function

function self = layers(self)

Then use assignment to update the object.

net = net.layers

2) Use a handle class by deriving network from the handle class.

classdef network < handle

The layers function will now modify a reference to the object.

The link below contains more information on object modification in Matlab.

https://www.mathworks.com/help/matlab/matlab_oop/matlab-vs-other-oo-languages.html#bslvcv1

like image 99
user8550137 Avatar answered May 19 '26 16:05

user8550137


You need to return the modified self object from the layers method:

function self = layers(self)
  ...

This is because classes in MATLAB are value classes by default (i.e. methods that modify the object must return the modified object as an output argument). Alternatively, you can also design your class with reference-like behavior by making it a handle class. Some useful examples of value and handle classes can be found here, along with guidelines for when to use them.

In addition, you can create a constructor for your class object, which can take a set of inputs to initialize it with. For example, it could be designed like so:

function self = network(sizes, biases, weights, nLayers)
  if (nargin > 0)
    self.sizes = sizes;
  end
  if (nargin > 1)
    self.biases = biases;
  end
  if (nargin > 2)
    self.weights = weights;
  end
  if (nargin > 3)
    self.nLayers = nLayers;
  end
end

You could then instantiate it like so:

net = network([2 3 2 4]);  % Sets sizes to [2 3 2 4] and other properties to []
like image 38
gnovice Avatar answered May 19 '26 16:05

gnovice