如何理解增量随机梯度算法及其在逻辑回归中的实现[更新]?

数据挖掘 机器学习 Python 算法 梯度下降
2021-09-17 17:15:05

我很难从哪里开始实现增量随机梯度下降算法及其在逻辑回归中的相应实现。我不太了解这个算法,并且很少有资源可以用清晰的解释和可能的演示代码来解释它。我对 ML 算法很陌生,我不知道哪种方法可以有效地解决这个问题。

特别是我正在研究的问题是实现hogWild!逻辑回归算法,它要求我按顺序对增量 SGD 算法进行编程。谁能给我一个大致的想法或可能的管道以在 python 中实现这一点?

逻辑损失函数和梯度

在此处输入图像描述

这是我的实现:

import numpy as np
import scipy as sp
import sklearn as sl
from scipy import special as ss
from  sklearn import datasets

X_train, y_train=datasets.load_svmlight_file('/path/to/train_dataset')
X_test,y_test=datasets.load_svmlight_file('/path/to/train_dataset.txt', 
                                          n_features=X_train.shape[1])

class ISGD:
def lossFunc(X,y,w):
    w.resize((w.shape[0],1))
    y.resize((y.shape[0],1))

    lossFnc=ss.log1p(1+np.nan_to_num(ss.expm1(-y* np.dot(X,w,))))
    rslt=np.float(lossFnc)
    return rslt

def gradFnc(X,y,w):
    w.resize((w.shape[0],1))
    y.resize((y.shape[0],1))

    gradF1=-y*np.nan_to_num(ss.expm1(-y))
    gradF2=gradF1/(1+np.nan_to_num(ss.expm1(-y*np.dot(X,w))))
    gradF3=gradF2.resize(gradF2.shape[0],)
    return gradF3

def _init_(self, learnRate=0.0001, num_iter=100, verbose=False):
    self.w=None
    self.learnRate=learnRate
    self.verbose=verbose
    self.num_iter=num_iter


def fitt(self, X,y):
    n,d=X.shape
    self.w=np.zeros(shape=(d,))

    for i in range(self.num_iter):
        print ("\n:", "Iteration:", i)

        grd=gradFnc(self.w, X,y)
        grd.resize((grd.shape[0],1))
        self.w=self.w-grd
        print "Loss:", lossFunc(self.w,X,y)

    return self

似乎我的上述实现有一些问题。谁能帮我纠正一下?另外,我不知道如何按顺序实现增量 SGD。我怎样才能做到这一点?任何的想法?

1个回答

梯度下降

梯度下降的思想是遍历一个函数 fLR(w) 并找到一组 a 值的局部最大值或最小值 w. 梯度下降是一个迭代过程。在每次迭代中,您将根据当前的一组值来评估函数。然后,您将对该函数对这些值求导,以查看每个值对函数斜率的贡献程度。然后,我们可以按比例更改这些值以向这个最佳点移动。

梯度下降方程描述为

w(k+1)=w(k)ρfLR(w)w(k)

在哪里ρ是学习率,通常很小。一个常数,它决定了我们想要改变我们正在优化的值的速度。

初始化值

有很多方法可以初始化这些值。我们可以将它们全部设置为零,也可以随机设置。

然后你可以在你的数据集中随机抽取一个实例xiyi并计算导数

fLR(w)w(k)=xi(yieyixiw1+eyixiw).

计算完之后,您可以将结果放入梯度下降方程并更新所有权重。

然后你继续经历这个过程,直到你的体重 w收敛到一个值,或满足某些其他条件。您可能希望使用一些迭代计数器来限制您的算法,以避免由不收敛的权重引起的无限循环。


梯度下降代码

这是一个使用梯度下降沿逻辑回归损失函数训练权重的示例。

import numpy as np

def update_weights(x_i, y_i, w):
   p = 0.8                  # The learning rate
   yhat = predict(x_i, w)   # The predicted target
   error = y_i - yhat       
   return w + p * (y_i - yhat) * x_i  # Update the weights

def predict(x_i, w):
   return 1/(1+np.exp(-1 * np.dot(w.T, x_i)))

def train_weights(x, y, verbose = 0):
   w = np.zeros((x.shape[1],))
   w_temp = np.zeros((x.shape[1],)) 

   epoch = 0
   while epoch <= 1000:
      for i, x_i in enumerate(x):
         w = update_weights(x_i, y[i], w)

      pred = 1/(1+np.exp(-1 * np.dot(x, w)))
      error = np.sum(pred - y)

      pred[pred < 0.5] = 0
      pred[pred >= 0.5] = 1
      epoch += 1

      if verbose == 1:
         print('------------------------------------------------')
         print('Targets: ', y)
         print('Predictions: ', pred)
         print('Predictions: ', pred)
         print('------------------------------------------------')

      # Check if we have reach convergence
      if np.sum(np.abs(w_temp - w)) < 0.001:
         print(epoch)
         print(error)
         return w
      else: 
         w_temp = w
  return w

# Create some artificial database
x = np.zeros((4,3))
y = np.zeros((4,)) 
x[0] = [1, 1, 1]
x[1] = [1, 2, 2]
x[2] = [1, 10, 10]
x[3] = [1, 11, 11]
y[0] = 0
y[1] = 0
y[2] = 1
y[3] = 1

print(x)
print(y)

# Train the weights
w = train_weights(x, y, 0)
print('Trained weights: ', w)

# Get predicitons
pred = 1/(1+np.exp(-1 * np.dot(x, w)))
error = np.sum(pred - y)   
pred[pred < 0.5] = 0
pred[pred >= 0.5] = 1
print('Predictions: ', pred)