计算神经网络内存占用

如果layer.count_params()或者model.summary()权重参数个数为负数的可以参考:
彻底解决keras model.summary()或者layer.count_params()权重参数个数为负数问题
举两个例子,一张(1024,1024,3)的图片,分别使用VGGNet,DenseNet网络。

一.VGGNet内存消耗计算

'''
Created on 2018年9月30日

'''

from keras import applications
import numpy as np

import cv2
image = cv2.imread("D:\\xxxx\\hashiqi.jpg")
image = cv2.resize(image,(1024,1024),interpolation = cv2.INTER_CUBIC)
x_train = np.expand_dims(image,axis=0)
y_train = np.array([0])
print(image.shape)
# (1024, 1024, 3)

model = applications.VGG16(input_shape=(1024,1024,3),include_top=False,weights=None)
print("无全连接层总参数量:",model.count_params())
model = applications.VGG16(input_shape=(1024,1024,3),include_top=True,weights=None)
print("有全连接层总参数量:",model.count_params())
# 无全连接层总参数量: 14714688
# 有全连接层总参数量: 2183080744 可见权重都基本占用在全连接层

all_params_memory = 0
all_feature_memory = 0
for layer in model.layers:
    #训练权重w占用的内存
    params_memory = layer.count_params()/(1024*1024) * 4
    print("训练权重w占用的内存:",layer.name,layer.count_params(),str(params_memory)+" M")
    all_params_memory = all_params_memory + params_memory
    #特征图占用内存
    feature_shape = layer.output_shape
    feature_size = 1
    for i in range(1,len(feature_shape)):
        feature_size = feature_size*feature_shape[i]
    feature_memory = feature_size/(1024*1024) * 4
    print("特征图占用内存:",feature_shape,feature_size,str(feature_memory)+" M")
    all_feature_memory = all_feature_memory + feature_memory

# 特征图占用内存: (None, 1024, 1024, 3) 3145728 12.0 M
# 训练权重w占用的内存: block1_conv1 1792 0.0068359375 M
# 特征图占用内存: (None, 1024, 1024, 64) 67108864 256.0 M
# 训练权重w占用的内存: block1_conv2 36928 0.140869140625 M
# 特征图占用内存: (None, 1024, 1024, 64) 67108864 256.0 M
# 训练权重w占用的内存: block1_pool 0 0.0 M
# 特征图占用内存: (None, 512, 512, 64) 16777216 64.0 M
# 训练权重w占用的内存: block2_conv1 73856 0.28173828125 M
# 特征图占用内存: (None, 512, 512, 128) 33554432 128.0 M
# 训练权重w占用的内存: block2_conv2 147584 0.56298828125 M
# 特征图占用内存: (None, 512, 512, 128) 33554432 128.0 M
# 训练权重w占用的内存: block2_pool 0 0.0 M
# 特征图占用内存: (None, 256, 256, 128) 8388608 32.0 M
# 训练权重w占用的内存: block3_conv1 295168 1.1259765625 M
# 特征图占用内存: (None, 256, 256, 256) 16777216 64.0 M
# 训练权重w占用的内存: block3_conv2 590080 2.2509765625 M
# 特征图占用内存: (None, 256, 256, 256) 16777216 64.0 M
# 训练权重w占用的内存: block3_conv3 590080 2.2509765625 M
# 特征图占用内存: (None, 256, 256, 256) 16777216 64.0 M
# 训练权重w占用的内存: block3_pool 0 0.0 M
# 特征图占用内存: (None, 128, 128, 256) 4194304 16.0 M
# 训练权重w占用的内存: block4_conv1 1180160 4.501953125 M
# 特征图占用内存: (None, 128, 128, 512) 8388608 32.0 M
# 训练权重w占用的内存: block4_conv2 2359808 9.001953125 M
# 特征图占用内存: (None, 128, 128, 512) 8388608 32.0 M
# 训练权重w占用的内存: block4_conv3 2359808 9.001953125 M
# 特征图占用内存: (None, 128, 128, 512) 8388608 32.0 M
# 训练权重w占用的内存: block4_pool 0 0.0 M
# 特征图占用内存: (None, 64, 64, 512) 2097152 8.0 M
# 训练权重w占用的内存: block5_conv1 2359808 9.001953125 M
# 特征图占用内存: (None, 64, 64, 512) 2097152 8.0 M
# 训练权重w占用的内存: block5_conv2 2359808 9.001953125 M
# 特征图占用内存: (None, 64, 64, 512) 2097152 8.0 M
# 训练权重w占用的内存: block5_conv3 2359808 9.001953125 M
# 特征图占用内存: (None, 64, 64, 512) 2097152 8.0 M
# 训练权重w占用的内存: block5_pool 0 0.0 M
# 特征图占用内存: (None, 32, 32, 512) 524288 2.0 M
# 训练权重w占用的内存: flatten 0 0.0 M
# 特征图占用内存: (None, 524288) 524288 2.0 M
# 训练权重w占用的内存: fc1 2147487744 8192.015625 M
# 特征图占用内存: (None, 4096) 4096 0.015625 M
# 训练权重w占用的内存: fc2 16781312 64 .015625 M
# 特征图占用内存: (None, 4096) 4096 0.015625 M
# 训练权重w占用的内存: predictions 4097000 15.628814697265625 M
# 特征图占用内存: (None, 1000) 1000 0.003814697265625 M
    
print("网络权重W占用总内存:",str(all_params_memory)+" M")
print("网络特征图占用总内存:",str(all_feature_memory)+" M")
print("网络总消耗内存:",str(all_params_memory+all_feature_memory)+" M")
# 网络权重W占用总内存: 8327.79214477539 M
# 网络特征图占用总内存: 1216.0350647 M
# 网络总消耗内存: 9543.82720947 M

二.DenseNet内存消耗计算

'''
Created on 2018年9月30日

'''

from keras import applications
import numpy as np

import cv2
image = cv2.imread("D:\\xxx\\hashiqi.jpg")
image = cv2.resize(image,(1024,1024),interpolation = cv2.INTER_CUBIC)
x_train = np.expand_dims(image,axis=0)
y_train = np.array([0])
print(image.shape)
# (1024, 1024, 3)

model = applications.DenseNet201(input_shape=(1024,1024,3),include_top=False,weights=None)
print("无全连接层总参数量:",model.count_params())
model = applications.DenseNet201(input_shape=(1024,1024,3),include_top=True,weights=None)
print("有全连接层总参数量:",model.count_params())
# 无全连接层总参数量: 18321984
# 有全连接层总参数量: 20242984 因为使用了GlobalAveragePooling2D,使得全连接参数少了很多

all_params_memory = 0
all_feature_memory = 0
for layer in model.layers:
    #训练权重w占用的内存
    params_memory = layer.count_params()/(1024*1024) * 4
    print("训练权重w占用的内存:",layer.name,layer.count_params(),str(params_memory)+" M")
    all_params_memory = all_params_memory + params_memory
    #特征图占用内存
    feature_shape = layer.output_shape
    feature_size = 1
    for i in range(1,len(feature_shape)):
        feature_size = feature_size*feature_shape[i]
    feature_memory = feature_size/(1024*1024) * 4
    print("特征图占用内存:",feature_shape,feature_size,str(feature_memory)+" M")
    all_feature_memory = all_feature_memory + feature_memory

# 训练权重w占用的内存: input_2 0 0.0 M
# 特征图占用内存: (None, 1024, 1024, 3) 3145728 12.0 M
# 训练权重w占用的内存: zero_padding2d_3 0 0.0 M
# 特征图占用内存: (None, 1030, 1030, 3) 3182700 12.141036987304688 M
# 训练权重w占用的内存: conv1/conv 9408 0.035888671875 M
# 特征图占用内存: (None, 512, 512, 64) 16777216 64.0 M
# 训练权重w占用的内存: conv1/bn 256 0.0009765625 M
# 特征图占用内存: (None, 512, 512, 64) 16777216 64.0 M
# 训练权重w占用的内存: conv1/relu 0 0.0 M
# 特征图占用内存: (None, 512, 512, 64) 16777216 64.0 M
# .........
    
print("网络权重W占用总内存:",str(all_params_memory)+" M")
print("网络特征图占用总内存:",str(all_feature_memory)+" M")
print("网络总消耗内存:",str(all_params_memory+all_feature_memory)+" M")
# 网络权重W占用总内存: 77.22085571289062 M
# 网络特征图占用总内存: 6151.65315246582 M
# 网络总消耗内存: 6228.874008178711 M 内存消耗基本在特征图上
### 卷积神经网络运行时的内存消耗分析 卷积神经网络(CNN)在运行过程中会占用大量内存资源,主要由以下几个因素决定: #### 1. 输入数据大小 输入图像的分辨率直接影响模型所需的显存空间。高分辨率图像通常需要更大的存储容量来保存激活值和梯度信息。 #### 2. 参数数量 每一层中的权重矩阵和其他参数都会增加整体所需的空间。尤其是全连接层可能占据大部分内存开销,因为它们涉及大量的权值存储[^1]。 #### 3. 特征映射尺寸 随着层数加深,每一步产生的特征图也会相应增大其体积;即使采用池化操作减小空间维度但仍需保留一定比例的信息以便后续处理. --- ### 内存优化策略 为了降低 CNN 的内存需求并提高效率,可以采取以下几种技术手段: #### 使用更高效的架构设计 通过引入跳跃连接(如ResNet),仅让网络学习差异部分而非整个变换过程从而缓解了深层结构带来的梯度消失问题进而减少了不必要的冗余计算.[^1] #### 应用深度可分离卷积 这种方法将标准二维卷积分解成逐通道卷积加上点状投影两阶段完成,在几乎不损失精度前提下极大地削减了浮点运算次数及其伴随而来的临时变量分配压力.[^2] #### 实施批标准化(Batch Normalization) 此方法通过对各批次样本均值方差调整使得前馈传播更加稳定可靠的同时还能起到正则化效果间接促进了收敛速度加快以及资源利用率提升.[^3] #### 调整超参设置 适当缩小初始滤波器尺度或者改变跨距(stride)数值亦有助于控制最终输出规模不至于过大以至于超出硬件承载极限范围之外.[^4] ```python import tensorflow as tf model = tf.keras.Sequential([ tf.keras.layers.Conv2D(filters=64, kernel_size=(3,3), strides=(1,1), padding='same', input_shape=[28, 28, 1]), tf.keras.layers.BatchNormalization(), tf.keras.layers.ReLU(), tf.keras.layers.MaxPooling2D(pool_size=(2, 2)), ]) ``` 上述代码片段展示了一个简单的 CNN 构建流程,其中包含了批量归一化的应用实例。 ---
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值