12.09 深度学习-经典神经网络LeNets5

发布于:2024-12-18 ⋅ 阅读:(152) ⋅ 点赞:(0)

# 一共七层,3个卷积层,2个池化层,2个全连接层

# 三个卷积层:

# ​ C1包括6个5×5卷积核

# ​ C3包括60个5×5卷积核(通道)

# ​ C5包括120×16个5×5卷积核

# 两个池化层S2和S4:

# ​ 都是2×2的平均池化,并添加了非线性映射

# 第一个全连接层:84个神经元

# 第二个全连接层: 10个神经元

# 所有激活函数采用Sigmoid

import torch

import torch.nn as nn

def demo1():

    class LeNets5_C3_12(nn.Module):

        def __init__(self,in_channels=3,total_channels=6,*args, **kwargs):

            super().__init__(*args, **kwargs)

            self.in_channels=in_channels

            self.total_channels=total_channels

            self.C3=nn.ModuleList([nn.Conv2d(self.in_channels,1,kernel_size=5) for i in range(self.total_channels)])

        def forward(self,x):

            c3_out_total=torch.empty(x.shape[0],0,x.shape[2]-4,x.shape[3]-4)

            # 针对12到14的特色情况

            if self.total_channels==3:

                for i in range(len(self.C3)):

                    index=[(0+i)%6,(1+i)%6,(2+i)%6,(3+i)%6,(4+i)%6,(5+i)%6]

                    index.pop(-1)

                    index.pop(2)

                    c3_out=self.C3[i](x[:,[j for j in index],:,:])

                   

                    # 拼接C3层总的输出特征图 在dim=1 上  

                    # print(c3_out.shape)

                    c3_out_total=torch.cat([c3_out_total,c3_out],dim=1)

               

                return c3_out_total

           

            for i in range(len(self.C3)):

                c3_out=self.C3[i](x[:,[j%6 for j in range(i,i+int(self.in_channels))],:,:])

               

                # 拼接C3层总的输出特征图 在dim=1 上

                # print(c3_out.shape)

                c3_out_total=torch.cat([c3_out_total,c3_out],dim=1)

           

            return c3_out_total

           

    class LeNets5(nn.Module):

        def __init__(self, *args, **kwargs):

            super().__init__(*args, **kwargs)

            self.C1=nn.Sequential(nn.Conv2d(1,6,kernel_size=5),nn.ReLU())

            self.S2=nn.AdaptiveMaxPool2d(14) # 自动池化 传入输出图的大小 特征图的数量不变

            # LeNets5非密集的特征图连接关系 目的是减少参数量的同时效果不会下降太多

            # # LeNets5 网络C3层的特殊处理 每个输出通道的输入通道 不一样  输入的通道数是一样的 使用列表推导式创建6个(3,1,kernel_size=5)的卷积核

            # self.C3_3_1=nn.ModuleList([nn.Conv2d(3,1,kernel_size=5) for i in range(6)])

            # self.C3_4_1=nn.ModuleList([nn.Conv2d(4,1,kernel_size=5) for i in range(6)])

            # # C3 前12个很像 可以单独做一个小的神经网络

            # 创建 C3层前12个通道

            self.C3_3_1=LeNets5_C3_12(3)

            self.C3_4_1=LeNets5_C3_12(4)

            self.C3_4__1=LeNets5_C3_12(4,3)

            self.C3_6_1=nn.Sequential(nn.Conv2d(6,1,kernel_size=5))

            self.S4=nn.AdaptiveMaxPool2d(5) # 自动池化 传入输出图的大小 特征图的数量不变

            self.C5=nn.Sequential(nn.Linear(16*5*5,120),nn.ReLU())

            self.F6=nn.Sequential(nn.Linear(120,84),nn.ReLU())

            self.out=nn.Sequential(nn.Linear(84,10),nn.Softmax())

        def forward(self,x):

            x=self.C1(x)

            x=self.S2(x)

            # c3_out_total=torch.empty(x.shape[0],0,x.shape[2]-4,x.shape[3]-4) # 通道数为0 size 减4个 要在通道上面拼接 卷积完后形状 减了4

            # # C3层传入 上层输出的NCHW为 1 6 28 28 C3层每一个小层传入 012,123,234,345 。。。

            # for i in self.C3_3_1:

            #     c3_out=i(x[:,[j%6 for j in range(i,i+3)],:,:])

            #     # 拼接C3层总的输出特征图 在dim=1 上

            #     torch.cat(c3_out_total,c3_out)

            # for i in self.C3_4_1:

            #     c3_out=i(x[:,[j%6 for j in range(i,i+4)],:,:])

            #     # 拼接C3层总的输出特征图 在dim=1 上

            #     torch.cat(c3_out_total,c3_out)

            c3_out_3_1=self.C3_3_1(x)

            c3_out_4_1=self.C3_4_1(x)

            # print(c3_out_3_1.shape)

            # print(c3_out_4_1.shape)

            c3_out_4__1=self.C3_4__1(x)

            # print(c3_out_4__1.shape)

            c3_out_6_1=self.C3_6_1(x)

            # print(c3_out_6_1.shape)

            x=torch.cat([c3_out_3_1,c3_out_4_1,c3_out_4__1,c3_out_6_1],dim=1)

            x=nn.ReLU(x)

            x=self.S4(x)

            x=x.view(x.shape[0],-1)

            x=self.C5(x)

            x=self.F6(x)

            x=self.out(x)

            return x

    # 图像NCHW

    img1=torch.randn(1,1,32,32)

    net1=LeNets5()

    res=net1.forward(img1)

    print(res)

    # 进行训练 。。。





 

if __name__=="__main__":

    pass

    demo1()


网站公告

今日签到

点亮在社区的每一天
去签到