【问题标题】:I'm having trouble initializing a MATLAB class我在初始化 MATLAB 类时遇到问题
【发布时间】:2018-03-21 02:29:24
【问题描述】:

我是使用 MATLAB 进行面向对象编程的新手,在初始化我正在构建的类时遇到了麻烦。我正在从头开始构建一个神经网络,我正在使用以下名为 network 的类和一个名为 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

所以在我创建了一个类网络的变量网络并将大小设置如下:

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

net = 

  network with properties:

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

我运行图层函数,但没有任何更新。

>> net.layers
>> net

net = 

  network with properties:

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

让我感到困惑的是,如果我在层函数的末尾设置一个断点,我会在调试模式下得到这些结果:

>> 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

这是我正在寻找的结果。关于我做错了什么的任何想法?另外,有没有人知道将输入传递给类的方法,以便我可以创建我的网络,例如: 净 = 网络(大小) ?

另外,我知道 python 更适合神经网络,甚至 java 也会是更好的选择。我这样做是为了学习,我对任何人对哪种语言最适合这个问题的看法并不感兴趣。

谢谢

【问题讨论】:

    标签: matlab class oop object initialization


    【解决方案1】:

    Matlab 有两种类型的类——值类和句柄类。默认情况下,Matlab 的类是值类,这意味着 Matlab 对对象的副本进行操作,而不是对它的引用。在示例中,layers 方法正在对对象的副本进行操作,而 net 对象并未像您观察到的那样更新。

    这篇文章详细解释了不同之处: https://www.mathworks.com/help/matlab/matlab_oop/comparing-handle-and-value-classes.html

    这个问题有两种解决方案:

    1) 继续使用值类并从layers 函数返回修改后的对象

    function self = layers(self)
    

    然后使用赋值更新对象。

    net = net.layers
    

    2) 通过从句柄类派生network 来使用句柄类。

    classdef network < handle
    

    layers 函数现在将修改对对象的引用。

    下面的链接包含更多关于在 Matlab 中修改对象的信息。

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

    【讨论】:

      【解决方案2】:

      你需要从layers方法返回修改后的self对象:

      function self = layers(self)
        ...
      

      这是因为 MATLAB 中的类默认为 value classes(即修改对象的方法必须将修改后的对象作为输出参数返回)。或者,您也可以通过将其设为handle class 来设计具有类似引用行为的类。可以在 here 找到一些有用的值和句柄类示例,以及何时使用它们的指南。

      此外,您可以为您的类对象创建一个constructor,它可以使用一组输入来初始化它。例如,它可以这样设计:

      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
      

      然后你可以像这样实例化它:

      net = network([2 3 2 4]);  % Sets sizes to [2 3 2 4] and other properties to []
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-02-20
        • 2020-11-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-17
        相关资源
        最近更新 更多