TF-char2-回归问题

2021-03-02 16:16:34 浏览数 (2)

char2-回归问题

主要介绍的知识点包含:

  • 神经知识简介
  • 基于梯度下降法的优化
  • 利用梯度下降发求解线性模型
  • 回归问题小结及应用

神经元模型

介绍神经元

每个神经元通过树突获取输入信号,通过轴 突传递输出信号,神经元之间相互连接构成了巨大的神经网络,从而形成了人脑的感知和 意识基础。

  • 典型的神经元结构模型
  • 模拟神经元机制的人工神经网络的数学模型
具体解释

将神经元模型抽象成数学结构:

  • 神经元输入向量x=[x_1,…,x_n]^T
  • 经过函数f_theta:x rightarrow y进行映射得到输出y
  • theta为函数f自身的参数
  • theta:={w_1,…,w_n,b}确定了神经元的状态;通过固定?参数即可确定此神经 元的处理逻辑

上面有个简单的线性模型:

f(x)=w^Tx b
f(x) = w_1x_1 w_2x_2 …w_nx_n b
单输入问题

当仅仅只有一个节点的时候,神经元模型简化为

y=wx b
  • w为直线的斜率slope
  • b为直线的偏置bias

带有误差的估计模型

的正态分布,即采样本符合:

y=wx b epsilon,epsilon-N(mu,sigma^2)

求出当前模型的采样点上的预测值和真实值之间的的差的平方和作为总误差L

L(w,b) = frac{1}{n}sumn_{i=1}(wx{(i)} b-y{(i)})2

找出一组参数w,b使得L最小:

w*,b* = arg min frac{1}{n}sumn_{i=1}(wx{(i)} b-y{(i)})2

上述方法称之为均方误差MSE,mean squared error

优化方法

梯度下降法

解析解:经过严格公式推导得到的结果

数值解:数据量大的情况下,可能无法得到解析解,借助数值优化的方法得到近似的数值解。

梯度的定义:函数对各个自变量的偏导数组成的向量

  • 红色箭头表示梯度向量的模
  • 箭头的方向是梯度向量的方向,函数值增速最快的方向
  • 函数曲面越陡峭,箭头越长,梯度的模越大
  • 指向函数值减小的方向
x^=x-eta cdot triangledown f

通过上式来不断地迭代更新

代价函数是均方误差函数

系数求解
L(w,b) = frac{1}{n}sumn_{i=1}(wx{(i)} b-y{(i)})2
w^` := w -eta frac{partial L}{partial w}
b^` := b -eta frac{partial L}{partial w}

不断循环地迭代更新参数。

线性模型实例-demo

  • 样例符合y=1.477*x 0.089,误差自变量epsilon采样自均值为0,方差为0.01的高斯分布:
y=1.477*x 0.089 epsilon,epsilon-N(0,0.01)
  • 通过采样100次,获得训练数据
采样数据
代码语言:javascript复制
import numpy as np
import tensorflow as tf

data = []  # 存放样本数据的列表
for i in range(100):
  x = np.random.uniform(-10, 10)  # 随机采样输入x
  eps = np.random.normal(0., 0.1)  # 采样高斯噪声
  y = 1.477 * x   0.089   eps  # 模型的输出

  data.append([x,y])  # 保存样本点

data = np.array(data)  # 全部采样完成之后,将数据转成Numpy数据
  • 循环100次
  • 每次从区间[-100,100]的均匀分区U[0,1]随机采样一个数据x
  • 高斯分布中采样噪声epsilon
  • 根据真实模型生成数据y,并保存为numpy数组
计算误差
代码语言:javascript复制
def mse(b,w,points):
  # 计算均方误差MSE
  totalError = 0
  # 循环迭代所有的点
  for i in range(0, len(points)):
    # 怎么从array中取出值
    x = points[i, 0]   # 获取第i号点的输入x
    y = points[i, 1]  #  获取输入y

    # 计算差的平方,再累加
    totalError  = (y - (w * x   b)) ** 2
    # 将累加的误差求平均,得到均方误差
   return totalError / float(len(points))
计算梯度

关于代价函数对两个参数的梯度,就是一个求导的过程,很简单:

L(w,b) = frac{1}{n}sumn_{i=1}(wx{(i)} b-y{(i)})2

求出来的结果为:

frac {partial L}{partial w} = frac{2}{n}sumn_{i=1}(wx{(i)} b-y^{(i)})cdot x^{(i)}
frac {partial L}{partial b} = frac{2}{n}sumn_{i=1}(wx{(i)} b-y^{(i)})
代码语言:javascript复制
def step_gradient(b_current, w_current, points, lr):
  """
  计算梯度函数

  b_current:目前b的值
  w_current:目前w的值
  points:总样本数据集
  lr: 学习率
  """
  b_gradient = 0
  w_gradient = 0
  M = float(len(points))  # 总样本数

  for i in range(0, len(points)):
    x = points[i, 0]
    y = points[i, 1]
    # 参考公式进行更新
    b_gradient  = (2/M) * ((w_current * x   b_current) - y)
    w_gradient  = (2/M) * x * ((w_current * x   b_current)-y)

  # 更新两个系数
  new_b = b_current - (lr * b_gradient)
  new_w = w_current - (lr * w_gradient)
  return [new_b,  new_w]
梯度更新
代码语言:javascript复制
def gradient_descent(points, starting_b, starting_w, lr, num_iterations):
  """
  梯度下降函数
  points:数据集
  starting_b, starting_w:两个参数的初始值
  lr:学习率
  num_iterations:迭代次数
  """
  b = starting_b
  w = starting_w

  for step in range(num_iterations):
    # 梯度下降函数,计算梯度,并且更新一次
    b, w = step_gradient(b, w, np.array(points), lr)
    # 求均方误差函数
    loss = mse(b, w, points)
    if step % 50 ==0:
      # 打印误差和实时 w,b 值
      print(f"iteration:{step}, loss:{loss}, w:{w}m b:{b}")
    return [b, w]  # 返回最后一次的w,b

def main():
  lr = 0.01
  # 初始化参数
  initial_b = 0
  initial_w = 0
  num_iterations = 1000
  [b,w,losses = gradient_descent(data, initial_b, initial_w, lr, num_iterations)]
  loss = mse(b,w,data)  # 计算最优数值解上的均方误差mse
  print(f'Fianl loss:{loss}, w:{w}, b:{b}')

对于复杂的线性模型,通过梯度下降算法求解得到的w,b可能是局部最小值而不是全局最小值。

总结

上面的栗子可以理解为一组连续值(向量)的预测问 题。

  • 给定数据集?,我们需要从?中学习到数据的真实模型,从而预测未见过的样本的输出值。
  • 在假定模型的类型后,学习过程就变成了搜索模型参数的问题
  • 对于任意的x输入,使用学习模型输出值作为真实值的近似

上述问题是属于连续性预测问题,这类问题属于回归问题

应用
  • 股票的走势问题
  • 天气预报中温度和湿度的预测
  • 年龄预测
  • 交通流量的预测

0 人点赞