动手学深度学习(二、深度学习基础--softmax回归)

动手学深度学习(二、深度学习基础--softmax回归)

一、图像分类数据集(Fashion-MNIST)数据集获取

import torch
import torchvision
import torchvision.transforms as transforms
from IPython import display
import matplotlib.pyplot as plt
import time
import sys
#对于pytorch中的torchvision不甚了解
#对于matplotlib不甚了解
#对于get_fashion_mnist_labels方法尚不了解(迭代器遍历)

# sys.path.append("..")
# import d2lzh_pytorch as d2l
print("start")
mnist_train = torchvision.datasets.FashionMNIST(root='F:\数据\MRC\dataset', train=True, download=True, transform=transforms.ToTensor())
mnist_test = torchvision.datasets.FashionMNIST(root='F:\数据\MRC\dataset', train=False, download=True, transform=transforms.ToTensor())
print("end")
print(type(mnist_train))
print(len(mnist_train), len(mnist_test))

feature, label = mnist_train[1]
print(feature.shape, label)

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 use_svg_display():
    """Use svg format to display plot in jupyter"""
    display.set_matplotlib_formats('svg')
    
def show_fashion_mnist(images, labels):
    use_svg_display()
    _, figs = plt.subplots(1, len(images), figsize=(12, 12))
    for f, img, lbl in zip(figs, images, labels):
        f.imshow(img.view((28, 28)).numpy())
        f.set_title(lbl)
        f.axes.get_xaxis().set_visible(False)
        f.axes.get_yaxis().set_visible(False)
    plt.show()
    
X, y = [], []
for i in range(10):
    X.append(mnist_train[i][0])
    y.append(mnist_train[i][1])

show_fashion_mnist(X, get_fashion_mnist_labels(y))

batch_size = 256
if sys.platform.startswith('win'):
    num_workers = 0    #0表示不用额外的进程来加速读取数据
else:
    num_workers = 4

train_iter = torch.utils.data.DataLoader(mnist_train, batch_size=batch_size, shuffle=True, num_workers=num_workers)
test_iter = torch.utils.data.DataLoader(mnist_test, batch_size=batch_size, shuffle=False, num_workers=num_workers)
start
end
<class 'torchvision.datasets.mnist.FashionMNIST'>
60000 10000
torch.Size([1, 28, 28]) 0   图像size为1 * 28 * 28, 是C * H * W, 通道数 * 高 * 宽

二、Softmax回归从零开始实现

对于Python中迭代器的用法不甚了解, 对于训练后预测的内容也不了解代码

import torch
import torchvision
import numpy as np
import sys

sys.path.append("F:\数据\MRC\动手学深度学习\Dive-into-DL-PyTorch-master\code")
import d2lzh_pytorch as d2l

#1.获取数据
batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, resize = None, root = 'F:\数据\MRC\dataset')

#2.初始化模型参数
num_inputs = 784
num_outputs = 10
W = torch.tensor(np.random.normal(0, 0.01, (num_inputs, num_outputs)), dtype = torch.float)
b = torch.zeros(num_outputs, dtype = torch.float)

W.requires_grad_(requires_grad = True)
b.requires_grad_(requires_grad = True)

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

#4.定义模型
def net(X):
    return softmax(torch.mm(X.view((-1, num_inputs)), W) + b)

#定义损失函数
y_hat = torch.tensor([[0.1, 0.3, 0.6], [0.3, 0.2, 0.5]])
y = torch.LongTensor([0, 2])
print(y_hat.gather(1, y.view(-1, 1)))

def cross_entropy(y_hat, y):
    return - torch.log(y_hat.gather(1, y.view(-1, 1)))

#计算分类准确率
def accuracy(y_hat, y):
    return (y_hat.argmax(dim = 1) == y).float().mean().item()

print(accuracy(y_hat, y))

def evaluate_accuracy(data_iter, net):
    acc_sum, n = 0.0, 0
    for X, y in data_iter:
        acc_sum += (net(X).argmax(dim=1) == y).float().sum().item()
        n += y.shape[0]
    print(n)
    return acc_sum / n

print(evaluate_accuracy(test_iter, net))

num_epochs, lr = 10, 0.1
def train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size, 
              params = None, lr = None, optimizer = 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:
            y_hat = net(X)
            l = loss(y_hat, y).sum()
            
            #梯度清零
            if optimizer is not None:
                optimizer.zero_grad()
            elif params is not None and params[0].grad is not None:
                for param in params:
                    param.grad.data.zero_()
            
            l.backward()
            if optimizer is None:
                d2l.sgd(params, lr, batch_size)
            else:
                optimizer.step()
                
            train_l_sum += l.item()
            train_acc_sum += (y_hat.argmax(dim = 1) == y).sum().item()
            n += y.shape[0]
        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_ch3(net, train_iter, test_iter, cross_entropy, num_epochs, batch_size, [W, b], lr)
    
#对于预测部分的代码不甚了解
X, y = iter(test_iter).next()

true_labels = d2l.get_fashion_mnist_labels(y.numpy())
pred_labels = d2l.get_fashion_mnist_labels(net(X).argmax(dim=1).numpy())
titles = [true + '\n' + pred for true, pred in zip(true_labels, pred_labels)]

d2l.show_fashion_mnist(X[0:9], titles[0:9])
tensor([[0.1000],
        [0.5000]])
0.5
10000
0.107
10000
epoch 1, loss 0.7864, train acc 0.747, test acc 0.797
10000
epoch 2, loss 0.5711, train acc 0.812, test acc 0.809
10000
epoch 3, loss 0.5254, train acc 0.826, test acc 0.819
10000
epoch 4, loss 0.5013, train acc 0.832, test acc 0.822
10000
epoch 5, loss 0.4851, train acc 0.836, test acc 0.827
10000
epoch 6, loss 0.4735, train acc 0.841, test acc 0.826
10000
epoch 7, loss 0.4665, train acc 0.842, test acc 0.829
10000
epoch 8, loss 0.4579, train acc 0.845, test acc 0.832
10000
epoch 9, loss 0.4521, train acc 0.847, test acc 0.834
10000
epoch 10, loss 0.4476, train acc 0.848, test acc 0.834

三、Softmax回归简洁实现

import torch
from torch import nn
from torch.nn import init
import numpy as np
import sys
sys.path.append("F:\数据\MRC\动手学深度学习\Dive-into-DL-PyTorch-master\code")
import d2lzh_pytorch as d2l

#1.获取数据
batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, resize = None, root = 'F:\数据\MRC\dataset')

print(train_iter)

#2.定义初始化模型
num_inputs = 784
num_outputs = 10
class LinearNet(nn.Module):
    def __init__(self, num_inputs, num_outputs):
        super(LinearNet, self).__init__()
        self.linear = nn.Linear(num_inputs, num_outputs)
    def forward(self, x):
        y = self.linear(x.view(x.shape[0], -1))
        return y

net = LinearNet(num_inputs, num_outputs)
print(net)

# class FlattenLayer(nn.Module):
#     def __init__(self):
#         super(FlattenLayer, self).__init__()
#     def forward(self, x):
#         return x.view(x.shape[0], -1)

# from collections import OrderedDict

# net = nn.Sequential(
    
#     OrderedDict([
#         ('flatten', FlattenLayer()),
#         ('linear', nn.Linear(num_inputs, num_outputs))
#     ])
# )

init.normal_(net.linear.weight, mean = 0, std = 0.01)
init.constant_(net.linear.bias, val = 0)

#3.softmax和交叉熵损失函数
loss = nn.CrossEntropyLoss()

#4.定义优化算法
optimizer = torch.optim.SGD(net.parameters(), lr = 0.1)

num_epochs = 5
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size, None, None, optimizer)
<torch.utils.data.dataloader.DataLoader object at 0x000001A38AD5A580>
LinearNet(
  (linear): Linear(in_features=784, out_features=10, bias=True)
)
epoch 1, loss 0.0031, train acc 0.751, test acc 0.789
epoch 2, loss 0.0022, train acc 0.812, test acc 0.800
epoch 3, loss 0.0021, train acc 0.826, test acc 0.811
epoch 4, loss 0.0020, train acc 0.833, test acc 0.817
epoch 5, loss 0.0019, train acc 0.837, test acc 0.826

定义完网络结构后, 通过调用网络结构进行模型训练

猜你喜欢

转载自blog.csdn.net/jiangchao98/article/details/115047453