Python:梯度下降 Lab (六十三)
梯度下降
在下面的 lab 中,你将能够在以下两个类的示例数据集上执行梯度下降算法。
工作区
要打开这个 notebook,你有两个选择:
在这个notebook中,你将实现构建梯度下降算法的功能,即:
- sigmoid: sigmoid激活函数。
- output_formula: 输出(预测)公式
- error_formula: 误差函数。
- update_weights: 更新权重的函数。
-
当你执行它们时,运行
train
函数,这将绘制连续梯度下降步骤中的几条直线。 它还会绘制误差函数,随着 epoch 数量的增加,你可以看到它正在降低。
如果你需要任何帮助,请随时在相同的文件夹中查看解决方案 notebook。
实现梯度下降算法
在该 Lab 中,我们将实现梯度下降算法的基本函数,以便在小数据集中查找数据边界。 首先,我们将从一些函数开始,帮助我们绘制和可视化数据。
实现梯度下降算法
在该 Lab 中,我们将实现梯度下降算法的基本函数,以便在小数据集中查找数据边界。 首先,我们将从一些函数开始,帮助我们绘制和可视化数据。
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
#Some helper functions for plotting and drawing lines
def plot_points(X, y):
admitted = X[np.argwhere(y==1)]
rejected = X[np.argwhere(y==0)]
plt.scatter([s[0][0] for s in rejected], [s[0][1] for s in rejected], s = 25, color = 'blue', edgecolor = 'k')
plt.scatter([s[0][0] for s in admitted], [s[0][1] for s in admitted], s = 25, color = 'red', edgecolor = 'k')
def display(m, b, color='g--'):
plt.xlim(-0.05,1.05)
plt.ylim(-0.05,1.05)
x = np.arange(-10, 10, 0.1)
plt.plot(x, m*x+b, color)
读取与绘制数据
data = pd.read_csv('data.csv', header=None)
X = np.array(data[[0,1]])
y = np.array(data[2])
plot_points(X,y)
plt.show()
待办: 实现基本函数
现在轮到你练习了。 如之前所述,实现以下基本函数。
- Sigmoid 激活函数
$$\sigma(x) = \frac{1}{1+e^{-x}}$$
- 输出(预测)公式
$$\hat{y} = \sigma(w_1 x_1 + w_2 x_2 + b)$$
- 误差函数
$$Error(y, \hat{y}) = - y \log(\hat{y}) - (1-y) \log(1-\hat{y})$$
- 更新权重的函数
$$ w_i^{'} \longleftarrow w_i + \alpha (y - \hat{y}) x_i$$
$$ b^{'} \longleftarrow b + \alpha (y - \hat{y})$$
# Implement the following functions
# Activation (sigmoid) function
def sigmoid(x):
return 1 / (1 + np.exp(-x))
# Output (prediction) formula
def output_formula(features, weights, bias):
return sigmoid(np.dot(features, weights) + bias)
# Error (log-loss) formula
def error_formula(y, output):
return -y*np.log(output) - (1-y)*np.log(1 - output)
# Gradient descent step
def update_weights(x, y, weights, bias, learnrate):
output = output_formula(x, weights, bias)
d_error = (y - output)
weights += learnrate * d_error * x
bias += learnrate * d_error
return weights, bias
训练函数
该函数将帮助我们通过所有数据来迭代梯度下降算法,用于多个 epoch。 它还将绘制数据,以及在我们运行算法时绘制出一些边界线。
np.random.seed(44)
epochs = 100
learnrate = 0.01
def train(features, targets, epochs, learnrate, graph_lines=False):
errors = []
n_records, n_features = features.shape
last_loss = None
weights = np.random.normal(scale=1 / n_features**.5, size=n_features)
bias = 0
for e in range(epochs):
del_w = np.zeros(weights.shape)
for x, y in zip(features, targets):
output = output_formula(x, weights, bias)
error = error_formula(y, output)
weights, bias = update_weights(x, y, weights, bias, learnrate)
# Printing out the log-loss error on the training set
out = output_formula(features, weights, bias)
loss = np.mean(error_formula(targets, out))
errors.append(loss)
if e % (epochs / 10) == 0:
print("\n========== Epoch", e,"==========")
if last_loss and last_loss < loss:
print("Train loss: ", loss, " WARNING - Loss Increasing")
else:
print("Train loss: ", loss)
last_loss = loss
predictions = out > 0.5
accuracy = np.mean(predictions == targets)
print("Accuracy: ", accuracy)
if graph_lines and e % (epochs / 100) == 0:
display(-weights[0]/weights[1], -bias/weights[1])
# Plotting the solution boundary
plt.title("Solution boundary")
display(-weights[0]/weights[1], -bias/weights[1], 'black')
# Plotting the data
plot_points(features, targets)
plt.show()
# Plotting the error
plt.title("Error Plot")
plt.xlabel('Number of epochs')
plt.ylabel('Error')
plt.plot(errors)
plt.show()
是时候来训练算法啦!
当我们运行该函数时,我们将获得以下内容:
- 目前的训练损失与准确性的 10 次更新
- 获取的数据图和一些边界线的图。 最后一个是黑色的。请注意,随着我们遍历更多的 epoch ,线会越来越接近最佳状态。
- 误差函数的图。 请留意,随着我们遍历更多的 epoch,它会如何降低。
train(X, y, epochs, learnrate, True)
========== Epoch 0 ==========
Train loss: 0.713584519538
Accuracy: 0.4
========== Epoch 10 ==========
Train loss: 0.622583521045
Accuracy: 0.59
========== Epoch 20 ==========
Train loss: 0.554874408367
Accuracy: 0.74
========== Epoch 30 ==========
Train loss: 0.501606141872
Accuracy: 0.84
========== Epoch 40 ==========
Train loss: 0.459333464186
Accuracy: 0.86
========== Epoch 50 ==========
Train loss: 0.425255434335
Accuracy: 0.93
========== Epoch 60 ==========
Train loss: 0.397346157167
Accuracy: 0.93
========== Epoch 70 ==========
Train loss: 0.374146976524
Accuracy: 0.93
========== Epoch 80 ==========
Train loss: 0.354599733682
Accuracy: 0.94
========== Epoch 90 ==========
Train loss: 0.337927365888
Accuracy: 0.94
为者常成,行者常至
自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)