【问题标题】:Why does feedforwardnet(int32(8)) raise an error while feedforwardnet(double(8)) doesn't?为什么 feedforwardnet(int32(8)) 会引发错误,而 feedforwardnet(double(8)) 不会?
【发布时间】:2013-04-04 06:04:51
【问题描述】:

在 MATLAB 中,feedforwardnet(8) 创建一个前馈网络,其中一个隐藏层包含 8 个隐藏神经元。 MATLAB 将数值数据存储为双精度浮点 (double) by default。因此feedforwardnet(8) 等价于feedforwardnet(double(8))

但是,feedforwardnet(int32(8)) 会引发以下错误:

Undefined function or variable 'ind'.

Error in network/subsasgn>setLayerSize (line 1170)
  err = sprintf('"layers{%g}.size" must be a positive integer.',ind);

Error in network/subsasgn>network_subsasgn (line 180)
        if isempty(err), [net,err] = setLayerSize(net,i,newSize); end

Error in network/subsasgn (line 13)
net = network_subsasgn(net,subscripts,v,netname);

Error in feedforwardnet>create_network (line 116)
      net.layers{i}.size = param.hiddenSizes(i);

Error in feedforwardnet (line 69)
    net = create_network(param);

为什么feedforwardnet() 不接受int32 作为参数?等效地,当给定int32(8) 作为参数时,为什么isposint()(在*network/subsasgn.m,第1169 行)不返回true

代码已使用 MATLAB 2011a、2012a 和 2012b 进行了测试。

【问题讨论】:

    标签: neural-network matlab


    【解决方案1】:

    不确定您使用的是哪个版本的工具箱,但 isposint(v) 的 1.7 版测试如下参数:

    [...]
    if ~isa(v,'double') | any(size(v) ~= [1 1]) | ...
      ~isreal(v) | v<0 | round(v) ~= v
    [...]
    

    这意味着它将为不是doubledouble 的子类的所有内容返回false

    至于 "Undefined function or variable 'ind'." 消息,我的猜测是因为代码中的错误(变量 ind 未创建/分配/传递作为函数中任意位置的参数)。

    【讨论】:

    • 谢谢,但是如果参数是 int32(或 int8/int64)返回 false 有什么意义呢?我觉得拒绝一个 int32 说函数需要一个整数是很奇怪的。
    • 我必须承认我不知道作者决定使用isa(v,'double') 而不是例如isnumeric(v)。可能是某些库已针对使用双精度浮点数的快速执行进行了调整,而任何其他数字类型都需要转换为 double,这需要时间。或者,也许作者想避免追逐由混合整数/浮点算术引起的潜在错误的痛苦,并强制使用独特的类型来处理。或者这可能是作者用来测试此类值的 Matlab 习语。
    • @FranckDernoncourt 那是因为每当您使用double 以外的类型进行算术运算时,matlab 会将结果转换回该类型。例如:uint16(0.6)*2 = 2class(ans) 将是 uint16。所以isposint 函数正在测试以确保它是double 类的整数,可能是因为要对其进行一些算术运算,但它仍然需要是整数。
    • 好的,在我看来,将 int8, int16, int32, int64, uint8, uint16, uint32, uint64 转换为 double 是一个好主意,尽管它可能会给大量数字带来麻烦(这可能是他们不投的另一个原因)。
    【解决方案2】:

    编辑(风险自负,未经彻底测试)isposint.m 第 9 行:

    % if ~isa(v,'double') | any(size(v) ~= [1 1]) | ...
    if ~isnumeric(v) | any(size(v) ~= [1 1]) | ...
    

    两者都通过:

    a = feedforwardnet(8);
    b = feedforwardnet(int32(8));
    

    大小变化不大:

    >> whos
      Name      Size            Bytes  Class      Attributes
    
      a         1x1             31224  network              
      b         1x1             30968  network
    

    【讨论】:

    • 有趣,谢谢!我猜大小的变化是由于int32是4个字节,而double是8个字节。
    • 是的,这里的重点是,您实际上并没有在内存和性能方面获得太多收益。除非你真的被限制使用int,否则我会选择double
    • int 转换为double 没有问题,您可以使用intmax('uint64')realmax('double') 进行检查,但会产生轻微的性能损失。
    • 好吧,double(intmax('uint64')) 你会失去精确度。但我同意这没什么大不了的,除非你的网络是人脑 ;-)
    • 好吧,被愚弄了(在 2^53 开始失去精度,而 uint64 最大在 2^64-1)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-28
    • 1970-01-01
    • 2014-12-11
    • 1970-01-01
    • 2020-12-09
    • 1970-01-01
    • 2015-09-02
    相关资源
    最近更新 更多