本节为吴恩达教授机器学习课程笔记第三部分,广义线性模型(2)构建广义线性模型,包括最小均方算法、逻辑回归,着重介绍softmax的推导,并给出softmax的核心代码以及pytorch实现。

2. 构建GLMS广义线性模型

  考虑一个分类或者回归问题,我们希望得到一个x的函数,来计算随机变量y的值。为了推导出一个广义线性模型,我们给出这样三个假设:

  • 给定x和广义线性模型结果如何可视化 广义线性模型怎么做_线性回归,我们假定y的分布服从参数为广义线性模型结果如何可视化 广义线性模型怎么做_系数矩阵_02的某个指数族分布
  • 给定x,目标是预测广义线性模型结果如何可视化 广义线性模型怎么做_广义线性模型结果如何可视化_03的期望值,在绝大多数例子中,广义线性模型结果如何可视化 广义线性模型怎么做_机器学习_04,因此,我们想要预测广义线性模型结果如何可视化 广义线性模型怎么做_广义线性模型_05的值使得广义线性模型结果如何可视化 广义线性模型怎么做_系数矩阵_06
  • 自然参数和x是线性相关的,即广义线性模型结果如何可视化 广义线性模型怎么做_广义线性模型_07,对于向量来说,即广义线性模型结果如何可视化 广义线性模型怎么做_广义线性模型结果如何可视化_08
2.1 典型的最小均方算法

广义线性模型结果如何可视化 广义线性模型怎么做_系数矩阵_09,于是有下面的式子:

广义线性模型结果如何可视化 广义线性模型怎么做_线性回归_10

2.2 逻辑回归

  对于二分类问题,有:

广义线性模型结果如何可视化 广义线性模型怎么做_线性回归_11

2.3 Softmax回归

  考虑一个多分类问题,即模型有多个可能的输出对应多个不同的类别,我们可以用多项式分布来对该问题进行建模。

  首先,我们可以将多项式分布表达为指数族的形式。定义:

广义线性模型结果如何可视化 广义线性模型怎么做_广义线性模型_12


  即:

广义线性模型结果如何可视化 广义线性模型怎么做_线性回归_13


  这里,广义线性模型结果如何可视化 广义线性模型怎么做_线性回归_14是一个广义线性模型结果如何可视化 广义线性模型怎么做_广义线性模型_15维向量,用广义线性模型结果如何可视化 广义线性模型怎么做_广义线性模型_16表示向量广义线性模型结果如何可视化 广义线性模型怎么做_线性回归_14的第i个分量。

  此外引入一种特殊的定义,即1{广义线性模型结果如何可视化 广义线性模型怎么做_系数矩阵_18},如果它接受的参数为True,则输出1,参数为False,输出0。这样我们可将把y和新的广义线性模型结果如何可视化 广义线性模型怎么做_线性回归_14的关系写为:

广义线性模型结果如何可视化 广义线性模型怎么做_广义线性模型_20


  更进一步地,有:

广义线性模型结果如何可视化 广义线性模型怎么做_广义线性模型结果如何可视化_21


  接下来证明多项式分布确实属于指数族分布,我们有:

广义线性模型结果如何可视化 广义线性模型怎么做_系数矩阵_22


  对应地:

广义线性模型结果如何可视化 广义线性模型怎么做_广义线性模型_23


  于是有:

广义线性模型结果如何可视化 广义线性模型怎么做_线性回归_24


广义线性模型结果如何可视化 广义线性模型怎么做_线性回归_25


  这表明:

广义线性模型结果如何可视化 广义线性模型怎么做_线性回归_26


  从而得到:

广义线性模型结果如何可视化 广义线性模型怎么做_广义线性模型结果如何可视化_27


  这个将广义线性模型结果如何可视化 广义线性模型怎么做_系数矩阵_28映射为广义线性模型结果如何可视化 广义线性模型怎么做_系数矩阵_29的函数成为softmax函数,根据之前给出的假设3,有:

广义线性模型结果如何可视化 广义线性模型怎么做_机器学习_30


  这个多分类模型即softmax回归,是逻辑回归的推广,所以广义线性模型结果如何可视化 广义线性模型怎么做_线性回归_31会输出:

广义线性模型结果如何可视化 广义线性模型怎么做_广义线性模型_32


  换句话说,广义线性模型结果如何可视化 广义线性模型怎么做_线性回归_31将输出属于每一类的概率。

  最后我们来探讨参数拟合的问题,给出如下对数似然函数:

广义线性模型结果如何可视化 广义线性模型怎么做_广义线性模型结果如何可视化_34


  之后我们就可以用牛顿法或者梯度下降来最大化对数似然函数已得到参数值了。


softmax回归的核心代码

# softmax函数,将线性回归值转化为概率的激活函数。输入s要是行向量
def softmax(s):
    return np.exp(s) / np.sum(np.exp(s), axis=1)

# 逻辑回归中使用梯度下降法求回归系数。逻辑回归和线性回归中原理相同,只不过逻辑回归使用sigmoid作为迭代进化函数。因为逻辑回归是为了分类而生。线性回归为了预测而生
def gradAscent(dataMat, labelPMat):
    alpha = 0.2                                                        #移动步长,也就是学习速率,控制更新的幅度。
    maxCycles = 1000                                                      #最大迭代次数
    weights = np.ones((dataMat.shape[1],labelPMat.shape[1]))             #初始化权回归系数矩阵  系数矩阵的行数为特征矩阵的列数,系数矩阵的列数为分类数目
    for k in range(maxCycles):
        h =  softmax(dataMat*weights)                                #梯度上升矢量化公式,计算预测值(行向量)。每一个样本产生一个概率行向量
        error = h-labelPMat                                            #计算每一个样本预测值误差
        weights = weights - alpha * dataMat.T * error                   # 根据所有的样本产生的误差调整回归系数
    return weights                                                     # 将矩阵转换为数组,返回回归系数数组

pytorch实现

EPOCH = 5000
BATCH_SIZE = 100
LR = 0.01

train_set = Data.TensorDataset(x_train,y_train)
train_loader = Data.DataLoader(
            dataset=train_set,
            batch_size=BATCH_SIZE,
            shuffle=True
            )
            
net = nn.Sequential(
            nn.Linear(8,50),
            nn.ReLU(),
            nn.Linear(50,4)
            )
LOSS_FUNC = nn.CrossEntropyLoss() # 损失函数torch.nn.CrossEntropyLoss()中已经包含了Softmax函数
OPTIMIZER = torch.optim.SGD(net.parameters(), lr=LR)  

for epoch in range(1,EPOCH+1):
    loss_sum = 0.0
    for step,(x,y) in enumerate(train_loader):
        y_pred = net(x)
        y = y.squeeze() #修正标签格式
        loss = LOSS_FUNC(y_pred,y)
        loss_sum += loss
        OPTIMIZER.zero_grad()
        loss.backward()
        OPTIMIZER.step()
    print("epoch: %d, loss: %f" %(epoch,loss_sum/BATCH_SIZE))