Pytorch Basics - Regressão Linear
Tutorial de como realizar um modelo de regressão linear no Pytorch.
O objetivo desse breve trabalho é apresentar como é realizado um modelo de regressão linear utilizando pytorch. Muitas das vezes utiliza-se regressão linear como uma primeira hipotese, devido a sua simplicidade, antes de partir para modelos mais complexos.
#Carregando o Pytorch
import torch
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
Para carregar o bando de dados que está em .csv, utilizamos o pandas, o qual consegue ler um arquivo localmente ou em um nuvem (url deve ser do raw do .csv)
df = pd.read_csv('https://raw.githubusercontent.com/lucastiagooliveira/lucas_repo/master/Kaggle/Revisiting%20a%20Concrete%20Strength%20regression/datasets_31874_41246_Concrete_Data_Yeh.csv')
Mostrando as 5 primeiras linhas do dataframe carregado, isso é importante para verificarmos o se o dataframe está correto.
df.head()
Apresentando um resumo estatístico dos dataframe por coluna, tais como: quantidade de dados, média, desvio padrão, mínimo, primeiro ao terceiro quartil e valor máximo.
df.describe()
Para visualização da relação entre as váriaveis é interessante fazer a visualização gráfica da relação entre as variáveis. Para isso usamos a função PairGrid da biblioteca Seaborn aliado com um scatterplot da biblioteca MatplotLib.
sns.set(style="darkgrid")
g = sns.PairGrid(df)
g.map(plt.scatter)
Para entendimento da correlação linear das variáveis entre si, temos a função "built-in" do Pandas que nos retorna o coeficiente de correlação que tem por padrão o método Pearson.
df.corr()
Escolhendo as variáveis que serão utilizadas para criação do modelo.
var_used = ['cement', 'superplasticizer', 'age', 'water']
train = df[var_used]
target = df['csMPa']
Tabela com somente as variáveis que serão utilizadas.
train.head()
Para iniciarmos um modelo temos que fazer a transformação da base de dados que está com o tipo de DataFrame para tensor, que é utilizado pelo Pytorch. Todavia, uma das maneiras de fazer essa transformação é antes fazer a transformação da base de dados para um vetor do Numpy e depois transformar para um tensor do Pytorch.
Obs.: Foi criado o vetor de uns para ser adicionado ao tensor dos parâmetros, pois essa coluna deverá multiplicar a constante da expressão (b), conforme o exemplo abaixo.
Y = a*X + b
train = np.asarray(train)
a = np.ones((train.shape[0],1))
train = torch.tensor(np.concatenate((train, a), axis=1))
target = torch.tensor(np.asarray(target))
train.shape
Para iniciarmos precisamos criar uma função a qual definirá a equação da regressão linear a qual utilizará a função matmul para realizar a multiplicação entre os dois tensores dos parâmetros e variáveis dependentes.
def model(x,params):
return torch.matmul(x, params)
Função que calcula o erro quadrático médio (MSE).
Para saber mais sobre como é calculado acesso o link: https://pt.qwe.wiki/wiki/Mean_squared_error
def mse(pred, labels): return ((pred - labels)**2).mean()
Para iniciar o treino do modelo primeiramente temos que criar um tensor o qual receberá os valores dos parâmetros que serão atualizados a cada iteração, quedo assim precisamos utilizar o método requiresgrad assim será possível calcular o gradiente desse tensor quando necessário.
Observe que o tipo do objeto criado é torch.float64.
params = torch.randn(5,1, dtype=torch.float64).requires_grad_()
params.dtype
Primeiro passo: realizar as predições do modelo
pred = model(train, params)
Segundo passo: calcular como o nosso modelo performou, ou seja, calcular MSE para averiguação da performace do modelo.
Observe que o modelo vai apresentar um erro acentuado, pois os parâmetros ainda não foram treinados.
loss = mse(pred, target)
loss
Terceiro passo: realizar o gradiente descente.
Conceito do algoritmo de gradiente descendente: http://cursos.leg.ufpr.br/ML4all/apoio/Gradiente.html
loss.backward()
params.grad
Quarto passo: Atualização dos parâmetros, para isso utiliza-se o valor do gradiente por meio do algoritmo descendente e é escalado (multiplicado) pelo taxa de aprendizado (learning rate).
Após a realização da atulização dos parâmetros deve-se resetar o gradiente.
lr = 1e-5
params.data -= lr * params.grad.data
params.grad = None
Primeira iteração realizada, pode-se observar o valor do erro do nosso modelo reduziu. A tendência é ocorrer uma diminuição até a cada iteração, até a estabilização do modelo.
pred = model(train, params)
loss = mse(pred, target)
loss
Foi criada uma função que realiza todos os passos acima realizados.
def step(train, target, params, lr = 1e-6):
## realizando as predições
pred = model(train, params)
## caculando o erro
loss = mse(pred, target)
## realizando o gradiente descendente
loss.backward()
## atualizando os parâmtros
params.data -= lr * params.grad.data
## reset do gradiente
params.grad = None
## imprimindo na tela o erro
print('Loss:',loss.item())
## retornado as predições e os parâmetros atuzalizados na ultima iteração
return pred, params
Criando um loop para realizar as itereções, é possível verificar a diminuição do erro a cada iteração, ou seja, se realizada mais iteração pode-se chegar a um resultado plausível (neste caso não cheramos a um, pois o modelo de regressão linear não é um modelo adequado para esses dados, somente como hipótese inicial).
for i in range(10): loss, params = step(train, target, params)
Esté é o resultado dos parâmetros que serão utilizados para o modelo realizar futuras predições.
parameters = params
parameters #parametros do modelo