首页人工智能MXNet5.softmax回归的实...

5.softmax回归的实现

1.从零实现softmax回归:

import d2lzh as d2l
from mxnet import autograd,nd

# 读取数据集,并设置批量大小为256
batch_size = 256
train_iter,test_iter = d2l.load_data_fashion_mnist(batch_size)


# 初始化模型参数
num_inputs = 28*28
num_outputs = 1*10

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

# 为模型参数附上梯度
w.attach_grad()
b.attach_grad()


# 实现softmax运算
def softmax(X):
    X_exp = X.exp()
    partition = X_exp.sum(axis=1,keepdims=True)
    return X_exp / partition


# 定义模型
def net(X):
    return softmax(nd.dot(X.reshape((-1,num_inputs)),w) + b)


# 定义损失函数
def cross_entropy(y_hat,y):
    return -nd.pick(y_hat,y).log()


# 定义计算准确率函数
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


# 训练模型
num_epochs,lr = 10 , 0.1
def train_ch3(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:
                d2l.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("第{}轮,loss为{:.4f},train_acc为{:.3f},test_acc为{:.3f}".format(epoch+1 , train_l_sum/n , train_acc_sum/n , test_acc))

train_ch3(net,train_iter,test_iter,cross_entropy,num_epochs,batch_size,[w,b],lr)

迭代10轮得到如下结果:

第1轮,loss为0.7887,train_acc为0.747,test_acc为0.799
第2轮,loss为0.5727,train_acc为0.811,test_acc为0.819
第3轮,loss为0.5298,train_acc为0.825,test_acc为0.833
第4轮,loss为0.5051,train_acc为0.830,test_acc为0.839
第5轮,loss为0.4891,train_acc为0.834,test_acc为0.840
第6轮,loss为0.4779,train_acc为0.838,test_acc为0.841
第7轮,loss为0.4698,train_acc为0.840,test_acc为0.844
第8轮,loss为0.4618,train_acc为0.843,test_acc为0.845
第9轮,loss为0.4564,train_acc为0.843,test_acc为0.849
第10轮,loss为0.4513,train_acc为0.846,test_acc为0.848

2.softmax回归的简洁实现:

import d2lzh as d2l
from mxnet import gluon,init
from mxnet.gluon import loss as gloss , nn


# 读取数据集,并设置批量大小为256
batch_size = 256
train_iter,test_iter = d2l.load_data_fashion_mnist(batch_size)

# 定义和初始化模型
# 添加一个输出个数为10的全连接层,并使用均值为0、标准差为0.01的正态分布随机初始化模型的权重参数
net = nn.Sequential()
net.add(nn.Dense(10))
net.initialize(init.Normal(sigma=0.01))

# Gluon提供了一个包含softmax运算和交叉熵损失计算的函数,它的数值稳定性更好
loss = gloss.SoftmaxCrossEntropyLoss()

# 使用学习率为0.1的小批量随机梯度下降作为优化算法
trainer = gluon.Trainer(net.collect_params(),'sgd',{'learning_rate':0.1})

# 训练模型
num_epochs = 10
d2l.train_ch3(net,train_iter,test_iter,loss,num_epochs,batch_size,None,None,trainer)

迭代10轮得到如下结果:

epoch 1, loss 0.7891, train acc 0.746, test acc 0.802
epoch 2, loss 0.5750, train acc 0.810, test acc 0.825
epoch 3, loss 0.5289, train acc 0.824, test acc 0.831
epoch 4, loss 0.5058, train acc 0.830, test acc 0.837
epoch 5, loss 0.4898, train acc 0.835, test acc 0.841
epoch 6, loss 0.4785, train acc 0.838, test acc 0.842
epoch 7, loss 0.4698, train acc 0.841, test acc 0.846
epoch 8, loss 0.4628, train acc 0.843, test acc 0.847
epoch 9, loss 0.4565, train acc 0.845, test acc 0.849
epoch 10, loss 0.4517, train acc 0.846, test acc 0.849

Reference:
《动手学深度学习》

RELATED ARTICLES

欢迎留下您的宝贵建议

Please enter your comment!
Please enter your name here

- Advertisment -

Most Popular

Recent Comments