что такое pytorch-эквивалент линейной регрессии tensorflow?

#python #tensorflow #machine-learning #pytorch #regression

#python #tensorflow #машинное обучение #pytorch #регрессия

Вопрос:

Я изучаю pytorch, чтобы сделать базовую линейную регрессию по этим данным, созданным таким образом здесь:

 from sklearn.datasets import make_regression

x, y = make_regression(n_samples=100, n_features=1, noise=15, random_state=42)
y = y.reshape(-1, 1)
print(x.shape, y.shape)

plt.scatter(x, y)
  

Я знаю, что с помощью tensorflow этот код может решить:

 model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Dense(units=1, activation='linear', input_shape=(x.shape[1], )))

model.compile(optimizer=tf.keras.optimizers.SGD(lr=0.05), loss='mse')

hist = model.fit(x, y, epochs=15, verbose=0)
  

но мне нужно знать, каким будет эквивалент pytorch, я пытался сделать это:

 # Model Class
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.linear = nn.Linear(1,1)
        
    def forward(self, x):
        x = self.linear(x)
        return x
    
    def predict(self, x):
        return self.forward(x)
    
model = Net()

loss_fn = F.mse_loss
opt = torch.optim.SGD(modelo.parameters(), lr=0.05)

# Funcao para treinar
def fit(num_epochs, model, loss_fn, opt, train_dl):
    
    
    # Repeat for given number of epochs
    for epoch in range(num_epochs):
        
        # Train with batches of data
        for xb, yb in train_dl:
            
            # 1. Generate predictions
            pred = model(xb)
            
            # 2. Calculate Loss
            loss = loss_fn(pred, yb)
            
            # 3. Campute gradients
            loss.backward()
            
            # 4. Update parameters using gradients
            opt.step()
            
            # 5. Reset the gradients to zero
            opt.zero_grad()
            
        # Print the progress
        if (epoch 1) % 10 == 0:
            print('Epoch [{}/{}], Loss: {:.4f}'.format(epoch 1, num_epochs, loss.item()))

# Training
fit(200, model, loss_fn, opt, data_loader)
  

Но модель ничему не учится, я больше не знаю, что я могу сделать.

Размеры ввода / вывода равны (1/1)

Ответ №1:

Набор данных

Прежде всего, вы должны определить torch.utils.data.Dataset

 import torch
from sklearn.datasets import make_regression


class RegressionDataset(torch.utils.data.Dataset):
    def __init__(self):
        data = make_regression(n_samples=100, n_features=1, noise=0.1, random_state=42)
        self.x = torch.from_numpy(data[0]).float()
        self.y = torch.from_numpy(data[1]).float()

    def __len__(self):
        return len(self.x)

    def __getitem__(self, index):
        return self.x[index], self.y[index]
  

Он преобразует numpy данные в tensor внутри __init__ PyTorch и преобразует данные в float ( numpy имеет double по умолчанию, в то время как PyTorch по умолчанию float , чтобы использовать меньше памяти).

Кроме того, он просто вернет tuple функции и соответствующие цели регрессии.

Подходит

Почти получилось, но вам нужно сгладить вывод из модели (описано ниже). torch.nn.Linear вернет тензоры формы (batch, 1) , пока ваши цели имеют форму (batch,) . flatten() удалит ненужное 1 измерение.

 # 2. Calculate Loss
loss = criterion(pred.flatten(), yb)
  

Модель

Это все, что вам нужно на самом деле:

 model = torch.nn.Linear(1, 1)
  

Любой уровень может быть вызван напрямую, нет необходимости в forward и наследовании для простых моделей.

Вызов

Остальное почти в порядке, вам просто нужно создать torch.utils.data.DataLoader и передать экземпляр нашего набора данных. Что DataLoader делает, это выдает __getitem__ dataset несколько раз и создает пакет указанного размера (есть и другие забавные вещи, но это идея):

 dataset = RegressionDataset()
dataloader = torch.utils.data.DataLoader(dataset, batch_size=32)
model = torch.nn.Linear(1, 1)
criterion = torch.nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=3e-4)

fit(5000, model, criterion, optimizer, dataloader)
  

Также обратите внимание, что я использовал torch.nn.MSELoss() , поскольку мы передаем объект, в этом случае он выглядит лучше, чем функция.

Весь код

Чтобы упростить:

 import torch
from sklearn.datasets import make_regression


class RegressionDataset(torch.utils.data.Dataset):
    def __init__(self):
        data = make_regression(n_samples=100, n_features=1, noise=0.1, random_state=42)
        self.x = torch.from_numpy(data[0]).float()
        self.y = torch.from_numpy(data[1]).float()

    def __len__(self):
        return len(self.x)

    def __getitem__(self, index):
        return self.x[index], self.y[index]


# Funcao para treinar
def fit(num_epochs, model, criterion, optimizer, train_dl):
    # Repeat for given number of epochs
    for epoch in range(num_epochs):

        # Train with batches of data
        for xb, yb in train_dl:

            # 1. Generate predictions
            pred = model(xb)

            # 2. Calculate Loss
            loss = criterion(pred.flatten(), yb)

            # 3. Compute gradients
            loss.backward()

            # 4. Update parameters using gradients
            optimizer.step()

            # 5. Reset the gradients to zero
            optimizer.zero_grad()

        # Print the progress
        if (epoch   1) % 10 == 0:
            print(
                "Epoch [{}/{}], Loss: {:.4f}".format(epoch   1, num_epochs, loss.item())
            )


dataset = RegressionDataset()
dataloader = torch.utils.data.DataLoader(dataset, batch_size=32)
model = torch.nn.Linear(1, 1)
criterion = torch.nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=3e-4)

fit(5000, model, criterion, optimizer, dataloader)
  

Вы должны обойти 0.053 потерю или около того, варьировать noise или другие параметры для более сложной / легкой задачи регрессии.

Комментарии:

1. @manynothing Хотя благодарность естественна, здесь мы благодарим голосованием и принимаем ответ, который вы уже сделали (такие комментарии создают ненужный шум). Рад, что смог помочь, добро пожаловать в StackOverflow! 🙂