MXNet学习——自定义工具包

目前正在看《动手学深度学习》 ,这里是书中建议的部分工具包内容,内容持续更新中……

# -------------------------------------------------------------------------------
# Description:  
# Reference:
# Author: Sophia
# Date:   2021/2/23
# -------------------------------------------------------------------------------
from IPython import display
from mxnet import autograd, nd, init, gluon
from mxnet.gluon import data as gdata, loss as gloss, nn
import random, sys, time, matplotlib.pyplot as plt, mxnet as mx, os


# 定义模型(线性回归)
def linear_regression(X, w, b):
    return nd.dot(X, w) + b


# 定义平方损失函数
def squared_loss(yhat, y):
    return (yhat - y.reshape(yhat.shape)) ** 2 / 2


# 用矢量图显示
def use_svg_display():  # SVG: 可缩放矢量图形(Scalable Vector Graphics)
    display.set_matplotlib_formats('svg')


# 设置图的尺寸
def set_figsize(figsize=(3.5, 2.5)):
    use_svg_display()
    plt.rcParams['figure.figsize'] = figsize


# 数值标签 -> 文本标签
def get_fashion_mnist_labels(labels):
    text_labels = ['t-shirt', 'trouser', 'pullover', 'dress', 'coat',
                   'sandal', 'shirt', 'sneaker', 'bag', 'ankle boot']
    return [text_labels[int(i)] for i in labels]


# 在一行中画出多张图像并表示出对应标签
def show_fashion_mnist(images, labels):
    use_svg_display()
    _, figs = plt.subplots(1, len(images), figsize=(10, 5))
    for f, img, lbl in zip(figs, images, labels):
        f.imshow(img.reshape((28, 28)).asnumpy())
        f.set_title(lbl)
        f.axes.get_xaxis().set_visible(False)
        f.axes.get_yaxis().set_visible(False)
    # plt.savefig('images/part_of_predict_res.png')
    plt.show()


def load_data_fashion_mnist(batch_size):
    # 下载 FashionMNIST 数据集
    mnist_train = gdata.vision.FashionMNIST(train=True)  # 每一类衣服有6000张图像,10类共有60000张
    mnist_test = gdata.vision.FashionMNIST(train=False)  # 每一类衣服有1000张图像,10类共有10000张
    transformer = gdata.vision.transforms.ToTensor()  # ToTensor实例可将最后一维的通道移到最前一位
    if sys.platform.startswith('win'):
        num_workers = 0  # 0表示不用额外的进程来加速读取数据
    else:
        num_workers = 4
    train_iter = gdata.DataLoader(mnist_train.transform_first(transformer), batch_size, shuffle=True,
                                  num_workers=num_workers)
    test_iter = gdata.DataLoader(mnist_test.transform_first(transformer), batch_size, shuffle=False,
                                 num_workers=num_workers)
    return train_iter, test_iter


'''
读取数据
mxnet.gluon.data.vision.transforms 模块提供了预定义的视觉转换&数据增强方法
gdata.vision.transforms.Resize:Resize an image or a batch of image NDArray to the given size.
gdata.vision.transforms.ToTensor:Converts an image NDArray or batch of image NDArray to a tensor NDArray.
gdata.vision.transforms.Compose:Sequentially composes multiple transforms,顺序地组成多个变换
'''


def load_data_fashion_mnist_ch5(batch_size, resize=None,
                                root=os.path.join('~', '.mxnet', 'datasets', 'fashion-mnist')):
    root = os.path.expanduser(root)  # expanduser 可将参数中开头部分的 ~ 或 ~user 替换为当前用户的home目录并返回
    transformer = []
    if resize:
        transformer += [gdata.vision.transforms.Resize(resize)]  #
    transformer += [gdata.vision.transforms.ToTensor()]
    transformer = gdata.vision.transforms.Compose(transformer)
    # mnist_train = gdata.vision.FashionMNIST(root=root, train=True)
    # mnist_test = gdata.vision.FashionMNIST(root=root, train=False)
    mnist_train = gdata.vision.FashionMNIST(train=True)
    mnist_test = gdata.vision.FashionMNIST(train=False)
    num_workers = 0 if sys.platform.startswith('win32') else 4
    train_iter = gdata.DataLoader(mnist_train.transform_first(transformer), batch_size, shuffle=True,
                                  num_workers=num_workers)
    test_iter = gdata.DataLoader(mnist_test.transform_first(transformer), batch_size, shuffle=False,
                                 num_workers=num_workers)
    return train_iter, test_iter


'''
SGD:stochastic gradient descent,随机梯度下降
'''


def SGD(params, lr, batch_size):
    for param in params:
        param[:] = param - lr * param.grad / batch_size


'''
计算分类准确率
'''


def accuracy(yhat, y):
    return (yhat.argmax(axis=1) == y.astype('float32')).mean().asscalar()


def evaluate_accuracy_ch3(data_iter, net):
    acc_sum = 0.0
    n = 0
    for X, y in data_iter:
        acc_sum += (net(X).argmax(axis=1) == y.astype('float32')).sum().asscalar()
        n += y.size
    return acc_sum / n


def evaluate_accuracy_ch5(data_iter, net, ctx):
    acc_sum = nd.array([0], ctx=ctx)
    n = 0
    for X, y in data_iter:
        X = X.as_in_context(ctx)
        y = y.as_in_context(ctx).astype('float32')
        acc_sum += (net(X).argmax(axis=1) == y).sum().asscalar()
        n += y.size
    return acc_sum / n


'''
训练模型
'''


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_loss = 0.0
        train_acc = 0.0
        n = 0
        for X, y in train_iter:
            with autograd.record():
                yhat = net(X)
                l = loss(yhat, y).sum()
            l.backward()
            if trainer is None:
                SGD(params, lr, batch_size)  # 将梯度做平均,这样学习率会对 batch_size 不那么敏感
            else:
                trainer.step(batch_size)  # 'softmax'回归的简单实现
            train_loss += l.asscalar()
            train_acc += (yhat.argmax(axis=1) == y.astype('float32')).sum().asscalar()
            n += y.size

        test_acc = evaluate_accuracy_ch3(test_iter, net)
        print('epoch %d, loss %.4f, train acc %.3f, test acc %.3f'
              % (epoch + 1, train_loss / n, train_acc / n, test_acc))


def train_ch5(net, train_iter, test_iter, batch_size, trainer, ctx, num_epochs):
    print('training on', ctx)
    loss = gloss.SoftmaxCrossEntropyLoss()
    for epoch in range(num_epochs):
        train_loss = 0.0
        train_acc = 0.0
        n = 0
        start = time.time()
        for X, y in train_iter:
            X, y = X.as_in_context(ctx), y.as_in_context(ctx)
            with autograd.record():
                yhat = net(X)
                l = loss(yhat, y).sum()
            l.backward()
            trainer.step(batch_size)  # 'softmax'回归的简单实现
            train_loss += l.asscalar()
            train_acc += (yhat.argmax(axis=1) == y.astype('float32')).sum().asscalar()
            n += y.size

        test_acc = evaluate_accuracy_ch5(test_iter, net, ctx)
        print('epoch %d, loss %.4f, train acc %.3f, test acc %.3f, time %.1f sec'
              % (epoch + 1, train_loss / n, train_acc / n, test_acc, time.time() - start))


'''
semilogy:轴半对数刻度曲线, y轴使用了对数尺度
'''


def semilogy(x_vals, y_vals, x_label, y_label, x2_vals=None, y2_vals=None, legend=None, figsize=(3.5, 2.5)):
    set_figsize(figsize)
    plt.xlabel(x_label)
    plt.ylabel(y_label)
    plt.semilogy(x_vals, y_vals)
    if x2_vals and y2_vals:
        plt.semilogy(x2_vals, y2_vals)
        plt.legend(legend)
    # plt.savefig('images/house_adaptive.png')
    plt.show()


'''
二维卷积运算
'''


def corr2d(X, K):  # K为核数组,X为输入数组
    h, w = K.shape
    Y = nd.zeros((X.shape[0] - h + 1, X.shape[1] - w + 1))  # 输出
    for i in range(Y.shape[0]):
        for j in range(Y.shape[1]):
            Y[i, j] = (X[i: i + h, j: j + w] * K).sum()
    return Y


'''
尝试使用 gpu 的代码
'''


def try_gpu():
    try:
        ctx = mx.gpu()
        _ = nd.zeros((1,), ctx=ctx)
    except mx.base.MXNetError:
        ctx = mx.cpu()
    return ctx

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

我有明珠一颗

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

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

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

打赏作者

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

抵扣说明:

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

余额充值