目前正在看《动手学深度学习》 ,这里是书中建议的部分工具包内容,内容持续更新中……
# -------------------------------------------------------------------------------
# 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