Я новичок в 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.