提交 77295c9d 编写于 作者: W wizardforcel

2021-01-17 22:26:16

上级 3fba2354
...@@ -802,93 +802,70 @@ ...@@ -802,93 +802,70 @@
1. 导入所需的库。 1. 导入所需的库。
将 numpy 导入为 np ```py
import numpy as np
进口火炬 import torch
from torch import nn, optim
从火炬进口 nn,乐观 import torch.nn.functional as F
from torchvision import datasets
导入功能为 F 的 torch.nn。 import torchvision.transforms as transforms
from torch.utils.data.sampler import SubsetRandomSampler
从 torchvision 导入数据集中 from sklearn.metrics import accuracy_score
import matplotlib.pyplot as plt
导入 torchvision.transforms 作为转换 ```
从 torch.utils.data.sampler 导入 SubsetRandomSampler
从 sklearn.metrics 导入 precision_score
导入 matplotlib.pyplot 作为 plt
2. 设置要对数据进行的变换,将数据转换为张量并对像素值进行归一化。 2. 设置要对数据进行的变换,将数据转换为张量并对像素值进行归一化。
变换= \ ```py
transform = \
transforms.Compose([[transforms.ToTensor(),\     transforms.Compose([transforms.ToTensor(), \
                        transforms.Normalize((0.5, 0.5, 0.5),\
transforms.Normalize((0.5,0.5,0.5),\                                              (0.5, 0.5, 0.5))])
```
(0.5, 0.5, 0.5))])
3. 设置批量大小为 100 张图像,并从 **CIFAR10** 数据集下载训练和测试数据。 3. 设置批量大小为 100 张图像,并从 **CIFAR10** 数据集下载训练和测试数据。
```py
batch_size = 100 batch_size = 100
train_data = datasets.CIFAR10('data', train=True, \
train_data =数据集.CIFAR10('data',train = True,\                               download=True, \
                              transform=transform)
download = True,\ test_data = datasets.CIFAR10('data', train=False, \
                             download=True, \
转换=转换)                              transform=transform)
```
test_data =数据集.CIFAR10('data',train = False,\
download = True,\
转换=转换)
前面的代码将下载可通过 PyTorch 的`Torchvision`软件包获得的训练和测试数据集。 根据上一步中定义的转换对数据集进行转换。 前面的代码将下载可通过 PyTorch 的`Torchvision`软件包获得的训练和测试数据集。 根据上一步中定义的转换对数据集进行转换。
4. 使用 20% 的验证大小,定义训练和验证采样器,用于将数据集划分为这两组。 4. 使用 20% 的验证大小,定义训练和验证采样器,用于将数据集划分为这两组。
```py
dev_size = 0.2 dev_size = 0.2
idx = list(range(len(train_data)))
idx =列表(范围(len(train_data))) np.random.shuffle(idx)
split_size = int(np.floor(dev_size * len(train_data)))
np.random.shuffle(idx) train_idx, dev_idx = idx[split_size:], idx[:split_size]
train_sampler = SubsetRandomSampler(train_idx)
split_size = int(np.floor(dev_size * len(train_data))) dev_sampler = SubsetRandomSampler(dev_idx)
```
train_idx,dev_idx = idx [split_size:],idx [:split_size]
train_sampler = SubsetRandomSampler(train_idx)
dev_sampler = SubsetRandomSampler(dev_idx)
为了将训练集分为两组(训练和验证),为每个组定义了一个索引列表,然后可以使用`SubsetRandomSampler`函数对其进行随机采样。 为了将训练集分为两组(训练和验证),为每个组定义了一个索引列表,然后可以使用`SubsetRandomSampler`函数对其进行随机采样。
5. 使用`DataLoader()`函数来定义要使用的每一组数据的批次。 5. 使用`DataLoader()`函数来定义要使用的每一组数据的批次。
```py
train_loader = \ train_loader = \
torch.utils.data.DataLoader(train_data, \
torch.utils.data.DataLoader(train_data,\                             batch_size=batch_size, \
                            sampler=train_sampler)
batch_size =批量大小,\
sampler = train_sampler)
dev_loader = \ dev_loader = \
torch.utils.data.DataLoader(train_data, \
torch.utils.data.DataLoader(train_data,\                             batch_size=batch_size, \
                            sampler=dev_sampler)
batch_size =批量大小,\
sampler = dev_sampler)
test_loader = \ test_loader = \
torch.utils.data.DataLoader(test_data, \
torch.utils.data.DataLoader(test_data,\                             batch_size=batch_size)
```
batch_size =批量大小)
PyTorch 的`DataLoader`函数用于创建批量,这些批量将在开发过程的训练,验证和测试阶段馈送到模型中。 PyTorch 的`DataLoader`函数用于创建批量,这些批量将在开发过程的训练,验证和测试阶段馈送到模型中。
...@@ -910,319 +887,188 @@ ...@@ -910,319 +887,188 @@
Linear2:一个全连接层,可生成 10 个输出,每个类标签一个。 将`log_softmax`激活函数用于输出层: Linear2:一个全连接层,可生成 10 个输出,每个类标签一个。 将`log_softmax`激活函数用于输出层:
CNN(nn.Module)类: ```py
class CNN(nn.Module):
def __init __():     def __init__(self):
        super(CNN, self).__init__()
超级(CNN,自我).__ init __()         self.conv1 = nn.Conv2d(3, 10, 3, 1, 1)
        self.conv2 = nn.Conv2d(10, 20, 3, 1, 1)
self.conv1 = nn.Conv2d(3,10,3,1,1)         self.conv3 = nn.Conv2d(20, 40, 3, 1, 1)
        self.pool = nn.MaxPool2d(2, 2)
self.conv2 = nn.Conv2d(10,20,3,1,1)         self.linear1 = nn.Linear(40 * 4 * 4, 100)
        self.linear2 = nn.Linear(100, 10)
self.conv3 = nn.Conv2d(20,40,3,1,1)         self.dropout = nn.Dropout(0.2)
    def forward(self, x):
self.pool = nn.MaxPool2d(2,2)         x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
self.linear1 = nn.Linear(40 * 4 * 4,100)         x = self.pool(F.relu(self.conv3(x)))
        x = x.view(-1, 40 * 4 * 4)
self.linear2 = nn.Linear(100,10)         x = self.dropout(x)
        x = F.relu(self.linear1(x))
self.dropout = nn.Dropout(0.2)         x = self.dropout(x)
        x = F.log_softmax(self.linear2(x), dim=1)
def forward(self,x):         return x
```
x = self.pool(F.relu(self.conv1(x)))
x = self.pool(F.relu(self.conv2(x)))
x = self.pool(F.relu(self.conv3(x)))
x = x.view(-1,40 * 4 * 4)
x = self.dropout(x)
x = F.relu(self.linear1(x))
x = self.dropout(x)
x = F.log_softmax(self.linear2(x),dim = 1)
返回 x
前面的代码段包含一个定义了网络架构的类(`__init__`方法),以及在信息正向传递过程中所遵循的步骤(`forward`方法)。 前面的代码段包含一个定义了网络架构的类(`__init__`方法),以及在信息正向传递过程中所遵循的步骤(`forward`方法)。
7. 定义训练模型所需的所有参数。设置周期数为`50` 7. 定义训练模型所需的所有参数。设置周期数为`50`
型号= CNN() ```py
model = CNN()
loss_function = nn.NLLLoss() loss_function = nn.NLLLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
优化程序= optim.Adam(model.parameters(),lr = 0.001) epochs = 50
```
时代= 50
我们为此练习选择的优化器是 Adam。 同样,负对数似然率用作损失函数,如本书前一章所述。 我们为此练习选择的优化器是 Adam。 同样,负对数似然率用作损失函数,如本书前一章所述。
如果您的计算机具有可用的 GPU,则应按以下步骤完成模型的实例化: 如果您的计算机具有可用的 GPU,则应按以下步骤完成模型的实例化:
型号= CNN()。to(“ cuda”) ```py
model = CNN().to("cuda")
```
8. 训练你的网络,并确保保存训练集和验证集的损失和准确性的值。 8. 训练你的网络,并确保保存训练集和验证集的损失和准确性的值。
train_losses,dev_losses,train_acc,dev_acc = [],[],[],[] ```py
train_losses, dev_losses, train_acc, dev_acc= [], [], [], []
x_axis = [] x_axis = []
# For loop through the epochs
#循环遍历 for e in range(1, epochs+1):
    losses = 0
对于范围(1,历元+1)中的 e:     acc = 0
    iterations = 0
损失= 0     model.train()
    """
acc = 0     For loop through the batches (created using
    the train loader)
迭代次数= 0     """
    for data, target in train_loader:
model.train()         iterations += 1
        # Forward and backward pass of the training data
"""         pred = model(data)
        loss = loss_function(pred, target)
For 遍历批量(使用创建         optimizer.zero_grad()
        loss.backward()
火车装载者)         optimizer.step()
        losses += loss.item()
"""         p = torch.exp(pred)
        top_p, top_class = p.topk(1, dim=1)
对于数据,在 train_loader 中定位:         acc += accuracy_score(target, top_class)
    dev_losss = 0
迭代次数== 1     dev_accs = 0
    iter_2 = 0
#训练数据的前后传递     # Validation of model for given epoch
    if e%5 == 0 or e == 1:
pred =模型(数据)         x_axis.append(e)
        with torch.no_grad():
损失= loss_function(pred,目标)             model.eval()
            """
Optimizer.zero_grad()             For loop through the batches of
            the validation set
loss.backward()             """
            for data_dev, target_dev in dev_loader:
Optimizer.step()                 iter_2 += 1
                dev_pred = model(data_dev)
损失+ = loss.item()                 dev_loss = loss_function(dev_pred, target_dev)
                dev_losss += dev_loss.item()
p = torch.exp(pred)                 dev_p = torch.exp(dev_pred)
                top_p, dev_top_class = dev_p.topk(1, dim=1)
top_p,top_class = p.topk(1,暗= 1)                 dev_accs += accuracy_score(target_dev, \
                                           dev_top_class)
acc + = precision_score(target,top_class)         # Losses and accuracy are appended to be printed
        train_losses.append(losses/iterations)
dev_losss = 0         dev_losses.append(dev_losss/iter_2)
        train_acc.append(acc/iterations)
dev_accs = 0         dev_acc.append(dev_accs/iter_2)
        print("Epoch: {}/{}.. ".format(e, epochs), \
iter_2 = 0               "Training Loss: {:.3f}.. "\
              .format(losses/iterations), \
#验证给定时期的模型               "Validation Loss: {:.3f}.. "\
              .format(dev_losss/iter_2), \
如果 e% 5 == 0 或 e == 1:               "Training Accuracy: {:.3f}.. "\
              .format(acc/iterations), \
x_axis.append(e)               "Validation Accuracy: {:.3f}"\
              .format(dev_accs/iter_2))
使用 torch.no_grad(): ```
model.eval()
"""
用于循环遍历
验证集
"""
对于 dev_loader 中的 data_dev,target_dev:
iter_2 + = 1
dev_pred =模型(data_dev)
dev_loss = loss_function(dev_pred,target_dev)
dev_losss + = dev_loss.item()
dev_p = torch.exp(dev_pred)
top_p,dev_top_class = dev_p.topk(1,暗= 1)
dev_accs + = precision_score(target_dev,\
dev_top_class)
#损失和准确率将附加打印
train_losses.append(损失/迭代)
dev_losses.append(dev_losss / iter_2)
train_acc.append(acc /迭代)
dev_acc.append(dev_accs / iter_2)
print(“ Epoch:{} / {} ..”“ .format(e,epochs),\
“训练损失:{:. 3f} ..” \
.format(损失/迭代),\
“验证损失:{:. 3f} ..” \
.format(dev_losss / iter_2),\
“训练准确率:{:. 3f} ..” \
.format(acc / iterations),\
“验证准确率:{:. 3f}” \
.format(dev_accs / iter_2))
如果您的计算机具有可用的 GPU,则对前面的代码进行一些修改,如下所示: 如果您的计算机具有可用的 GPU,则对前面的代码进行一些修改,如下所示:
train_losses,dev_losses,train_acc,dev_acc = [],[],[],[] ```py
train_losses, dev_losses, train_acc, dev_acc= [], [], [], []
x_axis = [] x_axis = []
# For loop through the epochs
#循环遍历 for e in range(1, epochs+1):
    losses = 0
对于范围(1,历元+1)中的 e:     acc = 0
    iterations = 0
损失= 0     
    model.train()
acc = 0     """
    For loop through the batches
迭代次数= 0     (created using the train loader)
    """
model.train()     for data, target in train_loader:
        iterations += 1
"""         # Forward and backward pass of the training data
        pred = model(data.to("cuda"))
循环遍历批量         loss = loss_function(pred, target.to("cuda"))
        optimizer.zero_grad()
(使用火车装载程序创建)         loss.backward()
        optimizer.step()
"""         losses += loss.item()
        p = torch.exp(pred)
对于数据,在 train_loader 中定位:         top_p, top_class = p.topk(1, dim=1)
        acc += accuracy_score(target.to("cpu"), \
迭代次数== 1                top_class.to("cpu"))
    dev_losss = 0
#训练数据的前后传递     dev_accs = 0
    iter_2 = 0
pred =模型(data.to(“ cuda”))     # Validation of model for given epoch
    if e%5 == 0 or e == 1:
损失= loss_function(pred,target.to(“ cuda”))         x_axis.append(e)
        with torch.no_grad():
Optimizer.zero_grad()             model.eval()
            """
loss.backward()             For loop through the batches of
            the validation set
Optimizer.step()             """
            for data_dev, target_dev in dev_loader:
损失+ = loss.item()                 iter_2 += 1
                dev_pred = model(data_dev.to("cuda"))
p = torch.exp(pred)                 dev_loss = loss_function(dev_pred, \
                           target_dev.to("cuda"))
top_p,top_class = p.topk(1,暗= 1)                 dev_losss += dev_loss.item()
                dev_p = torch.exp(dev_pred)
acc + = precision_score(target.to(“ cpu”),\                 top_p, dev_top_class = dev_p.topk(1, dim=1)
                dev_accs += \
top_class.to(“ cpu”))                 accuracy_score(target_dev.to("cpu"), \
                               dev_top_class.to("cpu"))
dev_losss = 0         # Losses and accuracy are appended to be printed
        train_losses.append(losses/iterations)
dev_accs = 0         dev_losses.append(dev_losss/iter_2)
        train_acc.append(acc/iterations)
iter_2 = 0         dev_acc.append(dev_accs/iter_2)
        print("Epoch: {}/{}.. ".format(e, epochs), \
#验证给定时期的模型               "Training Loss: {:.3f}.. "\
              .format(losses/iterations), \
如果 e% 5 == 0 或 e == 1:               "Validation Loss: {:.3f}.. "\
              .format(dev_losss/iter_2), \
x_axis.append(e)               "Training Accuracy: {:.3f}.. "\
              .format(acc/iterations), \
使用 torch.no_grad():               "Validation Accuracy: {:.3f}"\
              .format(dev_accs/iter_2))
model.eval() ```
"""
用于循环遍历
验证集
"""
对于 dev_loader 中的 data_dev,target_dev:
iter_2 + = 1
dev_pred =模型(data_dev.to(“奇迹”))
dev_loss = loss_function(dev_pred,\
target_dev.to(“ cuda”))
dev_losss + = dev_loss.item()
dev_p = torch.exp(dev_pred)
top_p,dev_top_class = dev_p.topk(1,暗= 1)
dev_accs + = \
precision_score(target_dev.to(“ cpu”),\
dev_top_class.to(“ cpu”))
#损失和准确率将附加打印
train_losses.append(损失/迭代)
dev_losses.append(dev_losss / iter_2)
train_acc.append(acc /迭代)
dev_acc.append(dev_accs / iter_2)
print(“ Epoch:{} / {} ..”“ .format(e,epochs),\
“训练损失:{:. 3f} ..” \
.format(损失/迭代),\
“验证损失:{:. 3f} ..” \
.format(dev_losss / iter_2),\
“训练准确率:{:. 3f} ..” \
.format(acc / iterations),\
“验证准确率:{:. 3f}” \
.format(dev_accs / iter_2))
9. 绘制这两组数据的损失和精度。要绘制损失,请使用以下代码。 9. 绘制这两组数据的损失和精度。要绘制损失,请使用以下代码。
plt.plot(x_axis,train_losses,label ='训练损失') ```py
plt.plot(x_axis,train_losses, label='Training loss')
plt.plot(x_axis,dev_losses,label ='验证损失') plt.plot(x_axis, dev_losses, label='Validation loss')
plt.legend(frameon=False)
plt.legend(frameon = False)
plt.show() plt.show()
```
结果图应类似于以下内容: 结果图应类似于以下内容:
...@@ -1232,13 +1078,12 @@ ...@@ -1232,13 +1078,12 @@
要绘制精度,请使用以下代码: 要绘制精度,请使用以下代码:
plt.plot(x_axis,train_acc,label =“训练精度”) ```py
plt.plot(x_axis, train_acc, label="Training accuracy")
plt.plot(x_axis,dev_acc,label =“验证准确率”) plt.plot(x_axis, dev_acc, label="Validation accuracy")
plt.legend(frameon=False)
plt.legend(frameon = False)
plt.show() plt.show()
```
该图应类似于以下内容: 该图应类似于以下内容:
...@@ -1250,51 +1095,36 @@ ...@@ -1250,51 +1095,36 @@
10. 在测试集上检查模型的准确性。 10. 在测试集上检查模型的准确性。
model.eval() ```py
model.eval()
iter_3 = 0 iter_3 = 0
acc_test = 0 acc_test = 0
for data_test, target_test in test_loader:
对于 test_loader 中的 data_test 和 target_test:     iter_3 += 1
    test_pred = model(data_test)
iter_3 + = 1     test_pred = torch.exp(test_pred)
    top_p, top_class_test = test_pred.topk(1, dim=1)
test_pred =模型(data_test)     acc_test += accuracy_score(target_test, top_class_test)
print(acc_test/iter_3)
test_pred = torch.exp(test_pred) ```
top_p,top_class_test = test_pred.topk(1,暗= 1)
acc_test + =准确度得分(target_test,top_class_test)
打印(acc_test / iter_3)
使用我们之前创建的数据加载器,可以对测试集数据进行图像分类,以估计模型在看不见数据上的准确率。 使用我们之前创建的数据加载器,可以对测试集数据进行图像分类,以估计模型在看不见数据上的准确率。
如果您的计算机具有可用的 GPU,则对前面的代码进行一些修改,如下所示: 如果您的计算机具有可用的 GPU,则对前面的代码进行一些修改,如下所示:
model.eval() ```py
model.eval()
iter_3 = 0 iter_3 = 0
acc_test = 0 acc_test = 0
for data_test, target_test in test_loader:
对于 test_loader 中的 data_test 和 target_test:     iter_3 += 1
    test_pred = model(data_test.to("cuda"))
iter_3 + = 1     test_pred = torch.exp(test_pred)
    top_p, top_class_test = test_pred.topk(1, dim=1)
test_pred =模型(data_test.to(“ cuda”))     acc_test += accuracy_score(target_test .to("cpu"), \
                               top_class_test .to("cpu"))
test_pred = torch.exp(test_pred) print(acc_test/iter_3)
```
top_p,top_class_test = test_pred.topk(1,暗= 1)
acc_test + = precision_score(target_test .to(“ cpu”),\
top_class_test .to(“ cpu”))
打印(acc_test / iter_3)
测试集的准确率与其他两组所达到的准确率非常相似,这意味着该模型能够对看不见的数据表现出同样出色的性能。 它应该在 72% 左右。 测试集的准确率与其他两组所达到的准确率非常相似,这意味着该模型能够对看不见的数据表现出同样出色的性能。 它应该在 72% 左右。
...@@ -1320,27 +1150,19 @@ ...@@ -1320,27 +1150,19 @@
对于测试集,请勿添加任何其他转换: 对于测试集,请勿添加任何其他转换:
变换= \ ```py
transform = \
{“火车”:transforms.Compose([\ {"train": transforms.Compose([\
          transforms.RandomHorizontalFlip(0.5), \
transforms.RandomHorizo​​ntalFlip(0.5),\           transforms.RandomGrayscale(0.1),\
          transforms.ToTensor(),\
transforms.RandomGrayscale(0.1),\           transforms.Normalize((0.5, 0.5, 0.5), \
                               (0.5, 0.5, 0.5))]),\
transforms.ToTensor(),\ "test": transforms.Compose([\
        transforms.ToTensor(),\
transforms.Normalize((0.5,0.5,0.5),\         transforms.Normalize((0.5, 0.5, 0.5), \
                             (0.5, 0.5, 0.5))])}
(0.5, 0.5, 0.5))]),\ ```
“ test”:transforms.Compose([\
transforms.ToTensor(),\
transforms.Normalize((0.5,0.5,0.5),\
(0.5, 0.5, 0.5))])}
3. 训练模型 100 个纪元。 3. 训练模型 100 个纪元。
...@@ -1382,53 +1204,32 @@ ...@@ -1382,53 +1204,32 @@
网络的最终架构应如下: 网络的最终架构应如下:
CNN(nn.Module)类: ```py
class CNN(nn.Module):
def __init __():     def __init__(self):
        super(Net, self).__init__()
超级(净,自我).__ init __()         self.conv1 = nn.Conv2d(3, 10, 3, 1, 1)
        self.norm1 = nn.BatchNorm2d(10)
self.conv1 = nn.Conv2d(3,10,3,1,1)         self.conv2 = nn.Conv2d(10, 20, 3, 1, 1)
        self.norm2 = nn.BatchNorm2d(20)
self.norm1 = nn.BatchNorm2d(10)         self.conv3 = nn.Conv2d(20, 40, 3, 1, 1)
        self.norm3 = nn.BatchNorm2d(40)
self.conv2 = nn.Conv2d(10,20,3,1,1)         self.pool = nn.MaxPool2d(2, 2)
        self.linear1 = nn.Linear(40 * 4 * 4, 100)
self.norm2 = nn.BatchNorm2d(20)         self.norm4 = nn.BatchNorm1d(100)
        self.linear2 = nn.Linear(100, 10)
self.conv3 = nn.Conv2d(20,40,3,1,1)         self.dropout = nn.Dropout(0.2)
    def forward(self, x):
self.norm3 = nn.BatchNorm2d(40)         x = self.pool(self.norm1(F.relu(self.conv1(x))))
        x = self.pool(self.norm2(F.relu(self.conv2(x))))
self.pool = nn.MaxPool2d(2,2)         x = self.pool(self.norm3(F.relu(self.conv3(x))))
        x = x.view(-1, 40 * 4 * 4)
self.linear1 = nn.Linear(40 * 4 * 4,100)         x = self.dropout(x)
        x = self.norm4(F.relu(self.linear1(x)))
self.norm4 = nn.BatchNorm1d(100)         x = self.dropout(x)
        x = F.log_softmax(self.linear2(x), dim=1)
self.linear2 = nn.Linear(100,10)         return x
```
self.dropout = nn.Dropout(0.2)
def forward(self,x):
x = self.pool(self.norm1(F.relu(self.conv1(x))))
x = self.pool(self.norm2(F.relu(self.conv2(x))))
x = self.pool(self.norm3(F.relu(self.conv3(x))))
x = x.view(-1,40 * 4 * 4)
x = self.dropout(x)
x = self.norm4(F.relu(self.linear1(x)))
x = self.dropout(x)
x = F.log_softmax(self.linear2(x),dim = 1)
返回 x
3. 训练模型 100 个纪元。 3. 训练模型 100 个纪元。
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册