微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

计算CNN中的输出大小

如何解决计算CNN中的输出大小

以下模型中每一层的输出大小是多少?

'''

model = Sequential()
model.add(Conv2D(32,(8,8),padding='same',strides=(4,4),input_shape=(80,80,4)))
model.add(Activation('relu'))
model.add(Conv2D(64,(4,strides=(2,2)))
model.add(Activation('relu'))
model.add(Conv2D(64,(3,3),strides=(1,1)))
model.add(Activation('relu'))
model.add(Flatten())
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dense(2))

'''

Full Traceback (most recent call)

解决方法

TL;DR 如果“输出大小”是指参数的数量,这里是模型的内存大小和训练所需的内存:

-------------------------------------
Layer                   # of Params  
=====================================
Conv2D                  544
-------------------------------------
Conv2D                  8256
-------------------------------------
Conv2D                  36928
-------------------------------------
Dense                   13107712
-------------------------------------
Dense                   1026
=====================================
Total # of Params: 13154466
Model Size: 59.47 MiB
Memory Required to Train: 1.95 GiB
-------------------------------------

这里是计算每个方程的相关方程:

型号:

2D 转换层:

nw = kw * kh * d * d_prev  
nb = d 
n = nw + nb

密集层:

nw = no * ni  
nb = no  
n = nw + nb

培训:

2D 转换层:

n = wi * hi * dl

密集层:

n = no

图例:

nw = 权重参数的数量
nb = 偏置参数的数量
kw = 内核宽度
kh = 内核高度
d = 当前层的深度
d_prev = 上一层的深度
否 = 输出数量
ni = 输入数量
nt = 训练参数的数量
n = 参数总数

对于 1 的批量大小,59.47 MiB 进行训练。对于 32 的批量大小,1.95 GiB 进行训练。


一个很好的资源是内存使用计算注意事项,作者是 Kevin McGuinness。您可以在 YouTube here 上观看他的演示。他在 YouTube 帖子的信息部分提供了幻灯片的链接,但它们是 here 供您参考(查找 D2L1(第 2 天,第 1 课)。

这取决于四件事:

  1. 数据类型的大小,
  2. 模型中的参数数量,
  3. 存储训练输出所需的参数数量,以及
  4. 您的批量大小

默认情况下,tensorflow 使用 32 位浮点数据类型(这些大小为 4 个字节,因为一个字节有 8 个位)。

这是我为计算它而编写的代码。它与 keras 将输出的内容几乎相同,但还包括内存要求

源代码:

def model_params_Conv2D(d_n,k_w,k_h,d_n_prev,s_x=1,s_y=1):
    """Calculate the number of model parameters in a 2D Convolution Layer

    Args:
        d_n ([int]): Depth of current layer
        k_w ([int]]): Kernel width
        k_h ([int]): Kernel height
        d_n_prev ([int]): Depth of previous layer
        s_x ([int]): Strides in x-direction
        s_y ([int]): Strides in y-direction

    Returns:
        [int]: Number of layer parameters
    """
    n_w = d_n * k_w * k_h * d_n_prev // (s_x * s_y)  # Number of weight paramters
    n_b = d_n  # Number of bias parameters

    return n_w + n_b


def model_params_Dense(n_o,n_i):
    """Calculate the number of model parameters in a dense layer

    Args:
        n_o ([int]): Number of output
        n_i ([int]): Number of inputs

    Returns:
        [int]: Number of layer parameters
    """
    n_w = n_o * n_i  # Number of weight parameters
    n_b = n_o  # Number of bias parameters

    return n_w + n_b


def training_params_Conv2D(w_i,h_i,d_l):
    """Calclate number of training parameters in a 2D Convolution layer

    Args:
        w_i (int): Input width
        h_i (int): Input height
        d_l (int): Layer depth
    """
    return w_i * h_i * d_l


def training_params_Dense(n_o):
    """Calculate the number of training parameters in a Dense layer

    Args:
        n_o (int): Number of outputs
    """
    return n_o


def memory_requirement(n_p,m_dt=4):
    """Size of neural network model in bytes

    Args:
        n_p ([int]): Number of parameters
        m_dt ([int]): Memory size of data type in bytes
    Returns:
        [int]: Memory consumption in bytes
    """
    return n_p * m_dt


def SI2ibi(mem):
    """Convert from SI bytes to ibibytes

    Computers use powers of 2,so memory is represented in ibibytes,but
    SI prefixes are powers of 1000)

    kibi (KiB) = (2^10)^1,kilo (KB) = (10^3)^1 (1.024 KiB = 1 KB)
    mebi (MiB) = (2^10)^2,mega (MB) = (10^3)^2 (1.048576 MiB = 1 MB)
    gibi (GiB) = (2^10)^3,giga (GB) = (10^3)^3 (1.073741824 GiB = 1 GB)

    Args:
        mem ([int]): Memory size in bytes
    """
    KB = 10 ** 3
    MB = KB ** 2
    GB = KB ** 3

    KB2KiB = 1 / 1.024
    MB2MiB = 1 / 1.048576
    GB2GiB = 1 / 1.073741824

    if mem >= GB:
        mem /= GB * GB2GiB
        units = "GiB"
    elif mem >= MB:
        mem /= MB * MB2MiB
        units = "MiB"
    else:  # mem >= KB
        mem /= KB * KB2KiB
        units = "KiB"

    return mem,units


if __name__ == "__main__":
    # NOTE: Activation layers don't require any parameters. Use depth of
    #  input as d_n_prev of first layer.

    input_shape = (80,80,4)
    w_i = input_shape[0]  # Input width
    h_i = input_shape[1]  # Input height
    d_i = input_shape[2]  # Input depth

    conv01_params = model_params_Conv2D(
        d_n=32,k_w=8,k_h=8,d_n_prev=d_i,s_x=4,s_y=4
    )
    conv02_params = model_params_Conv2D(d_n=64,k_w=4,k_h=4,d_n_prev=32,s_x=2,s_y=2)
    conv03_params = model_params_Conv2D(d_n=64,k_w=3,k_h=3,d_n_prev=64)
    dense01_params = model_params_Dense(n_i=w_i * h_i * d_i,n_o=512)
    dense02_params = model_params_Dense(n_i=512,n_o=2)

    num_model_params = (
        conv01_params + conv02_params + conv03_params + dense01_params + dense02_params
    )

    header_ = "Layer\t\t\t# of Params"
    len_header_ = len(repr(header_.expandtabs()))
    bar_eq_ = "=" * len_header_
    bar_dash_ = "-" * len_header_

    num_training_params = training_params_Conv2D(w_i,32)
    num_training_params += training_params_Conv2D(w_i,64)
    num_training_params += training_params_Conv2D(w_i,64)
    num_training_params += training_params_Dense(512)
    num_training_params += training_params_Dense(2)

    model_memory = memory_requirement(num_model_params)
    training_memory = memory_requirement(num_training_params)
    total_memory = model_memory + training_memory

    batch_size = 32

    mem,units = SI2ibi(total_memory)
    mem32,units32 = SI2ibi(total_memory * batch_size)

    print(f"{bar_dash_}")
    print(f"{header_}")
    print(f"{bar_eq_}")
    print(f"Conv2D\t\t\t{conv01_params}")
    print(f"{bar_dash_}")
    print(f"Conv2D\t\t\t{conv02_params}")
    print(f"{bar_dash_}")
    print(f"Conv2D\t\t\t{conv03_params}")
    print(f"{bar_dash_}")
    print(f"Dense\t\t\t{dense01_params}")
    print(f"{bar_dash_}")
    print(f"Dense\t\t\t{dense02_params}")
    print(f"{bar_eq_}")
    print(f"Total # of Params: {num_model_params}")
    print(f"Model Size: {mem:.2f} {units}")
    print(f"Memory Required to Train: {mem32:.2f} {units32}")
    print(f"{bar_dash_}")

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。