矢量化正则化梯度下降未通过数值检查
Vectorized Regularized Gradient Descent not passing numerical check
我在 Python 中编写了一个实现,使用 NumPy 的向量化正则化梯度下降进行逻辑回归。我使用了一种数字检查方法来检查我的实现是否正确。数值检查验证了我对线性回归 GD 的实现,但是 Logisitc 失败了,我找不到。任何帮助,将不胜感激。所以这里是:
这些是我计算成本和梯度的方法(更新函数计算梯度并更新参数):
@staticmethod
def _hypothesis(parameters, features):
return Activation.sigmoid(features.dot(parameters))
@staticmethod
def _cost_function(parameters, features, targets):
m = features.shape[0]
return np.sum(-targets * (np.log(LogisticRegression._hypothesis(parameters, features)) - (1 - targets) * (
np.log(1 - LogisticRegression._hypothesis(parameters, features))))) / m
@staticmethod
def _update_function(parameters, features, targets, extra_param):
regularization_vector = extra_param.get("regularization_vector", 0)
alpha = extra_param.get("alpha", 0.001)
m = features.shape[0]
return parameters - alpha / m * (
features.T.dot(LogisticRegression._hypothesis(parameters, features) - targets)) + \
(regularization_vector / m) * parameters
成本函数不包含正则化,但我做的测试是使用等于零的正则化向量,所以这无关紧要。我如何测试:
def numerical_check(features, parameters, targets, cost_function, update_function, extra_param, delta):
gradients = - update_function(parameters, features, targets, extra_param)
parameters_minus = np.copy(parameters)
parameters_plus = np.copy(parameters)
parameters_minus[0, 0] = parameters_minus[0, 0] + delta
parameters_plus[0, 0] = parameters_plus[0, 0] - delta
approximate_gradient = - (cost_function(parameters_plus, features, targets) -
cost_function(parameters_minus, features, targets)) / (2 * delta) / parameters.shape[0]
return abs(gradients[0, 0] - approximate_gradient) <= delta
基本上,当我将第一个参数 delta 向左和向右移动时,我正在手动计算梯度。然后我将它与我从更新函数中获得的梯度进行比较。我使用的初始参数等于 0,因此接收到的更新参数等于梯度除以特征数。 alpha 也等于 1。不幸的是,我从这两种方法中得到了不同的值,但我找不到原因。非常感谢任何有关如何解决此问题的建议。
我想我在您的代码中发现了一个可能的错误,请告诉我这是否属实。
在您的 numerical_check
函数中,您调用 update_function
来初始化 gradient
。但是,在上面的 _update_function
中,您实际上并没有 return 渐变,而是 return 更新了 parameters
.
的值
也就是说,请注意您的 _update_function
的 return 语句是这样的:
return parameters - alpha / m * (
features.T.dot(LogisticRegression._hypothesis(parameters, features) - targets)) + \
(regularization_vector / m) * parameters
我想给你的建议以及我在 ML 算法中所做的是创建一个单独的函数来计算梯度,例如
def _gradient(features, parameters, target):
m = features.shape[0]
return features.T.dot(LogisticRegression._hypothesis(parameters, features) - targets)) / m
然后更改 numerical_check
函数来初始化 gradient
,如下所示:
gradient = _gradient(features, parameters, target)
希望这能解决您的问题。
您的成本函数有误。错误是由于括号的无效分配。我已经解决了
def _cost_function(parameters, features, targets):
m = features.shape[0]
return -np.sum(
( targets) * (np.log( LogisticRegression._hypothesis(parameters, features)))
+ (1 - targets) * (np.log(1 - LogisticRegression._hypothesis(parameters, features)))
) / m
尝试干净地编写代码,这有助于检测此类错误
我在 Python 中编写了一个实现,使用 NumPy 的向量化正则化梯度下降进行逻辑回归。我使用了一种数字检查方法来检查我的实现是否正确。数值检查验证了我对线性回归 GD 的实现,但是 Logisitc 失败了,我找不到。任何帮助,将不胜感激。所以这里是:
这些是我计算成本和梯度的方法(更新函数计算梯度并更新参数):
@staticmethod
def _hypothesis(parameters, features):
return Activation.sigmoid(features.dot(parameters))
@staticmethod
def _cost_function(parameters, features, targets):
m = features.shape[0]
return np.sum(-targets * (np.log(LogisticRegression._hypothesis(parameters, features)) - (1 - targets) * (
np.log(1 - LogisticRegression._hypothesis(parameters, features))))) / m
@staticmethod
def _update_function(parameters, features, targets, extra_param):
regularization_vector = extra_param.get("regularization_vector", 0)
alpha = extra_param.get("alpha", 0.001)
m = features.shape[0]
return parameters - alpha / m * (
features.T.dot(LogisticRegression._hypothesis(parameters, features) - targets)) + \
(regularization_vector / m) * parameters
成本函数不包含正则化,但我做的测试是使用等于零的正则化向量,所以这无关紧要。我如何测试:
def numerical_check(features, parameters, targets, cost_function, update_function, extra_param, delta):
gradients = - update_function(parameters, features, targets, extra_param)
parameters_minus = np.copy(parameters)
parameters_plus = np.copy(parameters)
parameters_minus[0, 0] = parameters_minus[0, 0] + delta
parameters_plus[0, 0] = parameters_plus[0, 0] - delta
approximate_gradient = - (cost_function(parameters_plus, features, targets) -
cost_function(parameters_minus, features, targets)) / (2 * delta) / parameters.shape[0]
return abs(gradients[0, 0] - approximate_gradient) <= delta
基本上,当我将第一个参数 delta 向左和向右移动时,我正在手动计算梯度。然后我将它与我从更新函数中获得的梯度进行比较。我使用的初始参数等于 0,因此接收到的更新参数等于梯度除以特征数。 alpha 也等于 1。不幸的是,我从这两种方法中得到了不同的值,但我找不到原因。非常感谢任何有关如何解决此问题的建议。
我想我在您的代码中发现了一个可能的错误,请告诉我这是否属实。
在您的 numerical_check
函数中,您调用 update_function
来初始化 gradient
。但是,在上面的 _update_function
中,您实际上并没有 return 渐变,而是 return 更新了 parameters
.
也就是说,请注意您的 _update_function
的 return 语句是这样的:
return parameters - alpha / m * (
features.T.dot(LogisticRegression._hypothesis(parameters, features) - targets)) + \
(regularization_vector / m) * parameters
我想给你的建议以及我在 ML 算法中所做的是创建一个单独的函数来计算梯度,例如
def _gradient(features, parameters, target):
m = features.shape[0]
return features.T.dot(LogisticRegression._hypothesis(parameters, features) - targets)) / m
然后更改 numerical_check
函数来初始化 gradient
,如下所示:
gradient = _gradient(features, parameters, target)
希望这能解决您的问题。
您的成本函数有误。错误是由于括号的无效分配。我已经解决了
def _cost_function(parameters, features, targets):
m = features.shape[0]
return -np.sum(
( targets) * (np.log( LogisticRegression._hypothesis(parameters, features)))
+ (1 - targets) * (np.log(1 - LogisticRegression._hypothesis(parameters, features)))
) / m
尝试干净地编写代码,这有助于检测此类错误