¿Qué representa la red neuronal super(XXX, self).__init__()?

En Li Mu: Aprendizaje profundo práctico Capítulo 9 Sección 7: Aprendizaje de secuencia a secuencia (Seq2Seq), existe el siguiente código:

#@save
class Seq2SeqEncoder(d2l.Encoder):
    """用于序列到序列学习的循环神经网络编码器"""
    def __init__(self, vocab_size, embed_size, num_hiddens, num_layers,
                 dropout=0, **kwargs):
        super(Seq2SeqEncoder, self).__init__(**kwargs)
        # 嵌入层
        self.embedding = nn.Embedding(vocab_size, embed_size)
        self.rnn = nn.GRU(embed_size, num_hiddens, num_layers,
                          dropout=dropout)

    def forward(self, X, *args):
        # 输出'X'的形状:(batch_size,num_steps,embed_size)
        X = self.embedding(X)
        # 在循环神经网络模型中,第一个轴对应于时间步
        X = X.permute(1, 0, 2)
        # 如果未提及状态,则默认为0
        output, state = self.rnn(X)
        # output的形状:(num_steps,batch_size,num_hiddens)
        # state的形状:(num_layers,batch_size,num_hiddens)
        return output, state

En la clase Seq2SeqEncoder, aparece super(Seq2SeqEncoder, self).__init__(**kwargs). Estoy un poco confundido acerca de para qué son las siguientes tres líneas de código. Para comprender estas tres líneas de código, debe comprender tres cosas :

  • parámetro propio
  • método __init__()
  • super(Neto, propio).init()

A continuación, te explicaré uno por uno.

1. El autoparámetro

self se refiere a la instancia de la instancia en sí, en la clase de Python se estipula que el primer parámetro de la función es el objeto de la instancia en sí, y se acostumbra escribir su nombre como self, es decir, el primer parámetro del método en la clase debe ser uno mismo y no se puede omitir.
Creo que hay tres puntos importantes sobre uno mismo:

  • self se refiere a la instancia en sí, no a la clase
  • self puede ser reemplazado por esto, pero no escribas así
  • El yo en el método de la clase no se puede omitir.

(1) self se refiere a la instancia en sí, no a la clase:

class Person():
    def eat(self):
        print(self)

Bob=Person() # 创建Person类的实例Bob
Bob.eat() # 调用eat
print(Person)

producción:

<__main__.Person object at 0x000002C383FBDA88> # Person类的实例Bob
<class '__main__.Person'> # Person是一个类

(2) self puede ser reemplazado por esto, pero generalmente no se escribe así:

class Person():
    def eat(this):
        print(this)

Bob=Person()
Bob.eat()
print(Person)

producción:

<__main__.Person object at 0x00000240E4C83908>
<class '__main__.Person'>

(3) No se puede omitir el self en el método de clase, el aviso en Pycharm:

 Dos, método __init__ ()

Después de crear una clase en python, generalmente se crea un método __init__(), que se ejecuta automáticamente cuando se crea una instancia de la clase. El método __init__() debe contener un parámetro propio y debe ser el primer parámetro.

Por ejemplo, en el código del siguiente ejemplo, cuando se crea una instancia del objeto Bob, el método __init__ () se ha ejecutado automáticamente, pero si no es el método __init__ (), como el método eat (), entonces debe sólo puede llamarse implemento.

class Person():
    def __init__(self):
        print("是一个人")
    def eat(self):
        print("要吃饭" )
Bob=Person()

La salida llama automáticamente a la función de impresión en init:

是一个人

A continuación, agregamos otros parámetros en el método __init__, como pasar el nombre:

class Person():
    def __init__(self,name):
        print("是一个人")
        self.name=name
    def eat(self):
        print("%s要吃饭" %self.name)

Bob=Person('Bob')
Bob.eat()

producción:

是一个人
Bob要吃饭

Nota: Después de proporcionar el nombre del parámetro en el método __init__, se debe especificar el nombre al crear una instancia de la clase; de ​​lo contrario, se informará un error.

Bob=Person()
Bob.eat()

Dado que el método __init__ se puede llamar automáticamente, en realidad sabemos más claramente lo que se debe definir en el método __init__(), es decir, esperamos que algunas operaciones estén disponibles cuando se cree la instancia. Por ejemplo, el siguiente código debería definir la cantidad de dinero en el método __init__(), de modo que no sea necesario ejecutar el método qian() después de ejecutar el método eat(). O cuando escribimos el código de la red neuronal, es mejor poner algunas configuraciones de estructura de red en el método \__init__().

class Person():
    def __init__(self,name):
        print("是一个人")
        self.name=name
    def eat(self,money):
        print("%s要吃饭" %self.name)
        self.money=money
    def qian(self):
        print("花了%s元" %self.money)

Bob=Person('Bob')
Bob.eat(12)
Bob.qian()

Tres, super(Net, self).__init__()

super(Net, self).__init__() en Python se refiere a encontrar primero la clase principal de Net (por ejemplo, la clase NNet), luego convertir el objeto propio de la clase Net en un objeto de la clase NNet y luego la clase "convertida". NNet El objeto llama a su propia función init. De hecho, la comprensión simple es que la subclase coloca el __init__() de la clase principal en su propio __init__(), de modo que la subclase tiene el __init__() de la clase principal.

Mirando hacia atrás en nuestro código principal, la clase Seq2SeqEncoder hereda d2l.Encoder, super(Net, self).__init__() es para inicializar las propiedades heredadas de la clase principal d2l.Encoder. Y el método de inicialización de d2l.Encoder se usa para inicializar las propiedades heredadas. Es decir, la subclase hereda todas las propiedades y métodos de la clase principal, y las propiedades de la clase principal se inicializarán naturalmente con los métodos de la clase principal.

Déjame darte un ejemplo para ayudarte a entender:

class Person:
    def __init__(self,name,gender):
        self.name = name
        self.gender = gender
    def printinfo(self):
        print(self.name,self.gender)

class Stu(Person):
    def __init__(self,name,gender,school):
        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('djk','man','nwnu')
    stu.printinfo()

Por supuesto, si la lógica de inicialización es diferente a la de la clase principal, también es posible reinicializar por sí mismo sin utilizar el método de la clase principal. Por ejemplo:

class Person(object):
    def __init__(self,name,gender,age):
        self.name = name
        self.gender = gender
        self.age = age
 
class Student(Person):
    def __init__(self,name,gender,age,school,score):
        #super(Student,self).__init__(name,gender,age)
        self.name = name.upper()  
        self.gender = gender.upper()
        self.school = school
        self.score = score
 
s = Student('Alice','female',18,'Middle school',87)
print s.school
print s.name

Supongo que te gusta

Origin blog.csdn.net/qq_54708219/article/details/129323207
Recomendado
Clasificación