• 终于搞懂了 super(XXXX, self).__init__()的作用是啥了


    在使用pytorch框架时,难免要自己定义网络。于是,super(XXXX, self).init(),就成了自定义网络结构时必不可少的第一句。但是,super(XXXX, self).init()具体的作用是什么我一直没有搞清楚。阅读了大量的博客后,我终于搞懂了!
    一言以蔽之:super(XXX, self).init()——对继承自父类的属性进行初始化,并且用父类的初始化方法初始化继承的属性。
    我们先看一个简单的例子:

    class Person():
        def __init__(self, name, gender):
        	# 为name和gender赋值 
            self.name = name
            self.gender = gender
            
        def printinfo(self):
        
            print(self.name, self.gender)
    
    
    # Stu类继承Person类        
    
    class Stu(Person):
        def __init__(self, name, gender, school):
        
            # 使用父类的初始化方法来初始化子类name和gender属性
            super(Stu, self).__init__(name, gender)  
            
            self.school = school
            
        def printinfo(self):   
        	# 对父类的printinfo方法进行重写
           
            print(self.name, self.gender, self.school) 
    
    
        
    if __name__=='__main__':
        stu = Stu('Bob', 'female', '5th')
        stu.printinfo()
    
    >>>
    Bob female 5th
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    当然,如果初始化的逻辑与父类的不同,不使用父类的方法,自己重新初始化也是可以的。比如:

    class Person(object):
        def __init__(self, name, gender, age):
            self.name = name
            self.gender = gender
            self.age = age
            
    # Student类继承Person类
    class Student(Person):
        def __init__(self, name, gender, age, school, score):
        
        	# 调用父类的初始化方法,初始化name、gender、age属性
            super(Student, self).__init__(name,gender, age)
            
            # 对name、gender属性进行改写。age属性仍保持父类的初始化方法
            
            self.name = name.upper()  # 姓名改为大写
            self.gender = gender.upper()  # 性别改为大写
            self.school = school
            self.score = score
            
    s = Student("Alice", "female", "18", "High school", "17")
    print(s.name, s.gender, s.school, s.score)
    
    >>>
    ALICE FEMALE High school 17
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    在理解了上面的小例子后,我们再仔细研究一下机器学习中的代码:

    class Net(nn.Module): # 继承自nn.Moudle
    
        def __init__(self):
        
            super(Net, self).__init__()
            # 输入图像channel:1;输出channel:6;5x5卷积核
            self.conv1 = nn.Conv2d(1, 6, 5)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    super(Net, self).init()的含义:子类Net类继承父类nn.Module,super(Net, self).init()就是对继承自父类nn.Module的属性进行初始化。并且是用nn.Module的初始化方法来初始化继承的属性。


    也就是:用父类的方法初始化子类的属性。

    有的人肯定会问,为啥要用父类的方法去初始化属性呢?原因很简单:就是因为父类的方法已经写好了,我们只需要调用就可以了。难道你还想自己写一堆代码去初始化各种权重和参数,处理一堆forward和backward的逻辑吗?


    最后,多一句嘴,介绍一写在python中__init()的作用
    在python中创建类后,通常会创建一个
    init__ ()方法,这个方法会在创建类的实例的时候自动执行

    实例1:【实例化Bob这个对象的时候, __ init__ ()方法会自动执行】:
    在下面的示例中,我们在实例化Bob这个对象的时候, __ init__ ()方法就已经自动执行了,如果不是__ init__ ()方法,比如说eat()方法,那就只有在调用时才会执行。

    class Person():
        def __init__(self):
            print("是一个人")
        def eat(self):
            print("要吃饭")
            
    Bob = Person()
    
    >>>
    是一个人
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    【实例2】哪些需放入__ init__ ()方法中,哪些不需要???

    需要在 __ init__ ()方法中定义:希望有一些操作是在创建实例的时候就自动创建的。在神经网络代码中,一些网络结构的设置,也最好放在 __ init__ ()方法中。

    在下述代码中,我们把money这个属性也定义在__ init__ ()方法中,这样就不需要在执行eat()方法后再执行qian()方法。

    class Person():
        def __init__(self, name,money):
            print("是一个人")
            self.name = name
            self.money = money
    
        def eat(self):
            print("%s要吃饭" % self.name)
    
        def qian(self):
            print("花了%s元" % self.money)
    
    
    Bob = Person("Bob",12)
    Bob.eat()
    Bob.qian()
    
    >>>
    是一个人
    Bob要吃饭
    花了12
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
  • 相关阅读:
    Nginx 禁止国外 IP 访问网站
    Java基础(六)
    康耐视读码器DataMan软件详细使用步骤
    软件测试面试之问——角色扮演
    香港的Web3从业者们 出走新加坡还是选择留下?
    多线程系列(十九) -Future使用详解
    金融大模型的下一步是什么?奇富科技费浩峻:大模型需要向小模型学习
    使用小程序制作一个飞机大战小游戏
    领域驱动模型DDD(一)——服务拆分策略
    鸿蒙Harmony应用开发—ArkTS声明式开发(鼠标事件)
  • 原文地址:https://blog.csdn.net/weixin_44025103/article/details/126143715