O que é o gradiente descendente estocástico?

Autora

Anna Gutowska

AI Engineer, Developer Advocate

IBM

O que é o gradiente descendente estocástico?

O gradiente descendente estocástico (SGD) é um algoritmo de otimização comumente usado para melhorar o desempenho de modelos de aprendizado de máquina. É uma variante do algoritmo tradicional de gradiente descendente, com uma modificação importante: em vez de depender de todo o conjunto de dados para calcular o gradiente em cada etapa, o SGD usa uma única amostra de dados de cada vez.

Gradiente descendente

O gradiente descendente (GD) é um algoritmo de otimização que minimiza iterativamente uma função objetiva. No contexto do aprendizado de máquina (ML), o gradiente descendente é fundamental para melhorar o desempenho de modelos de aprendizado supervisionado durante sua fase de treinamento. Os modelos de aprendizado de máquina, como as redes neurais, são complexos, não lineares e de alta dimensão. Portanto, não há uma equação normal para esses modelos que possa calcular os pesos ideais, ao contrário da regressão linear. Em vez disso, podem ser usados métodos de aproximação como as variantes do gradiente descendente, métodos de Newton e maximização de expectativas, entre outros.

Todo modelo tem uma função de perda, às vezes chamada de função de custo. Essa função mede o quanto as previsões de um modelo estão distantes dos pontos de dados verdadeiros. Pense nisso como uma medida do quanto as previsões do modelo estão "erradas". Por exemplo, o erro quadrático médio geralmente serve como função de perda em problemas de regressão. A fase de treinamento do modelo é projetada para encontrar os valores de parâmetros que minimizem essa perda. O gradiente descendente costuma ser a técnica de otimização usada no treinamento por esse motivo. O algoritmo calcula o gradiente, ou a inclinação, da perda em relação aos parâmetros do modelo. Com esse gradiente, dá um passo na direção oposta para reduzir a perda. A taxa de aprendizado (também chamada de tamanho da etapa ou alfa) é o tamanho das etapas e permanece fixa para todos os parâmetros do modelo. Esse processo se repete até que o modelo atinja a convergência perto de um mínimo.

Representação gráfica da convergência Representação gráfica da convergência

Idealmente, a convergência ocorre no mínimo global. Na visualização a seguir, é possível ver que o valor de perda é menor em um mínimo local do que na área circundante imediata, mas não necessariamente o valor mais baixo geral. O mínimo global é o valor absoluto mais baixo da função de perda em todo o seu domínio, representando a melhor solução possível para o problema.

Mínimo local e global no espaço tridimensional Mínimo local e global no espaço tridimensional

Se a taxa de aprendizado não for pequena o suficiente, o algoritmo geralmente convergirá para um mínimo local. Uma taxa bem escolhida é essencial para minimizar a função de perda e alcançar a convergência em um mínimo global.

Efeito da taxa de aprendizado na convergência Efeito da taxa de aprendizado na convergência

Essa visualização descreve o efeito da taxa de aprendizado na convergência. Uma pequena taxa de aprendizado leva a uma convergência lenta, mas estável (à esquerda), enquanto uma grande taxa de aprendizado pode causar excesso de aprendizado e instabilidade (à direita).

Do GD para o SGD

O principal diferenciador entre o gradiente descendente tradicional e o gradiente descendente estocástico é que o SGD atualiza os pesos do modelo usando um único exemplo de treinamento de cada vez. O exemplo é escolhido aleatoriamente em cada iteração.1 O gradiente descendente usa todo o conjunto de dados de treinamento para calcular o gradiente antes de cada atualização de parâmetros. Essa diferença no uso de dados é o que torna o SGD muito menos computacionalmente caro e mais fácil de escalar para grandes conjuntos de dados. Alternativamente, o comportamento de convergência do SGD é mais ruidoso do que o ruído do GD porque o ponto de dados de um exemplo pode não ser uma boa representação do conjunto de dados. Essa deturpação atualiza os pontos em uma direção ligeiramente "errada". No entanto, essa aleatoriedade é o que torna o SGD mais rápido e, às vezes, melhor para problemas de otimização não convexa, pois ele pode escapar de mínimos locais rasos, ou pontos de sela.

Estritamente falando, o SGD foi originalmente definido para atualizar parâmetros usando exatamente uma amostra de treinamento de cada vez. No uso moderno, o termo "SGD" é usado livremente para significar "minibatch gradiente descendente", uma variante do GD em que pequenos lotes de dados de treinamento são usados de cada vez. A principal vantagem de usar subconjuntos de dados em vez de uma amostra singular é um nível de ruído mais baixo, porque o gradiente é igual à média das perdas do minibatch. Por esse motivo, o gradiente descendente do minibatch é o padrão no deep learning. Ao contrário, o SGD rigoroso raramente é usado na prática. Esses termos são confundidos até pela maioria das bibliotecas de aprendizado de máquina, como PyTorch e TensorFlow; os otimizadores são frequentemente chamados de "SGD", embora normalmente usem minilotes.

A ilustração a seguir fornece uma descrição mais clara de como o aumento do tamanho da amostra de dados de treinamento reduz as oscilações e o "ruído".

Variantes do gradiente descendente

Existem várias outras variantes do GD baseadas em gradiente descendente básico, adicionando mecanismos para melhorar a velocidade, a estabilidade e a convergência.

Métodos baseados em impulso:

Ao acumular impulso em dimensões com gradientes consistentes e atenuar as atualizações em dimensões com mudanças nos gradientes, o momento ajuda o SGD a convergir mais rapidamente e com menos oscilação.2

SGD com e sem impulso
  • Gradiente descendente de impulso: incorpora um termo de "velocidade", uma média de gradientes anteriores que dá mais importância aos recentes. Essa abordagem reduz o ziguezague ou oscilações, ajudando o algoritmo a migrar mais rápido na direção certa.

  • NAG (gradiente acelerado de Nesterov): um método de impulso aprimorado que acelera e suaviza a convergência "olhando para a frente", para onde os parâmetros estão indo antes de calcular o gradiente. Em outras palavras, ele antecipa o gradiente futuro e usa essas informações para informar a etapa de atualização atual.3

Métodos de taxa de aprendizado adaptativo:

Métodos de taxa de aprendizado adaptativo, como AdaGrad e RMSProp, são únicos, pois adaptam a taxa de aprendizado para cada parâmetro individualmente. Essa abordagem contrasta com os métodos SGD, que usam uma taxa de aprendizado fixa para todos os parâmetros.

  • AdaGrad (adaptive gradient algorithm): adapta a taxa de aprendizado de cada parâmetro com base em seus gradientes anteriores. As funcionalidades que aparecem com menos frequência recebem taxas de aprendizado mais altas, e as funcionalidades frequentes recebem taxas mais baixas. Essa abordagem significa que funcionalidades infrequentes são aprendidas mais rapidamente do que com SGD. Essa taxa de aprendizado adaptativo significa que é um ótimo método para processamento de linguagem natural (NLP) e sistemas de recomendação com dados esparsos, nos quais há uma grande discrepância na frequência de funcionalidades.2
     

  • RMSProp (Root Mean Square Propagation): outra técnica de otimização de taxa de aprendizado adaptativo que dimensiona a taxa de aprendizado para cada parâmetro usando uma média móvel de gradientes quadrados recentes. O conhecimento anterior do gradiente é descartado e somente o conhecimento atual do gradiente é preservado.4 A taxa de aprendizado se torna maior para parâmetros com pequenos gradientes e menor para aqueles com grandes gradientes. Esse método elimina o problema da taxa de aprendizado de diminuição com o AdaGrad. O RMSProp ajuda a manter o treinamento estável em deep learning, especialmente para modelos como redes neurais recorrentes (RNNs), e funciona bem em problemas em que o objetivo continua mudando, como no aprendizado por reforço.

Métodos híbridos:

  • Adam (adaptive moment estimation): combina GD baseado em impulso com RMSProp, rastreando tanto os gradientes anteriores quanto a média dos gradientes quadrados.Essa combinação permite uma rápida taxa de convergência, mesmo para conjuntos de dados ruidosos e esparsos.3 Além disso, os hiperparâmetros padrão, como uma taxa de aprendizado de 0,001 em muitos frameworks, funcionam bem imediatamente. No entanto, para conjuntos de dados de grande escala, o SGD com impulso pode levar a uma melhor generalização. Os ajustes agressivos por parâmetros de Adam podem resultar em overfitting dos dados de treinamento ou na definição de mínimos acentuados, que também não generalizam bem.

O SGD e outras variantes do GD são úteis quando o tempo de treinamento é o gargalo.5

VarianteDados usados por etapaCaracterística principalUso comum
GDTodos os dadosEstável, mas lentoPequenos conjuntos de dados
SGDUma amostra para SGD clássicoBarulhento, mas rápidoAprendizado online
GD em minilotesPoucas amostrasEquilibrado e escalávelDeep learning
MomentoLote/miniloteAcelera na direção certaRedes neurais
NAGLote/miniloteImpulso de antecipaçãoConvergência mais rápida
AdaGradMiniloteTaxas de aprendizado adaptativoDados esparsos
RMSPropMiniloteCorrige o decaimento do AdaGradRNNs, redes profundas
AdamMiniloteImpulso + RMSPropOpção padrão hoje

Entenda a matemática

O objetivo do SGD é encontrar parâmetros θ que tornam as previsões do nosso modelo o mais próximo possível dos valores reais y . Ou seja, queremos minimizar a função de perda, L(θ) .

No caso da regressão linear, esses parâmetros são w (peso) e b (viés). Portanto, nesse caso, minimizar L(θ) é o mesmo que minimizar  L(w,b) .

 yi^=w·xi+b

L(w,b)=1ni=1n(yi-yi^)2

Uma analogia comumente usada ao ensinar o gradiente descendente é que o GD é como caminhar descendo uma montanha até chegar a um vale (a perda mínima). Visualize o gradiente da função de perda, L , aponta para cima e, para descer, devemos caminhar na direção oposta.

A regra geral de atualização para um parâmetro θ  é:

θ:=θ-η·θL(θ)

onde η é a taxa de aprendizado, e θL(θ) é o gradiente da perda em relação a θ .

O SGD usa apenas uma amostra escolhida aleatoriamente (xi,yi) para aproximar o gradiente:

θL(θ)θ(xi,yi;θ)

Observe que letras minúsculas (xi,yi;θ) representam a perda de um único exemplo de treinamento. Enquanto isso, letras maiúsculas L(θ) são a função de perda geral (a média de todas as perdas individuais em todo o conjunto de dados). Esse erro global é o que estamos tentando minimizar no treinamento.

Exemplo: regressão linear com SGD

Vamos terminar de analisar o exemplo de regressão linear com o SGD.

Para uma amostra (xi,yi) , a previsão é:

 yi^=w·xi+b

A perda local é o erro ao quadrado para uma amostra:

 (xi,yi;w,b)=(yi-(wxi+b))2

Agora, durante a retropropagação, os parâmetros do modelo são atualizados usando a regra da cadeia que calcula os gradientes da função de perda em relação a cada parâmetro.5 Os gradientes (derivadas) são:

 w=-2xi(yi-(wxi+b))

 b=-2(yi-(wxi+b))

Com o SGD, atualizamos cada um desses parâmetros, w e b , usando as seguintes regras:

 w:=w-η·(-2xi(yi-(wxi+b)))

 b:=b-η·(-2(yi-(wxi+b)))

Em vez de calcular um gradiente médio pesado em todo o conjunto de dados, o SGD usa uma estimativa aleatória leve.

Implementação em Python simples do SGD

Quando trabalhar com frameworks de aprendizado de máquina, há classes integradas de otimizadores de SGD que podem ser usadas. Por exemplo, torch.optim.SGD  para PyTorch, tf.keras.optimizers.SGD  para Keras integrado ao TensorFlow, e SGDRegressor  para Scikit-learn.

Para fins de aprendizado, vamos percorrer uma implementação simples do Python do SGD a partir do zero.

Para reiterar, nosso objetivo é encontrar os melhores parâmetros (pesos do modelo) que minimizem a função de perda (uma medida do quanto nossas previsões estão erradas). Atualizaremos uma amostra de cada vez ou um tamanho de lote muito pequeno.

Para começar, podemos inicializar os valores (pesos) dos parâmetros aleatoriamente. Em seguida, podemos selecionar um ponto de dados aleatório (x,y) . A partir daí, calculamos a previsão e o erro. Para esta demonstração simples, vamos tentar encaixar uma linha simples: y=mx+b . A próxima etapa no processo é a retropropagação, na qual os gradientes da função de perda são calculados em relação aos parâmetros. Esses gradientes (derivadas) são então usados para atualizar os parâmetros durante o processo de otimização do SGD. Como o gradiente aponta para a direção de aumento da função de perda, o SGD subtrai cada gradiente de seu respectivo valor de parâmetro atual. Podemos pensar nisso como um movimento na direção oposta do gradiente para diminuir a função de perda. Portanto, a “descida” no gradiente descendente estocástico. Repetimos essas etapas até um número fixo de epochs ou quando a perda é menor do que a tolerância. Esta última significaria que a perda pouco mudaria e não estamos mais melhorando a função objetiva. Em outras palavras, paramos quando o algoritmo converge.

import numpy as np 
 
def stochastic_gradient_descent(X, y, lr=0.01, epochs=100, tol=1e-6): 
    “”” 
    Perform Stochastic Gradient Descent (SGD) to fit a line y = w*x + b 
     
    Parameters: 
        X (ndarray): Input features 
        y (ndarray): Target values 
        lr (float): Learning rate (step size for updates) 
        epochs (int): Number of iterations through the dataset 
     
    Returns: 
        w (float): Learned weight 
        b (float): Learned bias 
    “”” 
    # Initialize parameters randomly 
    w = np.random.randn() 
    b = np.random.randn() 
     
    n = len(X) 
 
    prev_loss = float(‘inf’) 
     
    for epoch in range(epochs): 
        # Shuffle the data for each epoch 
        indices = np.arange(n) 
        np.random.shuffle(indices) 
         
        for i in indices: 
            xi = X[i] 
            yi = y[i] 
             
            # Prediction 
            y_pred = w * xi + b 
             
            # Compute gradients (derivatives) 
            dw = -2 * xi * (yi - y_pred)   # derivative wrt w 
            db = -2 * (yi - y_pred)        # derivative wrt b 
             
            # Update parameters 
            w -= lr * dw 
            b -= lr * db 
         
        
        # Compute loss at the end of the epoch 
        loss = np.mean((y - (w*X + b))**2) 
         
        # Check stopping condition 
        if abs(prev_loss - loss) < tol: 
            print(f”Stopped early at epoch {epoch+1}”) 
            break 
                 
        prev_loss = loss 
             
    return w, b

Aplicações do SGD

O SGD é o método de otimização mais comum para treinar rede neurais. No deep learning, um subconjunto do aprendizado de máquina dentro do campo mais amplo da ciência de dados, o objetivo é que os computadores simulem o complexo poder de tomada de decisão do cérebro humano. Modelos tradicionais de ML usam redes neurais simples que consistem em uma ou duas camadas. Já os modelos de deep learning usam três ou mais camadas. Normalmente, centenas ou milhares de camadas são necessárias para treinar os modelos. Dada a facilidade de escalonamento do SGD para grandes conjuntos de treinamento, ele geralmente é a abordagem ideal para treinar rede neurais. Outras aplicações do treinamento do SGD incluem regressão ridgeregressão logística regularizada e a otimização da função de perda de articulação usada em máquinas de vetores de suporte (SVMs) com um kernel linear.

Conclusão

O SGD é uma variante do GD que minimiza a função de perda de um modelo de aprendizado de máquina usando uma única amostra de dados de cada vez. Essa abordagem é diferente do GD, que depende de todo o conjunto de dados em cada etapa para calcular o gradiente. Existem várias outras variantes de GD que podem ser agrupadas como métodos de aprendizado baseados em impulso ou adaptativos. O gradiente descendente de impulso e o gradiente acelerado de Nesterov são exemplos do primeiro. Esses métodos aproveitam o impulso acumulado em dimensões com gradientes consistentes e atenuam as atualizações em dimensões com gradientes de mudança. Assim, ajudando o SGD a convergir mais rapidamente e com menos oscilação. Métodos de taxa de aprendizado adaptativo, como AdaGrad e RMSProp, adaptam a taxa de aprendizado para cada parâmetro individualmente, ao contrário do SGD tradicional, que usa uma taxa de aprendizado fixa. Além disso, métodos híbridos como o de Adam oferecem uma alternativa poderosa, combinando os pontos fortes do GD baseado em impulso e do RMSProp.

Soluções relacionadas
IBM watsonx.ai

Treine, valide, ajuste e implemente recursos de IA generativa, modelos de base e recursos de aprendizado de máquina com o IBM watsonx.ai, um estúdio empresarial de última geração para construtores de IA. Crie aplicações de IA em uma fração do tempo com uma fração dos dados.

Conheça o watsonx.ai
Soluções de inteligência artificial

Use a IA a serviço de sua empresa com a experiência e o portfólio de soluções líder do setor da IBM à sua disposição.

Explore as soluções de IA
Consultoria e serviços em IA

Reinvente os fluxos de trabalho e operações críticos adicionando IA para maximizar experiências, tomadas de decisão em tempo real e valor de negócios.

Explore os serviços de IA
Dê o próximo passo

Obtenha acesso completo aos recursos que abrangem o ciclo de vida do desenvolvimento da IA. Produza soluções poderosas de IA com interfaces fáceis de usar, fluxos de trabalhos e acesso a APIs e SDKs padrão do setor.

Explore o watsonx.ai Agende uma demonstração em tempo real
Notas de rodapé

Bottou, L. (2010). Large-Scale Machine Learning with Stochastic Gradient DescentLechevallier, Y., Saporta, G. (eds) Proceedings of COMPSTAT’2010. Physica-Verlag HD. 

Ruder, S. (2016). An overview of gradient descent optimization algorithms

Tian, Y., Zhang, Y. e Zhang, H. (2023). Recent Advances in Stochastic Gradient Descent in Deep LearningMathematics, 11(3), 682. 

Haji, S. H., & Abdulazeez, A. M. (2021). Comparison of optimization techniques based on gradient descent algorithm: A review. PalArch’s Journal of Archaeology of Egypt/Egyptology, 18(4), 2715-2743.

Bottou, L. (2012). Stochastic Gradient Descent TricksMontavon, G., Orr, G.B., Müller, KR. (eds) Neural Networks: Tricks of the Trade. Lecture Notes in Computer Science, vol 7700. Springer, Berlin, Heidelberg.