python 实现的 softmax regression

softmax regression

  让我们来手写一个 s o f t m a x      r e g r e s s i o n softmax \;\; regression softmaxregression 吧qwq

  最开始的,还是老样子,一堆import:

# coding = utf-8

from mxnet import gluon
from mxnet import ndarray as nd
import matplotlib.pyplot as plt
from mxnet import nd
from mxnet import autograd

1. load 数据

  首先,我们训练的数据来自一个叫 M N I S T MNIST MNIST 的数据集。

M N I S T MNIST MNIST 数据集是一个广泛使用的手写数字识别基准数据集,它包含 60000 60000 60000 个训练样本和 10000 10000 10000 个测试样本。每个样本都是一个 28 × 28 28 \times 28 28×28 像素大小的灰度图像,代表了从 0 0 0 9 9 9 的一个数字。 M N I S T MNIST MNIST 数据集非常适合用来评估机器学习算法的性能,特别是用于图像识别任务的深度学习模型。

  这里我们这样 load 数据:

mnist_train = gluon.data.vision.FashionMNIST(train = True, transform = transform)
mnist_test  = gluon.data.vision.FashionMNIST(train = True, transform = transform)
# Load 数据
batch_size = 256
train_data = gluon.data.DataLoader(mnist_train, batch_size, shuffle = True)
test_data  = gluon.data.DataLoader(mnist_test,  batch_size, shuffle = False)

  然后我们为了方便,把所有数据的类型全都改成 f l o a t 32 float32 float32

def transform(data, label):                                                              # 把图片转成矩阵的函数
    return data.astype('float32')/255, label.astype('float32')

2. 模型定义

  很简单的模型,就只有一层 D e n s e      l a y e r Dense \;\; layer Denselayer

net = nn.Sequential()
with net.name_scope():
    net.add(nn.Dense(10))
net.initialize()

  然后就是一些函数:

softmax_cross_entropy = gluon.loss.SoftmaxCrossEntropyLoss()
trainer = gluon.Trainer(net.collect_params(), 'sgd', {'learning_rate' : lr})

def accuracy(output, label):                                                     # 计算拟合的准确度
    return nd.mean(output.argmax(axis = 1) == label).asscalar()                  # argmax是把每一列的最大概率的index返回出来 然后和label比较是否相同 最后所有求个mean

def evaluate_accuracy(data_itetator, net):
    acc = 0.
    for data, label in data_itetator:
        output = net(data)
        acc += accuracy(output, label)
    return acc / len(data_itetator)

  这里的 s o f t m a x _ c r o s s _ e n t r o p y softmax\_cross\_entropy softmax_cross_entropy 就是 g l u o n gluon gluon 里面帮你实现好的 s o f t m a x softmax softmax 的损失函数, t r a i n e r trainer trainer 就是 s g d sgd sgd 的训练器,在后面要用到 s g d sgd sgd 的时候就这样调用就可以了:

trainer.step(batch_size)                           # 向下山的放下走一步

  然后这个 a c c u r a c y accuracy accuracy 就是我注释里面说的那样,把每一列的最大值(也就是最大概率是的那个物体)的下标返回出来,然后跟 l a b e l label label 比较是否相同,最后求个 m e s n mesn mesn。这个函数大概就能反应我们预测的准确程度。

  最后是 e v a l u a t e _ a c c u r a c y evaluate\_accuracy evaluate_accuracy,这个函数是用来看我们现在的 p a r a m e t e r s parameters parameters t e s t _ d a t a test\_data test_data 的预测准确度的。具体代码很好懂,这里就不作解释了。

3. 开始训练

  然后就是训练了,跟 l i n e a r      r e g r e s s i o n linear \;\; regression linearregression 的训练没啥区别:

for epoch in range(num_epoch):
    train_loss, train_acc = 0., 0.
    for data, label in train_data:
        with autograd.record():
            out = net(data)
            loss = softmax_cross_entropy(out, label)
        loss.backward()
        trainer.step(batch_size)                                            # 做一次 sgd
        train_loss += nd.mean(loss).asscalar()
        train_acc += accuracy(out, label)
    test_acc = evaluate_accuracy(test_data, net)
    print("Epoch %d. Loss : %f, Train acc : %f, Test acc : %f" % 
                (epoch, train_loss / len(train_data), train_acc / len(train_data), test_acc))

  跑完之后输出如下:

Epoch 0. Loss : 0.797578, Train acc : 0.740930, Test acc : 0.804422
Epoch 1. Loss : 0.575026, Train acc : 0.810511, Test acc : 0.820612
Epoch 2. Loss : 0.531063, Train acc : 0.822396, Test acc : 0.822972
Epoch 3. Loss : 0.506821, Train acc : 0.829566, Test acc : 0.835455
Epoch 4. Loss : 0.491926, Train acc : 0.833500, Test acc : 0.833051
Epoch 5. Loss : 0.479950, Train acc : 0.836353, Test acc : 0.836464
Epoch 6. Loss : 0.470627, Train acc : 0.839905, Test acc : 0.840764
Epoch 7. Loss : 0.463425, Train acc : 0.841866, Test acc : 0.845739
Epoch 8. Loss : 0.457521, Train acc : 0.843983, Test acc : 0.846371
Epoch 9. Loss : 0.451265, Train acc : 0.846077, Test acc : 0.845152

  光有这些数据看着还是有些抽象了,我们试试把一些具体的数据打印出来看看:

data, label = mnist_test[0 : 19]
print("true labels")
print(get_text_labels(label))
predicted_labels = net(data).argmax(axis = 1)
print("predicted labels")
print(get_text_labels(predicted_labels.asnumpy()))

  输出就是这样:

true labels
['pullover', 'ankle boot', 'shirt', 't-shirt', 'dress', 'coat', 'coat', 'sandal', 'coat', 'bag', 't-shirt', 'bag', 'ankle boot', 't-shirt', 'pullover', 'pullover', 'ankle boot', 'dress', 'dress']
predicted labels
['bag', 'sneaker', 'shirt', 't-shirt', 'dress', 'shirt', 'coat', 'sandal', 'coat', 'bag', 't-shirt', 'bag', 'ankle boot', 't-shirt', 'pullover', 'shirt', 'ankle boot', 'dress', 't-shirt']

  这样我们就能对照着看看我们预测的效果了。

  完整代码如下:

# coding = utf-8

from mxnet import gluon
from mxnet.gluon import nn
from d2l import mxnet as d2l
from mxnet import autograd, nd
import matplotlib.pyplot as plt

def transform(data, label):                                                              # 把图片转成矩阵的函数
    return data.astype('float32') / 255, label.astype('float32')
mnist_train = gluon.data.vision.FashionMNIST(train = True, transform = transform)
mnist_test  = gluon.data.vision.FashionMNIST(train = True, transform = transform)

def show_images(images):
    n = images.shape[0]
    _, figs = plt.subplots(1, n, figsize = (15, 15))
    for i in range(n):
        figs[i].imshow(images[i].reshape((28, 28)).asnumpy())
        figs[i].axes.get_xaxis().set_visible(False)
        figs[i].axes.get_yaxis().set_visible(False)
    plt.show()

def get_text_labels(label):
    text_labels = [ 't-shirt', 'trouser', 'pullover', 'dress', 'coat',
                    'sandal', 'shirt', 'sneaker', 'bag', 'ankle boot' ]
    return [text_labels[int(i)] for i in label]

# 试试show_images的效果
# data, label = mnist_train[0 : 9]
# print(get_text_labels(label))
# show_images(data)

# Load 数据
batch_size, num_epoch, lr = 256, 10, 0.1
train_data = gluon.data.DataLoader(mnist_train, batch_size, shuffle = True)
test_data  = gluon.data.DataLoader(mnist_test,  batch_size, shuffle = False)

net = nn.Sequential()
with net.name_scope():
    net.add(nn.Dense(10))
net.initialize()

softmax_cross_entropy = gluon.loss.SoftmaxCrossEntropyLoss()
trainer = gluon.Trainer(net.collect_params(), 'sgd', {'learning_rate' : lr})

def accuracy(output, label):                                                     # 计算拟合的准确度
    return nd.mean(output.argmax(axis = 1) == label).asscalar()                  # argmax是把每一列的最大概率的index返回出来 然后和label比较是否相同 最后所有求个mean

def evaluate_accuracy(data_itetator, net):
    acc = 0.
    for data, label in data_itetator:
        output = net(data)
        acc += accuracy(output, label)
    return acc / len(data_itetator)

for epoch in range(num_epoch):
    train_loss, train_acc = 0., 0.
    for data, label in train_data:
        with autograd.record():
            out = net(data)
            loss = softmax_cross_entropy(out, label)
        loss.backward()
        trainer.step(batch_size)
        train_loss += nd.mean(loss).asscalar()
        train_acc += accuracy(out, label)
    test_acc = evaluate_accuracy(test_data, net)
    print("Epoch %d. Loss : %f, Train acc : %f, Test acc : %f" % 
                (epoch, train_loss / len(train_data), train_acc / len(train_data), test_acc))
    
data, label = mnist_test[0 : 19]
print("true labels")
print(get_text_labels(label))
predicted_labels = net(data).argmax(axis = 1)
print("predicted labels")
print(get_text_labels(predicted_labels.asnumpy()))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值