GoogLeNet卷积神经网络输出数据形参分析-笔记

这篇具有很好参考价值的文章主要介绍了GoogLeNet卷积神经网络输出数据形参分析-笔记。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

GoogLeNet卷积神经网络输出数据形参分析-笔记

分析结果为:
输入数据形状:[10, 3, 224, 224]
最后输出结果:linear_0 [10, 1] [1024, 1] [1]

子空间执行逻辑

def forward_old(self, x):
        # 支路1只包含一个1x1卷积
        p1 = F.relu(self.p1_1(x))
        # 支路2包含 1x1卷积 + 3x3卷积
        p2 = F.relu(self.p2_2(F.relu(self.p2_1(x))))
        # 支路3包含 1x1卷积 + 5x5卷积
        p3 = F.relu(self.p3_2(F.relu(self.p3_1(x))))
        # 支路4包含 最大池化和1x1卷积
        p4 = F.relu(self.p4_2(self.p4_1(x)))
        # 将每个支路的输出特征图拼接在一起作为最终的输出结果
        return paddle.concat([p1, p2, p3, p4], axis=1)
        # return self.batchnorm()

其中拼接张量情况为:
拼接代码:paddle.concat([p1, p2, p3, p4], axis=1)

p1=[10,64,5,6,56]
p2=[10,128,56,56]
p3=[10,32,56,56]
p4=[10,32,56,56]
拼接后结果为:【10,256,56,56】 sum(64+128+32+32)=256

分析详细过程如下所示:

PS E:\project\python> & D:/ProgramData/Anaconda3/python.exe e:/project/python/PM/GoogLeNet_PM.py
W0804 11:14:26.736726  5484 gpu_resources.cc:61] Please NOTE: device: 0, GPU Compute Capability: 6.1, Driver API Version: 12.2, Runtime API Version: 10.2
W0804 11:14:26.747695  5484 gpu_resources.cc:91] device: 0, cuDNN Version: 7.6.
116
(10, 3, 224, 224)
[10, 3, 224, 224]
#第一模块  包括一个7X7的卷积
conv2d_0 [10, 64, 224, 224] [64, 3, 7, 7] [64]
# 3x3最大池化
max_pool2d_0 [10, 64, 112, 112]
# 第二个模块包含2个卷积层
conv2d_1 [10, 64, 112, 112] [64, 64, 1, 1] [64]
conv2d_2 [10, 192, 112, 112] [192, 64, 3, 3] [192]
# 3x3最大池化
max_pool2d_1 [10, 192, 56, 56]
# 第三个模块包含2个Inception块
print block3-1: Inception盗梦空间1 即子空间1
conv2d_3 [10, 64, 56, 56] [64, 192, 1, 1] [64]
conv2d_4 [10, 96, 56, 56] [96, 192, 1, 1] [96]
conv2d_5 [10, 128, 56, 56] [128, 96, 3, 3] [128]
conv2d_6 [10, 16, 56, 56] [16, 192, 1, 1] [16]
conv2d_7 [10, 32, 56, 56] [32, 16, 5, 5] [32]
max_pool2d_2 [10, 192, 56, 56]
conv2d_8 [10, 32, 56, 56] [32, 192, 1, 1] [32]
block3_1.shape= [10, 256, 56, 56]
print block3-2: Inception盗梦空间2  即子空间2
conv2d_9 [10, 128, 56, 56] [128, 256, 1, 1] [128]
conv2d_10 [10, 128, 56, 56] [128, 256, 1, 1] [128]
conv2d_11 [10, 192, 56, 56] [192, 128, 3, 3] [192]
conv2d_12 [10, 32, 56, 56] [32, 256, 1, 1] [32]
conv2d_13 [10, 96, 56, 56] [96, 32, 5, 5] [96]
max_pool2d_3 [10, 256, 56, 56]
conv2d_14 [10, 64, 56, 56] [64, 256, 1, 1] [64]
block3_2.shape= [10, 480, 56, 56]
# 3x3最大池化
max_pool2d_4 [10, 480, 28, 28]
# 第四个模块包含5个Inception块
print block4_1:
conv2d_15 [10, 192, 28, 28] [192, 480, 1, 1] [192]
conv2d_16 [10, 96, 28, 28] [96, 480, 1, 1] [96]
conv2d_17 [10, 208, 28, 28] [208, 96, 3, 3] [208]
conv2d_18 [10, 16, 28, 28] [16, 480, 1, 1] [16]
conv2d_19 [10, 48, 28, 28] [48, 16, 5, 5] [48]
max_pool2d_5 [10, 480, 28, 28]
conv2d_20 [10, 64, 28, 28] [64, 480, 1, 1] [64]
block4_1.shape= [10, 512, 28, 28]
print block4_2:
conv2d_21 [10, 160, 28, 28] [160, 512, 1, 1] [160]
conv2d_22 [10, 112, 28, 28] [112, 512, 1, 1] [112]
conv2d_23 [10, 224, 28, 28] [224, 112, 3, 3] [224]
conv2d_24 [10, 24, 28, 28] [24, 512, 1, 1] [24]
conv2d_25 [10, 64, 28, 28] [64, 24, 5, 5] [64]
max_pool2d_6 [10, 512, 28, 28]
conv2d_26 [10, 64, 28, 28] [64, 512, 1, 1] [64]
block4_2.shape= [10, 512, 28, 28]
print block4_3:
conv2d_27 [10, 128, 28, 28] [128, 512, 1, 1] [128]
conv2d_28 [10, 128, 28, 28] [128, 512, 1, 1] [128]
conv2d_29 [10, 256, 28, 28] [256, 128, 3, 3] [256]
conv2d_30 [10, 24, 28, 28] [24, 512, 1, 1] [24]
conv2d_31 [10, 64, 28, 28] [64, 24, 5, 5] [64]
max_pool2d_7 [10, 512, 28, 28]
conv2d_32 [10, 64, 28, 28] [64, 512, 1, 1] [64]
block4_3.shape= [10, 512, 28, 28]
print block4_4:
conv2d_33 [10, 112, 28, 28] [112, 512, 1, 1] [112]
conv2d_34 [10, 144, 28, 28] [144, 512, 1, 1] [144]
conv2d_35 [10, 288, 28, 28] [288, 144, 3, 3] [288]
conv2d_36 [10, 32, 28, 28] [32, 512, 1, 1] [32]
conv2d_37 [10, 64, 28, 28] [64, 32, 5, 5] [64]
max_pool2d_8 [10, 512, 28, 28]
conv2d_38 [10, 64, 28, 28] [64, 512, 1, 1] [64]
block4_4.shape= [10, 528, 28, 28]
print block4_5:
conv2d_39 [10, 256, 28, 28] [256, 528, 1, 1] [256]
conv2d_40 [10, 160, 28, 28] [160, 528, 1, 1] [160]
conv2d_41 [10, 320, 28, 28] [320, 160, 3, 3] [320]
conv2d_42 [10, 32, 28, 28] [32, 528, 1, 1] [32]
conv2d_43 [10, 128, 28, 28] [128, 32, 5, 5] [128]
max_pool2d_9 [10, 528, 28, 28]
conv2d_44 [10, 128, 28, 28] [128, 528, 1, 1] [128]
block4_5.shape= [10, 832, 28, 28]
max_pool2d_10 [10, 832, 14, 14]
# 第五个模块包含2个Inception块(block5_1,block5_2)
print block5_1:
conv2d_45 [10, 256, 14, 14] [256, 832, 1, 1] [256]
conv2d_46 [10, 160, 14, 14] [160, 832, 1, 1] [160]
conv2d_47 [10, 320, 14, 14] [320, 160, 3, 3] [320]
conv2d_48 [10, 32, 14, 14] [32, 832, 1, 1] [32]
conv2d_49 [10, 128, 14, 14] [128, 32, 5, 5] [128]
max_pool2d_11 [10, 832, 14, 14]
conv2d_50 [10, 128, 14, 14] [128, 832, 1, 1] [128]
block5_1.shape= [10, 832, 14, 14]
print block5_2:
conv2d_51 [10, 384, 14, 14] [384, 832, 1, 1] [384]
conv2d_52 [10, 192, 14, 14] [192, 832, 1, 1] [192]
conv2d_53 [10, 384, 14, 14] [384, 192, 3, 3] [384]
conv2d_54 [10, 48, 14, 14] [48, 832, 1, 1] [48]
conv2d_55 [10, 128, 14, 14] [128, 48, 5, 5] [128]
max_pool2d_12 [10, 832, 14, 14]
conv2d_56 [10, 128, 14, 14] [128, 832, 1, 1] [128]
block5_2.shape= [10, 1024, 14, 14]
adaptive_avg_pool2d_0 [10, 1024, 1, 1]
linear_0 [10, 1] [1024, 1] [1]
PS E:\project\python>

分析测试代码如下所示:文章来源地址https://www.toymoban.com/news/detail-625706.html

# GoogLeNet模型代码
#GoogLeNet卷积神经网络-笔记
import numpy as np
import paddle
from paddle.nn import Conv2D, MaxPool2D, AdaptiveAvgPool2D, Linear
## 组网
import paddle.nn.functional as F

#分析形参定制版本方法
def printItem(item,x):
      # item是CNN类中的一个子层
      # 查看经过子层之后的输出数据形状
      try:
          x = item(x)
      except:
          x = paddle.reshape(x, [x.shape[0], -1])
          x = item(x)         
      if len(item.parameters())==2:
          # 查看卷积和全连接层的数据和参数的形状,
          # 其中item.parameters()[0]是权重参数w,item.parameters()[1]是偏置参数b
          print(item.full_name(), x.shape, item.parameters()[0].shape, item.parameters()[1].shape)
      else:
          # 池化层没有参数
          print(item.full_name(), x.shape) 
      return x;        

# 定义Inception块
class Inception(paddle.nn.Layer):
    def __init__(self, c0, c1, c2, c3, c4, **kwargs):
        '''
        Inception模块的实现代码,
        
        c1,图(b)中第一条支路1x1卷积的输出通道数,数据类型是整数
        c2,图(b)中第二条支路卷积的输出通道数,数据类型是tuple或list, 
               其中c2[0]是1x1卷积的输出通道数,c2[1]是3x3
        c3,图(b)中第三条支路卷积的输出通道数,数据类型是tuple或list, 
               其中c3[0]是1x1卷积的输出通道数,c3[1]是3x3
        c4,图(b)中第一条支路1x1卷积的输出通道数,数据类型是整数
        '''
        super(Inception, self).__init__()
        # 依次创建Inception块每条支路上使用到的操作
        self.p1_1 = Conv2D(in_channels=c0,out_channels=c1, kernel_size=1, stride=1)
        self.p2_1 = Conv2D(in_channels=c0,out_channels=c2[0], kernel_size=1, stride=1)
        self.p2_2 = Conv2D(in_channels=c2[0],out_channels=c2[1], kernel_size=3, padding=1, stride=1)
        self.p3_1 = Conv2D(in_channels=c0,out_channels=c3[0], kernel_size=1, stride=1)
        self.p3_2 = Conv2D(in_channels=c3[0],out_channels=c3[1], kernel_size=5, padding=2, stride=1)
        self.p4_1 = MaxPool2D(kernel_size=3, stride=1, padding=1)
        self.p4_2 = Conv2D(in_channels=c0,out_channels=c4, kernel_size=1, stride=1)
        
        # # 新加一层batchnorm稳定收敛
        # self.batchnorm = paddle.nn.BatchNorm2D(c1+c2[1]+c3[1]+c4)

    def forward_old(self, x):
        # 支路1只包含一个1x1卷积
        p1 = F.relu(self.p1_1(x))
        # 支路2包含 1x1卷积 + 3x3卷积
        p2 = F.relu(self.p2_2(F.relu(self.p2_1(x))))
        # 支路3包含 1x1卷积 + 5x5卷积
        p3 = F.relu(self.p3_2(F.relu(self.p3_1(x))))
        # 支路4包含 最大池化和1x1卷积
        p4 = F.relu(self.p4_2(self.p4_1(x)))
        # 将每个支路的输出特征图拼接在一起作为最终的输出结果
        return paddle.concat([p1, p2, p3, p4], axis=1)
        # return self.batchnorm()
    #分析形参定制版本方法
    def forward(self,x):
        p1=printItem(self.p1_1,x)
        p1=F.relu(p1)
        #
        p2=printItem(self.p2_1,x)
        p2=F.relu(p2)
        p2=printItem(self.p2_2,p2)
        p2=F.relu(p2)
        #
        p3=printItem(self.p3_1,x)
        p3=F.relu(p3)
        p3=printItem(self.p3_2,p3)
        p3=F.relu(p3)
        #
        p4=printItem(self.p4_1,x)
        p4=printItem(self.p4_2,p4)
        p4=F.relu(p4)
        return paddle.concat([p1, p2, p3, p4], axis=1);

    
class GoogLeNet(paddle.nn.Layer):
    def __init__(self):
        super(GoogLeNet, self).__init__()
        # GoogLeNet包含五个模块,每个模块后面紧跟一个池化层
        # 第一个模块包含1个卷积层
        self.conv1 = Conv2D(in_channels=3,out_channels=64, kernel_size=7, padding=3, stride=1)
        # 3x3最大池化
        self.pool1 = MaxPool2D(kernel_size=3, stride=2, padding=1)
        # 第二个模块包含2个卷积层
        self.conv2_1 = Conv2D(in_channels=64,out_channels=64, kernel_size=1, stride=1)
        self.conv2_2 = Conv2D(in_channels=64,out_channels=192, kernel_size=3, padding=1, stride=1)
        # 3x3最大池化
        self.pool2 = MaxPool2D(kernel_size=3, stride=2, padding=1)
        # 第三个模块包含2个Inception块
        self.block3_1 = Inception(192, 64, (96, 128), (16, 32), 32)
        self.block3_2 = Inception(256, 128, (128, 192), (32, 96), 64)
        # 3x3最大池化
        self.pool3 = MaxPool2D(kernel_size=3, stride=2, padding=1)
        # 第四个模块包含5个Inception块
        self.block4_1 = Inception(480, 192, (96, 208), (16, 48), 64)
        self.block4_2 = Inception(512, 160, (112, 224), (24, 64), 64)
        self.block4_3 = Inception(512, 128, (128, 256), (24, 64), 64)
        self.block4_4 = Inception(512, 112, (144, 288), (32, 64), 64)
        self.block4_5 = Inception(528, 256, (160, 320), (32, 128), 128)
        # 3x3最大池化
        self.pool4 = MaxPool2D(kernel_size=3, stride=2, padding=1)
        # 第五个模块包含2个Inception块
        self.block5_1 = Inception(832, 256, (160, 320), (32, 128), 128)
        self.block5_2 = Inception(832, 384, (192, 384), (48, 128), 128)
        # 全局池化,用的是global_pooling,不需要设置pool_stride
        self.pool5 = AdaptiveAvgPool2D(output_size=1)
        self.fc = Linear(in_features=1024, out_features=1)
        

    def forward(self, x):
        x = self.pool1(F.relu(self.conv1(x)))
        x = self.pool2(F.relu(self.conv2_2(F.relu(self.conv2_1(x)))))
        x = self.pool3(self.block3_2(self.block3_1(x)))
        x = self.block4_3(self.block4_2(self.block4_1(x)))
        x = self.pool4(self.block4_5(self.block4_4(x)))
        x = self.pool5(self.block5_2(self.block5_1(x)))
        x = paddle.reshape(x, [x.shape[0], -1])
        x = self.fc(x)
        return x
     
    #分析形参定制版本方法 
    def printStruct(self,x):
        print(x.shape)
        x = paddle.to_tensor(x)  #转为张量x
        print(x.shape)
        #
        x=printItem(self.conv1,x)
        x=F.relu(x)
        x=printItem(self.pool1,x)
        #
        x=printItem(self.conv2_1,x) 
        x=F.relu(x)
        x=printItem(self.conv2_2,x)  
        x=F.relu(x)  
        x=printItem(self.pool2,x)
        #    
        print('print block3-1:')    
        x=self.block3_1(x)
        print('block3_1.shape=',x.shape)
        print('print block3-2:') 
        x=self.block3_2(x) 
        print('block3_2.shape=',x.shape)       
        x=printItem(self.pool3,x) 
        #
        print('print block4_1:')    
        x=self.block4_1(x)
        print('block4_1.shape=',x.shape)  
        print('print block4_2:') 
        x=self.block4_2(x)  
        print('block4_2.shape=',x.shape)
        print('print block4_3:') 
        x=self.block4_3(x)  
        print('block4_3.shape=',x.shape)
        print('print block4_4:') 
        x=self.block4_4(x) 
        print('block4_4.shape=',x.shape)
        print('print block4_5:') 
        x=self.block4_5(x)    
        print('block4_5.shape=',x.shape)  
        x=printItem(self.pool4,x) 
        #
        print('print block5_1:') 
        x=self.block5_1(x)  
        print('block5_1.shape=',x.shape) 
        print('print block5_2:') 
        x=self.block5_2(x)    
        print('block5_2.shape=',x.shape)   
        x=printItem(self.pool5,x) 
        x = paddle.reshape(x, [x.shape[0], -1])
        x=printItem(self.fc,x)
        return x

#=================================
import PM
# 创建模型
model = GoogLeNet()
print(len(model.parameters()))
opt = paddle.optimizer.Momentum(learning_rate=0.001, momentum=0.9, parameters=model.parameters(), weight_decay=0.001)
# 启动训练过程
#PM.train_pm(model, opt)

'''
#输出结果:
PS E:\project\python> & D:/ProgramData/Anaconda3/python.exe e:/project/python/PM/GoogLeNet_PM.py
W0803 18:25:55.522811  8308 gpu_resources.cc:61] Please NOTE: device: 0, GPU Compute Capability: 6.1, Driver API Version: 12.2, Runtime API Version: 10.2
W0803 18:25:55.532805  8308 gpu_resources.cc:91] device: 0, cuDNN Version: 7.6.
116
start training ...
epoch: 0, batch_id: 0, loss is: 0.6920
epoch: 0, batch_id: 20, loss is: 0.8546
[validation] accuracy/loss: 0.7100/0.5381
epoch: 1, batch_id: 0, loss is: 0.6177
epoch: 1, batch_id: 20, loss is: 0.4581
[validation] accuracy/loss: 0.9400/0.3120
epoch: 2, batch_id: 0, loss is: 0.2858
epoch: 2, batch_id: 20, loss is: 0.5234
[validation] accuracy/loss: 0.5975/0.5757
epoch: 3, batch_id: 0, loss is: 0.6338
epoch: 3, batch_id: 20, loss is: 0.3180
[validation] accuracy/loss: 0.9575/0.1915
epoch: 4, batch_id: 0, loss is: 0.1087
epoch: 4, batch_id: 20, loss is: 0.3728
[validation] accuracy/loss: 0.9500/0.2322
PS E:\project\python>
'''

# 输入数据形状是 [N, 3, H, W]
# 这里用np.random创建一个随机数组作为输入数据
x = np.random.randn(*[10,3,224,224])
x = x.astype('float32')
# 创建CNN类的实例,指定模型名称和分类的类别数目
#model = VGG(1)
#
model.printStruct(x);
#



到了这里,关于GoogLeNet卷积神经网络输出数据形参分析-笔记的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包