softmax回归的从零开始实现

softmax回归的从零开始实现

# 导入包或模块
%matplotlib inline
from utils import load_data_fashion_mnist
from mxnet import autograd, nd

1. 获取和读取数据

# 使用Fashion-MNIST数据集,并设置批量大小为256
batch_size = 256
train_iter, test_iter = load_data_fashion_mnist(batch_size)

2. 初始化模型参数

已知每个样本输⼊是⾼和宽均为28像素的图像。模型的输⼊向量的⻓度是28 × 28 = 784:该向量的每个元素对应图像中每个像素。由于图像有10个类别,单层神经⽹络输出层的输出个数为10,因此softmax回归的权重和偏差参数分别为784 × 10和1 × 10的矩阵。

num_inputs = 784 # 输入维数
num_outputs = 10 # 输出类别数

W = nd.random.normal(scale=0.01, shape=(num_inputs, num_outputs))
b = nd.zeros(num_outputs)

# 附上梯度
W.attach_grad()
b.attach_grad()

3. 实现softmax运算

给定⼀个NDArray矩阵X。我们可以只对其中同⼀列(axis=0)或同⼀⾏(axis=1)的元素求和,并在结果中保留⾏和列这两个维度(keepdims=True)。

在下⾯的函数中,矩阵X的⾏数是样本数,列数是输出个数。为了表达样本预测各个输出的概率,softmax运算会先通过exp函数对每个元素做指数运算,再对exp矩阵同⾏元素求和,最后令矩阵每⾏各元素与该⾏元素之和相除。这样⼀来,最终得到的矩阵每⾏元素和为1且⾮负。因此,该矩阵每⾏都是合法的概率分布。softmax运算的输出矩阵中的任意⼀行元素代表了⼀个样本在各个输出类别上的预测概率

# 对于输⼊,将每个元素变成了⾮负数,且每⼀⾏和为1。
def softmax(X):
    X_exp = X.exp()
    partition = X_exp.sum(axis=1, keepdims=True)
    return X_exp / partition # 应用广播机制

4. 定义模型

有了softmax运算,我们可以定义上节描述的softmax回归模型了。这⾥通过reshape函数将每张原始图像改成⻓度为num_inputs的向量。

def net(X):
    return softmax(nd.dot(X.reshape((-1, num_inputs)), W) + b)

5. 定义损失函数

为了得到标签的预测概率,我们可以使⽤pick函数。

y_hat = nd.array([[0.1, 0.3, 0.6], [0.3, 0.2, 0.5]])
y = nd.array([0, 2], dtype='int32')
nd.pick(y_hat, y)


[0.1 0.5]
<NDArray 2 @cpu(0)>

def cross_entropy(y_hat, y):
    return -nd.pick(y_hat, y).log()

6. 计算分类准确率

为了演示准确率的计算,下⾯定义准确率accuracy函数。其中y_hat.argmax(axis=1)返回矩阵y_hat每⾏中最大元素的索引,且返回结果与变量y形状相同。相等条件判断式(y_hat.argmax(axis=1) == y)是⼀个值为0(相等为假)或1(相等为真)的NDArray。由于标签类型为整数,我们先将变量y变换为浮点数再进⾏相等条件判断。

def accuracy(y_hat, y):
    return (y_hat.argmax(axis=1) == y.astype('float32')).mean().asscalar()
# 预测准确率
accuracy(y_hat, y)
0.5
# 模型net在数据集data_iter上的准确率
def evaluate_accuracy(data_iter, net):
    acc_sum, n = 0.0, 0
    for X, y in data_iter:
        y = y.astype('float32')
        acc_sum += (net(X).argmax(axis=1) == y).sum().asscalar()
        n += y.size
    return acc_sum / n
evaluate_accuracy(test_iter, net)
0.0856

7. 训练模型

在训练模型时,迭代周期数num_epochs和学习率lr都是可以调的超参数。改变它们的值可能会得到分类更准确的模型。

from utils import sgd
num_epochs, lr = 6, 0.01
def train_softmax(net, train_iter, test_iter, loss, num_epochs, batch_size, params=None, lr=None, trainer=None):
    for epoch in range(num_epochs):
        train_l_sum, train_acc_sum, n = 0.0, 0.0, 0
        for X, y in train_iter:
            with autograd.record():
                y_hat = net(X)
                l = loss(y_hat, y).sum()
            l.backward()
            if trainer is None:
                sgd(params, lr, batch_size)
            else:
                trainer.step(batch_size)
            y = y.astype('float32')
            train_l_sum += l.asscalar()
            train_acc_sum += (y_hat.argmax(axis=1) == y).sum().asscalar()
            n += y.size
            test_acc = evaluate_accuracy(test_iter, net)
        print('epoch %d, loss %.4f, train acc %.3f, test acc %.3f'% (epoch + 1, train_l_sum / n, train_acc_sum / n, test_acc))
            
train_softmax(net, train_iter, test_iter, cross_entropy, num_epochs, batch_size, [W, b], lr)
epoch 1, loss 1.3704, train acc 0.633, test acc 0.692
epoch 2, loss 0.9199, train acc 0.714, test acc 0.736
epoch 3, loss 0.8060, train acc 0.747, test acc 0.759
epoch 4, loss 0.7455, train acc 0.765, test acc 0.771
epoch 5, loss 0.7059, train acc 0.777, test acc 0.783
epoch 6, loss 0.6770, train acc 0.786, test acc 0.791

8. 预测

给定⼀系列图像(第三行图像输出),我们⽐较⼀下它们的真实标签(第⼀行⽂本输出)和模型预测结果(第二行文本输出)。

from utils import get_fashion_mnist_labels, show_fashion_mnist
for X, y in test_iter:
    break
true_labels = get_fashion_mnist_labels(y.asnumpy())
pred_labels = get_fashion_mnist_labels(net(X).argmax(axis=1).asnumpy())
titles = [true + '\n' + pred for true, pred in zip(true_labels, pred_labels)]

show_fashion_mnist(X[0:10], titles[0:10])


在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
softmax回归从零开始的实现可以分为以下几个步骤: 1. 获取并读取数据:首先,我们需要获取训练数据集和测试数据集。然后,我们可以通过数据加载器将数据集转换为可供模型使用的张量格式。 2. 初始化模型参数:我们需要定义模型的参数,其中包括权重矩阵w和偏置向量b,并将它们初始化为随机值。 3. 定义模型:softmax回归的模型可以表示为线性变换和softmax操作的组合。我们可以使用矩阵乘法和加法运算来实现线性变换,并使用softmax函数将输出转换为概率分布。 4. 定义损失函数:softmax回归使用交叉熵损失函数来衡量预测结果与真实标签之间的差异。交叉熵损失函数可以通过计算预测概率分布和真实标签的对数似然来得到。 5. 定义优化算法:我们可以使用梯度下降算法来最小化损失函数。梯度下降算法的核心思想是通过计算损失函数关于模型参数的梯度来更新参数的值。 6. 训练模型:在训练过程中,我们需要将输入数据传递给模型,计算预测结果,并根据损失函数的值来更新模型参数。这个过程可以通过多次迭代来完成。 以下是一个伪代码示例: ``` # 步骤1:获取并读取数据 data_loader = DataLoader(...) train_data, test_data = data_loader.load_data(...) # 步骤2:初始化模型参数 w = torch.randn(...) b = torch.zeros(...) # 步骤3:定义模型 def model(X): return softmax(torch.matmul(X, w) + b) # 步骤4:定义损失函数 def loss(y_hat, y): return cross_entropy(y_hat, y) # 步骤5:定义优化算法 def optimize(params, lr): params -= lr * params.grad # 步骤6:训练模型 for epoch in range(num_epochs): for X, y in train_data: # 前向传播 y_hat = model(X) # 计算损失 l = loss(y_hat, y) # 反向传播 l.backward() # 更新参数 optimize([w, b], lr) # 清零梯度 w.grad.zero_() b.grad.zero_() # 相关问题:

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DeeGLMath

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值