pytorch定义大量层 如何循环操作:pytorch是假定了, 所有w层都作为self的属性被维持了

本文探讨了在PyTorch中错误初始化模型层导致的精度损失问题。错误写法1通过列表乘法创建全连接层,导致部分权重未被正确跟踪,测试集精度下降5%。错误写法2使用列表推导式创建全连接层,测试集精度下降2%。正确做法是显式地为每个全连接层创建单独的模型属性,确保权重在计算梯度时被正确处理,从而保持预期的精度水平。
摘要由CSDN通过智能技术生成

错误写法1 (在本案例中,此错误写法导致第1个epoch的测试集精度降低5%)


class Net(nn.Module):
    """
    简写约定:
    小格子:cell, (一个28*28的图片被分割成7*7个 4*4的小格子)
    层级:level:lv
    选择器:selector:sel
    分类器:classify:clsfy
    尺寸:size:sz
    输出:output:o
    激活:active:a, 经过非线性函数后的输出 称为 激活 或 激活值
    输入:input:in
    图片高度:高度:height:h
    图片宽度:宽度:width:w
    图片高度*图片宽度:height*width:HW:hw
    全连接:full connection:fc
    self.level*_fc*:lv*_fc*
    self.level1_selector:lv1_sel
    self.classify_fc:clsfy_fc
    LV1_FC_O_SZ:LEVEL1_FC_OUTPUT_SIZE

    """
    LEVEL1_FC_CNT =5 #5:指代__init__中的5个self.level1_fc*
    lv1_w_pair_cnt=int(LEVEL1_FC_CNT*(LEVEL1_FC_CNT-1)/2)
    def __init__(self):
        super(Net, self).__init__()
        CELL_HW=MnistDim.CELL_HW
        CELL_H = MnistDim.CELL_H
        CELL_W = MnistDim.CELL_W
        CELL_CNT_H = MnistDim.CELL_CNT_H
        CELL_CNT_W = MnistDim.CELL_CNT_W
        LV1_FC_O_SZ = MnistDim.LV1_FC_O_SZ
        CLSFY_FC_IN_SZ = MnistDim.CLSFY_FC_IN_SZ
        self.lv1_sel=nn.Linear(CELL_HW, Net.LEVEL1_FC_CNT)#(4*4, 5)# lv1_sel: 在以下5个lv1_fc*中选择哪一个
        
		#下面这行写法是错误的,  错误原因是  pytorch是假定了, 所有w层都作为self的属性被维持了
        self.lv1_fc = [nn.Linear(CELL_HW, LV1_FC_O_SZ, bias=False)]*Net.LEVEL1_FC_CNT#5个 (4*4, 2)
        #对于哪些没有被self维持的w层 ,显然在计算梯度时 可能会错过,这显然不是期望的样子,所以测试集精度会降低,本案例中此错误写法导致第1个epoch中 测试集精度比正常写法的测试集精度 降低了5%  (测试集精度只有85%  , 正常写法的测试集精度90%   )
        

错误写法2 (在本案例中,此错误写法导致第1个epoch的测试集精度降低2%)


class Net(nn.Module):
    """
    简写约定:
    小格子:cell, (一个28*28的图片被分割成7*7个 4*4的小格子)
    层级:level:lv
    选择器:selector:sel
    分类器:classify:clsfy
    尺寸:size:sz
    输出:output:o
    激活:active:a, 经过非线性函数后的输出 称为 激活 或 激活值
    输入:input:in
    图片高度:高度:height:h
    图片宽度:宽度:width:w
    图片高度*图片宽度:height*width:HW:hw
    全连接:full connection:fc
    self.level*_fc*:lv*_fc*
    self.level1_selector:lv1_sel
    self.classify_fc:clsfy_fc
    LV1_FC_O_SZ:LEVEL1_FC_OUTPUT_SIZE

    """
    LEVEL1_FC_CNT =5 #5:指代__init__中的5个self.level1_fc*
    lv1_w_pair_cnt=int(LEVEL1_FC_CNT*(LEVEL1_FC_CNT-1)/2)
    def __init__(self):
        super(Net, self).__init__()
        CELL_HW=MnistDim.CELL_HW
        CELL_H = MnistDim.CELL_H
        CELL_W = MnistDim.CELL_W
        CELL_CNT_H = MnistDim.CELL_CNT_H
        CELL_CNT_W = MnistDim.CELL_CNT_W
        LV1_FC_O_SZ = MnistDim.LV1_FC_O_SZ
        CLSFY_FC_IN_SZ = MnistDim.CLSFY_FC_IN_SZ
        self.lv1_sel=nn.Linear(CELL_HW, Net.LEVEL1_FC_CNT)#(4*4, 5)# lv1_sel: 在以下5个lv1_fc*中选择哪一个
        
		#下面这行写法是错误的,  错误原因是  pytorch是假定了, 所有w层都作为self的属性被维持了
        self.lv1_fc = [nn.Linear(CELL_HW, LV1_FC_O_SZ, bias=False) for _ in range(Net.LEVEL1_FC_CNT) ]#5个 (4*4, 2)
        #对于哪些没有被self维持的w层 ,显然在计算梯度时 可能会错过,这显然不是期望的样子,所以测试集精度会降低,本案例中此错误写法导致第1个epoch中 测试集精度比正常写法的测试集精度 降低了2%  (测试集精度只有88%  , 正常写法的测试集精度90%   )
        
#至于为什么  本写法虽然是错误的 但却比错误写法1 稍微好一些  的原因还不清楚  

正确写法


class Net(nn.Module):
    """
    简写约定:
    小格子:cell, (一个28*28的图片被分割成7*7个 4*4的小格子)
    层级:level:lv
    选择器:selector:sel
    分类器:classify:clsfy
    尺寸:size:sz
    输出:output:o
    激活:active:a, 经过非线性函数后的输出 称为 激活 或 激活值
    输入:input:in
    图片高度:高度:height:h
    图片宽度:宽度:width:w
    图片高度*图片宽度:height*width:HW:hw
    全连接:full connection:fc
    self.level*_fc*:lv*_fc*
    self.level1_selector:lv1_sel
    self.classify_fc:clsfy_fc
    LV1_FC_O_SZ:LEVEL1_FC_OUTPUT_SIZE

    """
    LEVEL1_FC_CNT =5 #5:指代__init__中的5个self.level1_fc*
    lv1_w_pair_cnt=int(LEVEL1_FC_CNT*(LEVEL1_FC_CNT-1)/2)
    def __init__(self):
        super(Net, self).__init__()
        CELL_HW=MnistDim.CELL_HW
        CELL_H = MnistDim.CELL_H
        CELL_W = MnistDim.CELL_W
        CELL_CNT_H = MnistDim.CELL_CNT_H
        CELL_CNT_W = MnistDim.CELL_CNT_W
        LV1_FC_O_SZ = MnistDim.LV1_FC_O_SZ
        CLSFY_FC_IN_SZ = MnistDim.CLSFY_FC_IN_SZ
        self.lv1_sel=nn.Linear(CELL_HW, Net.LEVEL1_FC_CNT)#(4*4, 5)# lv1_sel: 在以下5个lv1_fc*中选择哪一个
        #这些w层都被维持为self的属性了,  所以计算梯度时是正常的表现
        self.lv1_fc1 = nn.Linear(CELL_HW, LV1_FC_O_SZ, bias=False)#(4*4, 2)
        self.lv1_fc2 = nn.Linear(CELL_HW, LV1_FC_O_SZ, bias=False)#(4*4, 2)
        self.lv1_fc3 = nn.Linear(CELL_HW, LV1_FC_O_SZ, bias=False)#(4*4, 2)
        self.lv1_fc4 = nn.Linear(CELL_HW, LV1_FC_O_SZ, bias=False)#(4*4, 2)
        self.lv1_fc5 = nn.Linear(CELL_HW, LV1_FC_O_SZ, bias=False)#(4*4, 2)
        
        #但是操作这些w层时 ,并不想一一指定  而是想写循环,所以借用以下列表来操作上面定义的那些w层
        self.lv1_fc = [self.lv1_fc1,self.lv1_fc2,self.lv1_fc3,self.lv1_fc4,self.lv1_fc5]#5个 (4*4, 2)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ziix

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值