吴恩达Coursera课程——第一部分:监督学习Week1

   本人ML小白一枚,知识的学习和笔记的整理也借鉴了多位大佬的知识,一起加油~~

 

一、机器学习

1、定义

      Tom认为能从经验E中学习,解决任务T,达到性能度量值P,当且仅当,有了经验E后,经过P评判,程序在处理T时的性能有所提升。

  • 监督学习: 教会计算机完成某项任务。
  • 非监督学习:让计算机自己学习完成某项任务。
  • 案例:

       医疗、自动驾驶、读手语、音乐生成、自然语言处理的案例。

2、监督学习

       给算法一个数据集,其中包含了正确答案,算法的目的是给出更多的正确答案。

       监督学习方式有:

  • 回归问题-预测连续的值的输出:预测房价。
  • 分类问题-预测离散值:预测肿瘤是良性或恶性。    

   3、非监督学习

       只给算法一个数据集,但是不给数据集的正确答案,由算法自行分类。

  • 聚类算法 

二、单变量线性回归

2.1 模型表示 

      举例:房价预测。

      使用一个数据集,包括某地的住房价格。在这里,要根据不同房屋的尺寸大小,得知这个房子的价格。所以,我们可以构建一个模型。这也是回归问题。回归一词指的是,我们根据之前的数据预测出一个准确的连续值,即房子的价格。这里的Data table是我们的数据集,即训练集。 

       另一个分类问题,当我们想要预测离散的输出值,例如,我们正在寻找癌症肿瘤,并想要确定肿瘤是良性的还是恶性的,这就是0/1离散输出的问题。

       我们将要用来描述这个回归问题的标记如下:

假设函数:f=wx+b

m 代表训练集中实例的数量

x 代表特征/输入变量

y 代表目标变量/输出变量

(x,y) 代表训练集中的样本

(xi,yi) 代表第i个观察实例

f 代表学习算法的解决方案或函数也称为假设

 2.2 代价函数(损失函数)

       代价函数也被称为平方误差函数或者平方误差代价函数,在线性回归问题中,平方误差函数  是最常用的手段。

      f(x(i))是预测值,y(i)是实际值。两者取差,再平方。从其他博主那得知,此处可能用到了最小二乘法。。。。一些不大懂的东东。先按误差来理解吧!

       目标: 选择合适的参数w和b,最小化代价函数,即minimize J(w, b)

#J(a,b)代价函数的计算求和。
def compute_cost(x, y, w, b): 
    """
    Computes the cost function for linear regression.
    
    Args:
      x (ndarray (m,)): Data, m examples 
      y (ndarray (m,)): target values
      w,b (scalar)    : model parameters  
    
    Returns
        total_cost (float): The cost of using w,b as the parameters for linear regression
               to fit the data points in x and y
    """
    # number of training examples
    m = x.shape[0] 
    
    cost_sum = 0 
    for i in range(m): 
        f_wb = w * x[i] + b #预测值,y[i]是实际值 
        cost = (f_wb - y[i]) ** 2  
        cost_sum = cost_sum + cost  
    total_cost = (1 / (2 * m)) * cost_sum  

    return total_cost

 cost function直观理解1:

       上图只是关于一个w特征的二维图。

       左侧×符号标记是对于w,b所能确定的f预测值,直线表示实际值。

       右侧是探究w对J的影响。

   cost function直观理解2:

      三维图像始终包含一个最低点。

       总之,我们真正需要的是一种有效的算法,能够自动地找出这些使代价函数 J 取最小值的参数 w和b 来。

 2.3 梯度下降

      梯度下降是一个用来求函数最小值的算法。我们将使用梯度下降算法求出代价函数的最小值。 

     算法思路

  • 指定w 和 b 的初始值,通常设w=0,b=0
  • 不断改变w和b的值,使J(w,b)不断减小
  • 得到一个最小值或局部最小值时停止。

      梯度: 函数中某一点(x, y)的梯度代表函数在该点变化最快的方向。
(选用不同的点开始可能达到另一个局部最小值,选择不同的初始参数组合,可能会找到不同的局部最小值。)

       梯度下降公式:

说明: 

  • 第二个公式的是未更新的值。
  • i从第一个数据开始。
  • w和b应同步更新。如果先更新w,会使得b是根据更新后的w去更新的。

       关于学习率 α :

  •        如果学习率太小,那速度太慢了,每次都是移动很小很小的一步,所以最后需要很多步才能到达局部最低点。
  •       如果学习率太大,可能走几步就越过了局部最低点,甚至无法收敛。

      但,Don`t worry!

       随着梯度下降法的运行,你移动的幅度会自动变得越来越小,直到最终移动幅度非常小,你会发现,已经收敛到局部极小值。

       在梯度下降法中,当我们接近局部最低点时,梯度下降法会自动采取更小的幅度,这是因为当我们接近局部最低点时,很显然在局部最低时导数等于,所以当我们接近局部最低时,导数值会自动变得越来越小,所以梯度下降将自动采取较小的幅度,这就是梯度下降的做法。

      即经过多次迭代,学习率小,慢慢迭代,偏导数逐渐趋向于0.迭代不能进行,W值不会变了,模型逐渐趋向于平稳(收敛),不再更新,则到达局部最小值,则合适的W,b就能找出来。

    梯度下降完整代码:

#自动化优化过程 𝑤 和 𝑏 使用梯度下降。
import math, copy
import numpy as np
import matplotlib.pyplot as plt
plt.style.use('./deeplearning.mplstyle')
from my_Function.lab_utils_uni import plt_house_x, plt_contour_wgrad, plt_divergence, plt_gradients
# Load our data set
x_train = np.array([1.0, 2.0])   #features
y_train = np.array([300.0, 500.0])   #target value


# Function to calculate the cost
#代价函数J(w,b)求和。
#𝐽(𝑤,𝑏)=1/2𝑚∑(𝑓𝑤,𝑏(𝑥(𝑖))−𝑦(𝑖))²
def compute_cost(x, y, w, b):
    """
       Computes the cost function for linear regression.
       Args:
         x (ndarray (m,)): Data, m examples
         y (ndarray (m,)): target values
         w,b (scalar)    : model parameters

       Returns
           total_cost (float): The cost of using w,b as the parameters for linear regression
                  to fit the data points in x and y
       """
    # number of training examples
    m = x.shape[0]
    cost = 0
    for i in range(m):
        f_wb = w * x[i] + b
        cost = cost + (f_wb - y[i]) ** 2  #y[i]是实际值
    total_cost = 1 / (2 * m) * cost

    return total_cost


# 求偏导的
def compute_gradient(x, y, w, b):
    """
    Computes the gradient for linear regression
    Args:
      x (ndarray (m,)): Data, m examples
      y (ndarray (m,)): target values
      w,b (scalar)    : model parameters
    Returns
      dj_dw (scalar): The gradient of the cost w.r.t. the parameters w
      dj_db (scalar): The gradient of the cost w.r.t. the parameter b
     """

    # Number of training examples
    m = x.shape[0]
    dj_dw = 0
    dj_db = 0

    for i in range(m):
        f_wb = w * x[i] + b
        dj_dw_i = (f_wb - y[i]) * x[i]
        dj_db_i = f_wb - y[i]
        dj_db += dj_db_i  # 对b求偏导,1-m个数据的导数的和
        dj_dw += dj_dw_i
    dj_dw = dj_dw / m
    dj_db = dj_db / m

    return dj_dw, dj_db

plt_gradients(x_train,y_train, compute_cost, compute_gradient)
plt.show()

def gradient_descent(x, y, w_in, b_in, alpha, num_iters, cost_function, gradient_function):
    """
    Performs gradient descent to fit w,b. Updates w,b by taking
    num_iters gradient steps with learning rate alpha
    --执行梯度下降以适应w,b。通过以下方式更新w、b
      具有学习速率α的num_iters梯度步长

    Args:
      x (ndarray (m,))  : Data, m examples
      y (ndarray (m,))  : target values
      w_in,b_in (scalar): initial values of model parameters
      alpha (float):     Learning rate
      num_iters (int):   number of iterations to run gradient descent——运行梯度下降的迭代次数
      cost_function:     function to call to produce cost——函数调用以生成成本
      gradient_function: function to call to produce gradient

    Returns:
      w (scalar): Updated value of parameter after running gradient descent——运行梯度下降后更新的参数值
      b (scalar): Updated value of parameter after running gradient descent
      J_history (List): History of cost values
      p_history (list): History of parameters [w,b]

      列表是最常用的Python数据类型,它可以作为一个方括号内的逗号分隔值出现。
      列表的数据项不需要具有相同的类型
      创建一个列表,只要把逗号分隔的不同的数据项使用方括号括起来即可。如下所示:

      list1 = ['physics', 'chemistry', 1997, 2000]
      list2 = [1, 2, 3, 4, 5 ]
      list3 = ["a", "b", "c", "d"]
      """
    # copy.deepcopy()函数是一个深复制函数。所谓深复制,就是从输入变量完全复刻一个相同的变量,无论怎么改变新变量,原有变量的值都不会受到影响。
    # 与等号赋值不同,等号复制类似于贴标签,两者实质上是同一段内存。
    w = copy.deepcopy(w_in)  # avoid modifying global w_in
    # An array to store cost J and w's at each iteration primarily for graphing later
    # 一个数组,用于存储每次迭代的成本J和w,主要用于以后的绘图
    J_history = []
    p_history = []
    b = b_in
    w = w_in

    for i in range(num_iters):
        # Calculate the gradient and update the parameters using gradient_function
        # 计算梯度并使用gradient_function更新参数
        dj_dw, dj_db = gradient_function(x, y, w, b)  # 这是那个导数项

        # Update Parameters using equation (3) above
        b = b - alpha * dj_db
        w = w - alpha * dj_dw

        # Save cost J at each iteration——每次迭代节省成本J
        if i < 100000:  # prevent resource exhaustion ——防止资源耗尽
            J_history.append(cost_function(x, y, w, b))
            p_history.append([w, b])  # 把每一次迭代产生的w,b都加入p_history
        # Print cost every at intervals 10 times or as many iterations if < 10
        # 每隔10次打印一次成本,如果<10次,则重复次数相同
        # math.ceil:向上取整,四舍五入。
        if i % math.ceil(num_iters / 10) == 0:
            print(f"Iteration {i:4}: Cost {J_history[-1]:0.2e} ",
                  f"dj_dw: {dj_dw: 0.3e}, dj_db: {dj_db: 0.3e}  ",
                  f"w: {w: 0.3e}, b:{b: 0.5e}")

    return w, b, J_history, p_history  # return w and J,w history for graphing——返回w和J,w的图形历史记录

# initialize parameters
w_init = 0
b_init = 0
# some gradient descent settings
iterations = 20000
tmp_alpha = 1.0e-2
# run gradient descent——运行梯度下降函数
w_final, b_final, J_hist, p_hist = gradient_descent(x_train ,y_train, w_init, b_init, tmp_alpha,
                                                    iterations, compute_cost, compute_gradient)
print(f"(w,b) found by gradient descent: ({w_final:8.4f},{b_final:8.4f})")
#经过多次迭代,学习率小,慢慢迭代,偏导数逐渐趋向于0.迭代不能进行,W值不会变了,模型逐渐趋向于平稳(收敛),不再更新,则到达局部最小值。
#则合适的W,b就能找出来。

# plot cost versus iteration
fig, (ax1, ax2) = plt.subplots(1, 2, constrained_layout=True, figsize=(12,4))
ax1.plot(J_hist[:100])
ax2.plot(1000 + np.arange(len(J_hist[1000:])), J_hist[1000:])
ax1.set_title("Cost vs. iteration(start)");  ax2.set_title("Cost vs. iteration (end)")
ax1.set_ylabel('Cost')            ;  ax2.set_ylabel('Cost')
ax1.set_xlabel('iteration step')  ;  ax2.set_xlabel('iteration step')
plt.show()

print(f"1000 sqft house prediction {w_final*1.0 + b_final:0.1f} Thousand dollars")
print(f"1200 sqft house prediction {w_final*1.2 + b_final:0.1f} Thousand dollars")
print(f"2000 sqft house prediction {w_final*2.0 + b_final:0.1f} Thousand dollars")

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值