Расширение класса PyTorch nn.Sequential - PullRequest
0 голосов
/ 18 июня 2020

Я новичок в OOP в Python и вообще ржавый. Я хотел бы расширить объект PyTorch 'nn.Sequential' таким образом, чтобы передача ему кортежа, содержащего номер узла в каждом слое, автоматически генерировала OrderedDict в соответствии с этими узлами. Для функционального примера:

layers = (784, 392, 196, 98, 10)
n_layers = len(layers)
modules = OrderedDict()

# Layer definitions for inner layers:
for i in range(n_layers - 2):
    modules[f'fc{i}']   = nn.Linear(layers[i], layers[i+1])
    modules[f'relu{i}'] = nn.ReLU()

# Definition for output layer:
modules['fc_out'] = nn.Linear(layers[-2], layers[-1])
modules['smax_out'] = nn.LogSoftmax(dim=1)

# Define model and check attributes:
model = nn.Sequential(modules)

Итак, вместо того, чтобы передавать объект 'OrderedDict' при инициализации nn.Sequential, я хочу, чтобы мой класс взял вместо этого кортеж.

class Network(nn.Sequential):
   def__init__(self, n_nodes):
      super().__init__()

      **** INSERT LOGIC FROM LAST SNIPPET ***

Итак похоже, что это не сработает, потому что когда мой класс Network вызывает super().__init__(), он захочет увидеть словарь активаций слоев. Как я могу go написать свою собственную сеть таким образом, чтобы она обошла эту проблему, но при этом сохранила все функции последовательного объекта PyTorche?

Я думал примерно так:

class Network(nn.Sequential):
    def __init__(self, layers):
        super().__init__(self.init_modules(layers))


    def init_modules(self, layers):
        n_layers = len(layers)
        modules = OrderedDict()

        # Layer definitions for inner layers:
        for i in range(n_layers - 2):
            modules[f'fc{i}']   = nn.Linear(layers[i], layers[i+1])
            modules[f'relu{i}'] = nn.ReLU()

        # Definition for output layer:
        modules['fc_out'] = nn.Linear(layers[-2], layers[-1])
        modules['smax_out'] = nn.LogSoftmax(dim=1)

        return modules

Я не уверен, разрешены ли подобные вещи и / или это хорошая практика в Python.

1 Ответ

1 голос
/ 18 июня 2020

Ваша реализация разрешена и хороша.

И вы также можете инициализировать super().__init__() vacant, а затем использовать self.add_module(key, module) в al oop, чтобы присоединить Linear или Relu или что-то еще . Таким образом, функция __init__ может покрывать работу init_modules.

...