Как перевести нейронную сеть MLP с tenorflow на pytorch

Я создал нейронную сеть MLP, используя Tensorflow, о котором говорится ниже:

model_mlp=Sequential()
model_mlp.add(Dense(units=35, input_dim=train_X.shape[1], kernel_initializer='normal', activation='relu'))
model_mlp.add(Dense(units=86, kernel_initializer='normal', activation='relu'))
model_mlp.add(Dense(units=86, kernel_initializer='normal', activation='relu'))
model_mlp.add(Dense(units=10, kernel_initializer='normal', activation='relu'))
model_mlp.add(Dense(units=1))

Я хочу преобразовать приведенный выше код MLP с помощью pytorch. Как это сделать? Я стараюсь делать это следующим образом:

    class MLP(nn.Module):
    def __init__(self):
        super(MLP, self).__init__()
        self.fc1 = nn.Linear(train_X.shape[1],35)
        self.fc2 = nn.Linear(35, 86)
        self.fc3 = nn.Linear(86, 86)
        self.fc4 = nn.Linear(86, 10)
        self.fc5 = nn.Linear(10, 1)
    def forward(self, x):
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = F.relu(self.fc3(x))
        x = F.relu(self.fc4(x))
        x = self.fc5(x)
        return x
    def predict(self, x_test):
        x_test = torch.from_numpy(x_test).float()
        x_test = self.forward(x_test)
        return x_test.view(-1).data.numpy()
model = MLP()

Я использую один и тот же набор данных, но два кода дают два разных ответа. Код, написанный на Tensorflow, всегда дает гораздо лучшие результаты, чем код, написанный на Pytorch. Интересно, неправильный ли мой код в pytorch. Если мой написанный код в PyTorch верен, мне интересно, как объяснить различия. Я с нетерпением жду ответов.


person will_cheuk    schedule 28.07.2020    source источник


Ответы (1)


Добро пожаловать в pytorch!

Думаю, проблема в инициализации вашей сети. Вот как бы я это сделал:

def init_weights(m):
    if type(m) == nn.Linear:
        torch.nn.init.xavier_normal(m.weight)  # initialize with xaver normal (called gorot in tensorflow)
        m.bias.data.fill_(0.01) # initialize bias with a constant

class MLP(nn.Module):
    def __init__(self, input_dim):
        super(MLP, self).__init__()
        self.mlp = nn.Sequential(nn.Linear(input_dim ,35), nn.ReLU(),
                                 nn.Linear(35, 86), nn.ReLU(),
                                 nn.Linear(86, 86), nn.ReLU(), 
                                 nn.Linear(86, 10), nn.ReLU(),
                                 nn.Linear(10, 1), nn.ReLU())

    def forward(self, x):
        y =self.mlp(x)
        return y

model = MLP(input_dim)
model.apply(init_weights)

optimizer = Adam(model.parameters())
loss_func = BCEWithLogistLoss()

# training loop

for data, label in dataloader:
    optimizer.zero_grad()
    
    pred = model(data)
    loss = loss_func(pred, lable)
    loss.backward()
    optimizer.step()
    

Обратите внимание, что в pytorch мы вызываем не model.forward(x), а model(x). Это потому, что nn.Module применяет хуки в .__call__(), которые используются в обратном проходе.

Вы можете проверить документацию по инициализации веса здесь: https://pytorch.org/docs/stable/nn.init.html

person Victor Zuanazzi    schedule 28.07.2020