zoukankan      html  css  js  c++  java
  • 机器学习线性回归

    假设对于数据集\(D=\{(x_{1},y_{1}),\cdots,(x_{N},y_{N})\}\),然后定义矩阵\(X\)如下

    \[\mathbf{X} = \left[ \begin{matrix}x_{11}&\cdots&x_{1p}\\\vdots & \cdots & \vdots\\x_{N1} & \cdots & x_{Np}\end{matrix}\right ]=[\mathbf{x}_{1},\cdots,\mathbf{x}_{N}]^T \]

    以及输出矩阵\(Y\)

    \[\mathbf{Y}=\left [ \begin{matrix}y_{1}\\y_{2}\\\vdots\\y_{N}\end{matrix}\right ] \]

    那么对于模型\(f(w)=\mathbf{w}^Tx\)而言,基于上面的数据集,结合最小二乘法可以得到加权系数\(\mathbf{w}\)的值。首先定义损失函数

    \[\ell({\mathbf{w}})=\sum_{n=1}^{N}\lvert \lvert \mathbf{w}^Tx_i-y_{i}\rvert\rvert^2\\=\sum_{n=1}^{N}({\mathbf{w}^Tx_i-y_{i})}^2 \]

    进而可以将\(\ell({\mathbf{w}})\)表示成

    \[\ell(\mathbf{w})=(\,\mathbf{w}^T\mathbf{x}_{1}-y_{1},\cdots,\mathbf{w}^T\mathbf{x}_{N}-y_{N})\left (\begin{matrix} \mathbf{w}^T\mathbf{x}_{1}-y_{1}\\\mathbf{w}^T\mathbf{x}_{2}-y_{2} \\\vdots\\ \mathbf{w}^T\mathbf{x}_{N}-y_{N} \end{matrix}\right )\\ \]

    对上式进行化简整理得到

    \[\ell(\mathbf{w})=(\mathbf{w}^T\mathbf{X}^T-\mathbf{Y}^T)(\mathbf{Xw-Y})\\=\mathbf{w^TX^TXw-2w^TX^TY+Y^TY}\\ \]

    \(\ell({\mathbf{w}})\)\(\mathbf{w}\)求导,可以得到

    \[\frac{\partial{\ell({\mathbf{w}})}}{\partial\mathbf{w}}=\mathbf{2X^T Xw-2X^TY}=0 \]

    从而可以得到

    \[\mathbf{w}=\mathbf{(X^TX)^{-1}X^TY} \]

    另外从概率角度分析,假设噪声\(\epsilon\)服从均值为0,方差为\(\sigma^2\)的高斯分布,定义

    \[y=f(\mathbf{w})+\epsilon \]

    那么\(y\)将服从均值为\(\mathbf{w}^Tx\),方差为\(\sigma^2\)的高斯分布。另外定义损失函数

    \[\ell_{p}(\mathbf{w})=log\Pi_{n=1}^{N}p(y_{i}|x_{i};\mathbf{w})=\sum_{n=1}^{N}log p(y_{i}|x_i;\mathbf{w})\\=\sum_{n=1}^{N}(log(\frac{1}{\sqrt{2\pi}})+log\frac{1}{\sigma}-\frac{(y_i-\mathbf{w}^Tx_{i})^2}{2\sigma^2}) \]

    那么参数\(\hat{\mathbf{w}}\)可以用如下的公式进行估计

    \[\hat{\mathbf{w}}=argmax\ell_{p}(\mathbf{w})\\=argmin(y_i-\mathbf{w}^Tx_{i})^2 \]

    接下来求取\(\hat{\mathbf{w}}\)的步骤就和上面的最小二乘法一样。结合推导过程可以得到,利用最小二乘法计算权重使用了噪声服从高斯分布这个前提。

    可以看到\(\hat{\mathbf{w}}\)的求取涉及到了逆矩阵求解,为了保证逆存在,因此引入正则化是有必要的。正则化主要有两种正则化:\(\ell_{1}\)正则化和\(\ell_{2}\)正则化。两者的区别在于加入的正则项不一样。引入\(\ell_{2}\)正则化,此时可以得到损失函数为

    \[\ell({\mathbf{w}})=\sum_{n=1}^{N}\lvert\lvert\mathbf{w}^Tx_{i}-y_{i}\rvert\rvert^2+\alpha\lvert\lvert\mathbf{w}\rvert\rvert^2 \]

    可以得到此时的权重为

    \[\hat{\mathbf{w}}_{r}=\mathbf{(X^TX+\alpha I)^{-1}X^TY} \]

    从而保证矩阵的求逆能够正确进行。

    import torch
    from matplotlib import pyplot as plt
    import numpy as np
    import torch.nn
    from torch.nn import init
    import torch.optim as optim
    
    num_inputs = 2
    num_examples = 1000
    true_w = [2, -4.3]
    true_b = 3.5
    features = torch.randn(num_examples, num_inputs, dtype=torch.float32)
    labels = true_w[0] * features[:, 0] + true_w[1] * features[:, 1] + true_b
    labels += torch.tensor(np.random.normal(0, 0.01, size=labels.size()), dtype=torch.float32)
    
    # plt.plot(x_data, y_data, 'ro', label='Origin Data')
    # plt.show()
    batch_size = 10
    dataset = torch.utils.data.TensorDataset(features, labels)
    # 随机读取小批量
    data_iter = torch.utils.data.DataLoader(dataset, batch_size, shuffle=True)
    # 定义模型参数
    num_inputs = 2
    # 第一种定义网络结构
    # net = torch.nn.Sequential()
    # net.add_module('linear', torch.nn.Linear(num_inputs, 1))
    # 第二种定义网络结构
    class LinearNet(torch.nn.Module):
        def __init__(self, n_feature):
            super(LinearNet, self).__init__()
            self.linear = torch.nn.Linear(n_feature, 1)
        def forward(self, x):
            out = self.linear(x)
            return out
    net = LinearNet(num_inputs)
    # print(net)
    # 初始化模型参数
    
    
    init.normal_(net.linear.weight, mean=0, std=0.01)
    init.constant_(net.linear.bias, val=0)
    # 损失函数
    loss = torch.nn.MSELoss()
    # 定义优化算法
    
    optimizer = optim.SGD(net.parameters(), lr = 0.03)
    
    # 训练模型
    num_epochs = 3
    for epoch in range(1, num_epochs + 1):
        for X, y in data_iter:
            output = net(X)
            l = loss(output, y.view(-1, 1))
            optimizer.zero_grad()
            l.backward()
            optimizer.step()
        print('epoch %d, loss: %f' % (epoch, l.item()))
    print(true_w, net.linear.weight)
    print(true_b, net.linear.bias)
    
    

    结果如下

    epoch 1, loss: 0.000542
    epoch 2, loss: 0.000167
    epoch 3, loss: 0.000069
    [2, -4.3] Parameter containing:
    tensor([[ 1.9995, -4.3000]], requires_grad=True)
    3.5 Parameter containing:
    tensor([3.5006], requires_grad=True)
    
  • 相关阅读:
    json schema相关
    好看的记录片和电影
    java函数局部变量的坑(非常隐藏)
    maven操作
    Js数组的常用的方法概述
    深入理解JS各种this指向问题
    浅谈ES5和ES6继承和区别
    vue
    使用 vue-i18n 切换中英文
    js_数组对象的浅克隆
  • 原文地址:https://www.cnblogs.com/tingweichen/p/12731615.html
Copyright © 2011-2022 走看看