选做实验:逻辑回归
- 探索 sigmoid 函数(也称为逻辑函数)
- 探索使用 sigmoid 函数的逻辑回归
import numpy as np
%matplotlib widget
import matplotlib.pyplot as plt
from plt_one_addpt_onclick import plt_one_addpt_onclick
from lab_utils_common import draw_vthresh
plt.style.use('./deeplearning.mplstyle')
Sigmoid or Logistic Function
如讲座视频中讨论的那样,对于分类任务,我们可以从使用线性回归模型开始:
f w , b ( x ( i ) ) = w ⋅ x ( i ) + b f_{w,b}(x^{(i)}) = \mathbf{w} \cdot \mathbf{x}^{(i)} + b fw,b(x(i))=w⋅x(i)+b
给定 x x x 来预测 y y y 。
- 然而,我们希望分类模型的预测值在 0 0 0 和 1 1 1 之间,因为我们的输出变量 y y y 只能是 0 0 0 或 1 1 1。
- 这可以通过使用“ s i g m o i d sigmoid sigmoid 函数”来实现,该函数将所有输入值映射到 0 0 0 和 1 1 1 之间。
让我们实现 s i g m o i d sigmoid sigmoid 函数并亲自看看。
图中描述了 s i g m o i d sigmoid sigmoid 函数(也称为逻辑函数),其输出值在 0 0 0 和 1 1 1 之间。
Sigmoid 函数的公式
Sigmoid 函数的公式如下:
g ( z ) = 1 1 + e − z g(z) = \frac{1}{1 + e^{-z}} g(z)=1+e−z1
在逻辑回归的情况下, z z z (即 s i g m o i d sigmoid sigmoid 函数的输入)是线性回归模型的输出。
- 在单个示例的情况下, z z z 是标量。
- 在多个示例的情况下, z z z 可能是一个包含 m m m 个值的向量,每个示例一个值。
- Sigmoid 函数的实现应该覆盖这两种潜在的输入格式。让我们在 Python 中实现这一点。
NumPy 有一个名为 exp()
的函数,它提供了一种便捷的方法来计算输入数组
z
z
z 中所有元素的指数(
e
z
e^z
ez )。
它也适用于单个数字作为输入,如下所示。
# 输入是一个数组
input_array = np.array([1, 2, 3])
exp_array = np.exp(input_array)
print("Input to exp:", input_array)
print("Output of exp:", exp_array)
# 输入是一个单一数值
input_val = 1
exp_val = np.exp(input_val)
print("Input to exp:", input_val)
print("Output of exp:", exp_val)
输出结果:
Input to exp: [1 2 3]
Output of exp: [ 2.718 7.389 20.086]
Input to exp: 1
Output of exp: 2.718281828459045
Sigmoid 函数的实现
def sigmoid(z):
"""
计算 z 的 sigmoid 值
参数:
z (ndarray): 一个标量,或任意大小的 numpy 数组。
返回:
g (ndarray): z 的 sigmoid 值,形状与 z 相同
"""
g = 1 / (1 + np.exp(-z))
return g
查看函数在不同 z z z 值下的输出
# 生成一个从 -10 到 10 的等间隔值数组
z_tmp = np.arange(-10, 11)
# 使用上面实现的 sigmoid 函数获取 sigmoid 值
y = sigmoid(z_tmp)
# 美化打印两个数组
np.set_printoptions(precision=3)
print("Input (z), Output (sigmoid(z))")
print(np.c_[z_tmp, y])
输出结果:
Input (z), Output (sigmoid(z))
[[-1.000e+01 4.540e-05]
[-9.000e+00 1.234e-04]
[-8.000e+00 3.354e-04]
[-7.000e+00 9.111e-04]
[-6.000e+00 2.473e-03]
[-5.000e+00 6.693e-03]
[-4.000e+00 1.799e-02]
[-3.000e+00 4.743e-02]
[-2.000e+00 1.193e-01]
[-1.000e+00 2.689e-01]
...
使用 Matplotlib 绘制 Sigmoid 函数
# 绘制 z 与 sigmoid(z)
fig, ax = plt.subplots(1, 1, figsize=(5, 3))
ax.plot(z_tmp, y, c="b")
ax.set_title("Sigmoid function")
ax.set_ylabel('sigmoid(z)')
ax.set_xlabel('z')
draw_vthresh(ax, 0)
- 当 z z z 变为大负值时, s i g m o i d sigmoid sigmoid 函数接近 0 0 0;
- 当 z z z 变为大正值时, s i g m o i d sigmoid sigmoid 函数接近 1 1 1。
逻辑回归
逻辑回归模型将 s i g m o i d sigmoid sigmoid 函数应用于熟悉的线性回归模型,如下所示:
f w , b ( x ) = g ( w ⋅ x + b ) = 1 1 + e − ( w ⋅ x + b ) f_{w,b}(\mathbf{x}) = g(\mathbf{w} \cdot \mathbf{x} + b) = \frac{1}{1 + e^{-(\mathbf{w} \cdot \mathbf{x} + b)}} fw,b(x)=g(w⋅x+b)=1+e−(w⋅x+b)1
其中 g ( z ) = 1 1 + e − z g(z) = \frac{1}{1 + e^{-z}} g(z)=1+e−z1
将逻辑回归应用于肿瘤分类的分类数据示例。首先,加载示例和参数的初始值。
x_train = np.array([0., 1., 2., 3., 4., 5.])
y_train = np.array([0, 0, 0, 1, 1, 1])
w_in = np.zeros((1))
b_in = 0
尝试以下步骤:
- 点击“Run Logistic Regression”以找到给定训练数据的最佳逻辑回归模型
- 注意结果模型与数据非常匹配。
- 注意,橙色线是 z z z 或 w ⋅ x ( i ) + b \mathbf{w} \cdot \mathbf{x}^{(i)} + b w⋅x(i)+b ,它不匹配线性回归模型中的直线。通过应用阈值进一步改进这些结果。
- 勾选“Toggle 0.5 threshold”框以显示应用阈值后的预测。
- 这些预测看起来不错,预测与数据匹配。
- 现在,在较大肿瘤大小范围内(接近10)添加更多数据点,并重新运行线性回归。与线性回归模型不同,此模型继续做出正确的预测。
plt.close('all')
addpt = plt_one_addpt_onclick( x_train,y_train, w_in, b_in, logistic=True)
小结
探索了在逻辑回归中使用 sigmoid 函数
可选实验:逻辑回归,决策边界
目标
在这个实验中,你将:
- 绘制逻辑回归模型的决策边界。这将帮助你更好地理解模型的预测。
import numpy as np
%matplotlib widget
import matplotlib.pyplot as plt
from lab_utils_common import plot_data, sigmoid, draw_vthresh
plt.style.use('./deeplearning.mplstyle')
数据集
假设你有以下训练数据集:
- 输入变量 x x x 是一个包含 6 个训练样本的 numpy 数组,每个样本有两个特征。
- 输出变量 y y y 也是一个包含 6 个样本的 numpy 数组, y y y 要么是 0 0 0,要么是 1 1 1。
X = np.array([[0.5, 1.5], [1,1], [1.5, 0.5], [3, 0.5], [2, 2], [1, 2.5]])
y = np.array([0, 0, 0, 1, 1, 1]).reshape(-1,1)
绘制数据
让我们使用一个辅助函数来绘制这些数据。标签为 y = 1 y = 1 y=1 的数据点显示为红色叉号,而标签为 y = 0 y = 0 y=0 的数据点显示为蓝色圆圈。
fig,ax = plt.subplots(1,1,figsize=(4,4))
plot_data(X, y, ax)
ax.axis([0, 4, 0, 3.5])
ax.set_ylabel('$x_1$')
ax.set_xlabel('$x_0$')
plt.show()
逻辑回归模型
- 假设你想在这个数据上训练一个逻辑回归模型,该模型的形式为
f ( x ) = g ( w 0 x 0 + w 1 x 1 + b ) f(x) = g(w_0 x_0 + w_1 x_1 + b) f(x)=g(w0x0+w1x1+b)
其中
g ( z ) = 1 1 + e − z g(z) = \frac{1}{1 + e^{-z}} g(z)=1+e−z1,这是 S S S 形函数。 - 假设你训练了模型并得到参数
b = − 3 , w 0 = 1 , w 1 = 1 b = -3, w_0 = 1, w_1 = 1 b=−3,w0=1,w1=1
也就是说,
f ( x ) = g ( x 0 + x 1 − 3 ) f(x) = g(x_0 + x_1 - 3) f(x)=g(x0+x1−3)(你将在课程中学习如何将这些参数拟合到数据上)
让我们通过绘制其决策边界来尝试理解这个训练好的模型在预测什么。
逻辑回归和决策边界的复习
- 回顾一下,对于逻辑回归,模型表示为
f w , b ( x ( i ) ) = g ( w ⋅ x ( i ) + b ) f_{w,b}(\mathbf{x}^{(i)}) = g(\mathbf{w} \cdot \mathbf{x}^{(i)} + b) fw,b(x(i))=g(w⋅x(i)+b)
其中 g ( z ) g(z) g(z) 称为 S S S 形函数,它将所有输入值映射到 0 0 0 和 1 1 1 之间的值:
g ( z ) = 1 1 + e − z g(z) = \frac{1}{1 + e^{-z}} g(z)=1+e−z1
并且 w ⋅ x \mathbf{w} \cdot \mathbf{x} w⋅x 是向量点积:
w ⋅ x = w 0 x 0 + w 1 x 1 \mathbf{w} \cdot \mathbf{x} = w_0 x_0 + w_1 x_1 w⋅x=w0x0+w1x1 - 我们将模型 f w , b ( x ) f_{w,b}(x) fw,b(x) 的输出解释为在给定 x x x 的情况下 y = 1 y = 1 y=1 的概率,并由 w w w 和 b b b 参数化。
- 因此,要从逻辑回归模型中得到最终预测(
y
=
0
y = 0
y=0 或
y
=
1
y = 1
y=1 ),我们可以使用以下启发式方法:
- 如果 f w , b ( x ) ≥ 0.5 f_{w,b}(x) \geq 0.5 fw,b(x)≥0.5 ,则预测 y = 1 y = 1 y=1
- 如果 f w , b ( x ) < 0.5 f_{w,b}(x) < 0.5 fw,b(x)<0.5 ,则预测 y = 0 y = 0 y=0
- 让我们绘制 S S S 形函数来查看 g ( z ) ≥ 0.5 g(z) \geq 0.5 g(z)≥0.5 的位置。
# Plot sigmoid(z) over a range of values from -10 to 10
z = np.arange(-10,11)
fig,ax = plt.subplots(1,1,figsize=(5,3))
# Plot z vs sigmoid(z)
ax.plot(z, sigmoid(z), c="b")
ax.set_title("Sigmoid function")
ax.set_ylabel('sigmoid(z)')
ax.set_xlabel('z')
draw_vthresh(ax,0)
逻辑回归和决策边界的复习
- 如你所见,当 z ≥ 0 z \geq 0 z≥0 时, g ( z ) ≥ 0.5 g(z) \geq 0.5 g(z)≥0.5 。
- 对于逻辑回归模型,
z
=
w
⋅
x
+
b
z = \mathbf{w} \cdot \mathbf{x} + b
z=w⋅x+b 。因此,
- 如果 w ⋅ x + b ≥ 0 \mathbf{w} \cdot \mathbf{x} + b \geq 0 w⋅x+b≥0 ,模型预测 y = 1 y = 1 y=1
- 如果 w ⋅ x + b < 0 \mathbf{w} \cdot \mathbf{x} + b < 0 w⋅x+b<0 ,模型预测 y = 0 y = 0 y=0
绘制决策边界
现在,让我们回到我们的例子,理解逻辑回归模型是如何进行预测的。
- 我们的逻辑回归模型形式为
f ( x ) = g ( − 3 + x 0 + x 1 ) f(x) = g(-3 + x_0 + x_1) f(x)=g(−3+x0+x1) - 根据你上面学到的知识,你可以看到该模型预测 y = 1 y = 1 y=1 当且仅当 − 3 + x 0 + x 1 ≥ 0 -3 + x_0 + x_1 \geq 0 −3+x0+x1≥0 。
让我们看看这在图形上是什么样子。我们首先绘制 − 3 + x 0 + x 1 = 0 -3 + x_0 + x_1 = 0 −3+x0+x1=0 ,这相当于 x 1 = 3 − x 0 x_1 = 3 - x_0 x1=3−x0
# Choose values between 0 and 6
x0 = np.arange(0,6)
x1 = 3 - x0
fig,ax = plt.subplots(1,1,figsize=(5,4))
# Plot the decision boundary
ax.plot(x0,x1, c="b")
ax.axis([0, 4, 0, 3.5])
# Fill the region below the line
ax.fill_between(x0,x1, alpha=0.2)
# Plot the original data
plot_data(X,y,ax)
ax.set_ylabel(r'$x_1$')
ax.set_xlabel(r'$x_0$')
plt.show()
- 在上图中,蓝线表示直线 x 0 + x 1 − 3 = 0 x_0 + x_1 - 3 = 0 x0+x1−3=0 ,并且它应该在 x 1 x_1 x1 轴上与 3 3 3 相交 ( ( (如果我们设 x 1 = 3 , x 0 = 0 ) x_1 = 3 , x_0 = 0 ) x1=3,x0=0),并在 x 0 x_0 x0 轴上与 3 3 3相交(如果我们设 x 1 = 0 , x 0 = 3 x_1 = 0 , x_0 = 3 x1=0,x0=3 )。
- 阴影区域表示 − 3 + x 0 + x 1 < 0 -3 + x_0 + x_1 < 0 −3+x0+x1<0 。直线以上的区域表示 − 3 + x 0 + x 1 > 0 -3 + x_0 + x_1 > 0 −3+x0+x1>0 。
- 阴影区域中的任何点(在直线下方)都被分类为 y = 0 y = 0 y=0 。在直线上的任何点或以上的任何点都被分类为 y = 1 y = 1 y=1 。这条直线被称为“决策边界”。
正如我们在讲座中看到的,通过使用高阶多项式项(例如: f ( x ) = g ( x 0 2 + x 1 − 1 ) f(x) = g(x_0^2 + x_1 - 1) f(x)=g(x02+x1−1) ),我们可以得出更复杂的非线性边界。
小结
在逻辑回归的背景下探索了决策边界。