4.6.0 头文件

 

import torch
from torch import nn
from d2l import torch as d2l
from matplotlib import pyplot as plt

 

 

 

4.6.1 定义dropout层

 

def dropout_layer(X, dropout):
    assert 0 <= dropout <= 1
    # 在本情况中,所有元素都被丢弃(置0)
    if dropout == 1:
        return torch.zeros_like(X)
    # 在本情况中,所有元素都被保留(不变)
    if dropout == 0:
        return X

    # 生成一个随机矩阵和掩码矩阵,如果随机值大于dropout就置1,否则置0
    mask = (torch.rand(X.shape) > dropout).float()
    return mask * X / (1.0 - dropout)

# 定义一个张量,2行8列,元素值为从0到15
X= torch.arange(16, dtype = torch.float32).reshape((2, 8))
print(X)
# 输出:
# tensor([[ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.],
#         [ 8.,  9., 10., 11., 12., 13., 14., 15.]])
# print(dropout_layer(X, 0.))
# 输出:
# tensor([[ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.],
#         [ 8.,  9., 10., 11., 12., 13., 14., 15.]])
print(dropout_layer(X, 0.5))
# 输出:
# tensor([[ 0.,  2.,  4.,  0.,  8., 10.,  0.,  0.],
#         [ 0., 18., 20., 22., 24.,  0., 28.,  0.]])
print(dropout_layer(X, 1.))
# 输出:
# tensor([[0., 0., 0., 0., 0., 0., 0., 0.],
#         [0., 0., 0., 0., 0., 0., 0., 0.]])

 

 

 

4.6.2 定义网络模型

 

# 输入特征维度、输出特征维度、隐藏层1维度、隐藏层2维度
num_inputs, num_outputs, num_hiddens1, num_hiddens2 = 784, 10, 256, 256

# dropout1层的概率,dropout2层的概率
dropout1, dropout2 = 0.2, 0.5

# 定义网络模型
class Net(nn.Module):
    # 定义构造函数
    def __init__(self, num_inputs, num_outputs, num_hiddens1, num_hiddens2,is_training = True):
        # 调用父类的构造函数
        super(Net, self).__init__()
        self.num_inputs = num_inputs
        self.training = is_training #是训练还是测试
        # 定义全连接层1,全连接层输入维度num_inputs(784(28×28)),隐藏层1维度num_hiddens1(256)
        self.lin1 = nn.Linear(num_inputs, num_hiddens1)
        # 定义全连接层2,隐藏层1维度num_hiddens1(256),隐藏层2维度num_hiddens1(256)
        self.lin2 = nn.Linear(num_hiddens1, num_hiddens2)
        # 定义全连接层3,隐藏层2维度num_hiddens1(256),输出特征维度num_outputs(10)
        self.lin3 = nn.Linear(num_hiddens2, num_outputs)
        # relu激活函数
        self.relu = nn.ReLU()

    def forward(self, X):
        # 如果是训练模型:
        # 全连接层1 → relu层 → dropout层 → 全连接层2 → relu层 → dropout层 → 全连接层3
        # 如果是测试模型:
        # 全连接层1 → relu层 → 全连接层2 → relu层 → 全连接层3

        H1 = self.relu(self.lin1(X.reshape((-1, self.num_inputs))))
        # 只有在训练模型时才使用dropout
        if self.training == True:
            # 在第一个全连接层之后添加一个dropout层
            H1 = dropout_layer(H1, dropout1)
        H2 = self.relu(self.lin2(H1))
        if self.training == True:
            # 在第二个全连接层之后添加一个dropout层
            H2 = dropout_layer(H2, dropout2)
        out = self.lin3(H2)
        return out

net = Net(num_inputs, num_outputs, num_hiddens1, num_hiddens2)

 

 

 

4.6.3 定义损失函数

 

# 定义交叉熵损失函数
loss = nn.CrossEntropyLoss(reduction='none')

 

 

 

4.6.4 下载fashion_mnist数据集

 

# 定义批量大小
batch_size = 256
# 下载fashion_mnist,并对数据集进行打乱和按批量大小进行切割的操作,得到可迭代的训练集和测试集(训练集和测试集的形式都为(特征数据集合,数字标签集合))
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)

 

 

 

4.6.5 定义优化器

 

# 定义学习率
lr = 0.5
# 定义随机梯度下降优化器
trainer = torch.optim.SGD(net.parameters(), lr=lr)

 

 

 

4.6.6 训练过程

 

# 定义训练轮数、学习率
num_epochs = 10
# 开始训练
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)

 

 

 

4.6.7 训练结果可视化

 

plt.savefig('OutPut.png')

 

 

本小节完整代码如下

 

import torch
from torch import nn
from d2l import torch as d2l
from matplotlib import pyplot as plt

# ------------------------------定义dropout层------------------------------------

def dropout_layer(X, dropout):
    assert 0 <= dropout <= 1
    # 在本情况中,所有元素都被丢弃(置0)
    if dropout == 1:
        return torch.zeros_like(X)
    # 在本情况中,所有元素都被保留(不变)
    if dropout == 0:
        return X

    # 生成一个随机矩阵和掩码矩阵,如果随机值大于dropout就置1,否则置0
    mask = (torch.rand(X.shape) > dropout).float()
    return mask * X / (1.0 - dropout)

# 定义一个张量,2行8列,元素值为从0到15
X= torch.arange(16, dtype = torch.float32).reshape((2, 8))
print(X)
# 输出:
# tensor([[ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.],
#         [ 8.,  9., 10., 11., 12., 13., 14., 15.]])
# print(dropout_layer(X, 0.))
# 输出:
# tensor([[ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.],
#         [ 8.,  9., 10., 11., 12., 13., 14., 15.]])
print(dropout_layer(X, 0.5))
# 输出:
# tensor([[ 0.,  2.,  4.,  0.,  8., 10.,  0.,  0.],
#         [ 0., 18., 20., 22., 24.,  0., 28.,  0.]])
print(dropout_layer(X, 1.))
# 输出:
# tensor([[0., 0., 0., 0., 0., 0., 0., 0.],
#         [0., 0., 0., 0., 0., 0., 0., 0.]])

# ------------------------------定义网络模型------------------------------------

# 输入特征维度、输出特征维度、隐藏层1维度、隐藏层2维度
num_inputs, num_outputs, num_hiddens1, num_hiddens2 = 784, 10, 256, 256

# dropout1层的概率,dropout2层的概率
dropout1, dropout2 = 0.2, 0.5

# 定义网络模型
class Net(nn.Module):
    # 定义构造函数
    def __init__(self, num_inputs, num_outputs, num_hiddens1, num_hiddens2,is_training = True):
        # 调用父类的构造函数
        super(Net, self).__init__()
        self.num_inputs = num_inputs
        self.training = is_training #是训练还是测试
        # 定义全连接层1,全连接层输入维度num_inputs(784(28×28)),隐藏层1维度num_hiddens1(256)
        self.lin1 = nn.Linear(num_inputs, num_hiddens1)
        # 定义全连接层2,隐藏层1维度num_hiddens1(256),隐藏层2维度num_hiddens1(256)
        self.lin2 = nn.Linear(num_hiddens1, num_hiddens2)
        # 定义全连接层3,隐藏层2维度num_hiddens1(256),输出特征维度num_outputs(10)
        self.lin3 = nn.Linear(num_hiddens2, num_outputs)
        # relu激活函数
        self.relu = nn.ReLU()

    def forward(self, X):
        # 如果是训练模型:
        # 全连接层1 → relu层 → dropout层 → 全连接层2 → relu层 → dropout层 → 全连接层3
        # 如果是测试模型:
        # 全连接层1 → relu层 → 全连接层2 → relu层 → 全连接层3

        H1 = self.relu(self.lin1(X.reshape((-1, self.num_inputs))))
        # 只有在训练模型时才使用dropout
        if self.training == True:
            # 在第一个全连接层之后添加一个dropout层
            H1 = dropout_layer(H1, dropout1)
        H2 = self.relu(self.lin2(H1))
        if self.training == True:
            # 在第二个全连接层之后添加一个dropout层
            H2 = dropout_layer(H2, dropout2)
        out = self.lin3(H2)
        return out

net = Net(num_inputs, num_outputs, num_hiddens1, num_hiddens2)

# ------------------------------定义损失函数------------------------------------

# 定义交叉熵损失函数
loss = nn.CrossEntropyLoss(reduction='none')

# ------------------------------下载fashion_mnist数据集------------------------------------

# 定义批量大小
batch_size = 256
# 下载fashion_mnist,并对数据集进行打乱和按批量大小进行切割的操作,得到可迭代的训练集和测试集(训练集和测试集的形式都为(特征数据集合,数字标签集合))
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)

# ------------------------------定义优化器------------------------------------

# 定义学习率
lr = 0.5
# 定义随机梯度下降优化器
trainer = torch.optim.SGD(net.parameters(), lr=lr)

# ------------------------------训练过程------------------------------------

# 定义训练轮数、学习率
num_epochs = 10
# 开始训练
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)

# ------------------------------训练结果可视化------------------------------------

plt.savefig('OutPut.png')

 

 

posted on 2022-11-05 22:09  yc-limitless  阅读(266)  评论(0)    收藏  举报