《Pytorch深度学习和图神经网络(卷 1)》学习笔记——第六章

实例5:识别黑白图中的服装图案

Fashion-MNIST是手写数字数据集MNIST的一个替代品,常常被用来测试网络模型,如果在该数据集上效果都不好,其他数据集上的效果可想而知。其单个样本为28X28,6万张训练集,1万张测试集,共10类服装分类。

自动下载Fashion-MNIST

transform将图片转换成了Pytorch支持的形状(【通道,高,宽】)

import torchvision
import torchvision.transforms as tranforms
data_dir = './data/fashion_mnist/'
tranform = tranforms.Compose([tranforms.ToTensor()])
train_dataset = torchvision.datasets.FashionMNIST(data_dir, train=True, transform=tranform,download=True)

print("训练数据集条数",len(train_dataset))
val_dataset  = torchvision.datasets.FashionMNIST(root=data_dir, train=False, transform=tranform)
print("测试数据集条数",len(val_dataset))

我们直接打印一下val_dataset[0]和一张用Image读取的PNG图片

a = Image.open("1.png")
print(a)
print(val_dataset[0])

输出为:
<PIL.PngImagePlugin.PngImageFile image mode=RGBA size=1144x329 at 0x185B5B6E5D0>
(<PIL.Image.Image image mode=L size=28x28 at 0x185B5BE8890>, 9)

我们可以直接用np.array()来将PIL Image其转化成np数组,可以观察数据。

a = np.array(Image.open("1.png"))
print(a)
print(np.array(val_dataset[0][0]))
[[[245 247 249 255]
  [245 247 249 255]
  [245 247 249 255]
  ...
  [245 247 249 255]
  [245 247 249 255]
  [245 247 249 255]]

 [[245 247 249 255]
  [245 247 249 255]
  [184 184 184 255]
  ...
  [245 247 249 255]
  [245 247 249 255]
  [245 247 249 255]]

 [[245 247 249 255]
  [184 184 184 255]
  [184 184 184 255]
  ...
  [245 247 249 255]
  [245 247 249 255]
  [245 247 249 255]]

 ...

 [[245 247 182 255]
  [102  15  23 255]
  [ 62 143 216 255]
  ...
  [204 232 207 255]
  [204 232 207 255]
  [204 232 207 255]]

 [[245 247 249 255]
  [177 105  23 255]
  [ 12 105 182 255]
  ...
  [204 232 207 255]
  [204 232 207 255]
  [204 232 207 255]]

 [[245 247 249 255]
  [177 105  23 255]
  [ 12 105 182 255]
  ...
  [204 232 207 255]
  [204 232 207 255]
  [204 232 207 255]]]
[[  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   3   1   0   0   7   0  37   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   1   2   0  27  84
   11   0   0   0   0   0   0 119   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   1   0   0  88 143
  110   0   0   0   0  22  93 106   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   4   0  53 129 120
  147 175 157 166 135 154 168 140   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   2   0  11 137 130 128
  160 176 159 167 178 149 151 144   0   0]
 [  0   0   0   0   0   0   1   0   2   1   0   3   0   0 115 114 106 137
  168 153 156 165 167 143 157 158  11   0]
 [  0   0   0   0   1   0   0   0   0   0   3   0   0  89 139  90  94 153
  149 131 151 169 172 143 159 169  48   0]
 [  0   0   0   0   0   0   2   4   1   0   0   0  98 136 110 109 110 162
  135 144 149 159 167 144 158 169 119   0]
 [  0   0   2   2   1   2   0   0   0   0  26 108 117  99 111 117 136 156
  134 154 154 156 160 141 147 156 178   0]
 [  3   0   0   0   0   0   0  21  53  92 117 111 103 115 129 134 143 154
  165 170 154 151 154 143 138 150 165  43]
 [  0   0  23  54  65  76  85 118 128 123 111 113 118 127 125 139 133 136
  160 140 155 161 144 155 172 161 189  62]
 [  0  68  94  90 111 114 111 114 115 127 135 136 143 126 127 151 154 143
  148 125 162 162 144 138 153 162 196  58]
 [ 70 169 129 104  98 100  94  97  98 102 108 106 119 120 129 149 156 167
  190 190 196 198 198 187 197 189 184  36]
 [ 16 126 171 188 188 184 171 153 135 120 126 127 146 185 195 209 208 255
  209 177 245 252 251 251 247 220 206  49]
 [  0   0   0  12  67 106 164 185 199 210 211 210 208 190 150  82   8   0
    0   0 178 208 188 175 162 158 151  11]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]]

也可以用Tensor

data = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(tranforms.Compose([tranforms.ToTensor()])(data))
#输出
#tensor([[[1, 2, 3],
#         [4, 5, 6],
#         [7, 8, 9]]], dtype=torch.int32)

尝试用直接用tranforms.Compose([tranforms.ToTensor()])(a)转化成tensor失败,(其实也就可以用(tranforms.ToTensor()(a)) ),tranforms.Compose可以添加更多的转换条件。提示只能用于 PIL Image or ndarray,不支持直接用tuple元组转换,去看源代码,而是取出作为PIL Image进行的转换,而标签类别没有转换则返回默认类型Int。
在这里插入图片描述

print(type(val_dataset[0][0]))
print(type(val_dataset[0][1]))

返回的类型为:
<class ‘torch.Tensor’>
<class ‘int’>

读取显示Fashion-MNIST中的数据

im.reshape(-1,28)等价于im.reshape(28,28)等价于im.reshape(-1,28)
-1为自动匹配

import pylab
im = train_dataset[0][0]
im = im.reshape(-1,28) 
print("该图片的标签为:",train_dataset[0][1])
pylab.imshow(im)
pylab.show()

在这里插入图片描述
数据集封装类DataLoader
使用torch.utils.data.DataLoader类构建带有批次的数据集,与其配套的还有采样器Sampler类,有多种…
shuffle代表是否要顺序打乱
打印出来的train_dataset和用DataLoader之后的train_loader。
DataLoader就是用来读取dataset类的,自定义的数据集就要自己设计一个dataset类。

Dataset FashionMNIST
    Number of datapoints: 60000
    Root location: ./data/fashion_mnist/
    Split: Train
    StandardTransform
Transform: Compose(
               ToTensor()
           )
<torch.utils.data.dataloader.DataLoader object at 0x00000200A4746350>

用iter(train_loader)使其变为
<class ‘torch.utils.data.dataloader._SingleProcessDataLoaderIter’>
接着使用下列代码,就能打印出来10个数据。

print((iter(train_loader).__next__()))
[tensor([[[[0.0000, 0.0000, 0.0000,  ..., 0.0000, 0.0000, 0.0000],
          [0.0000, 0.0000, 0.0000,  ..., 0.0000, 0.0000, 0.0000],
          [0.0000, 0.0000, 0.0000,  ..., 0.0000, 0.0000, 0.0000],
          ...,
          [0.0000, 0.0000, 0.0000,  ..., 0.0000, 0.0000, 0.0000],
          [0.0000, 0.0000, 0.0000,  ..., 0.0000, 0.0000, 0.0000],
          [0.0000, 0.0000, 0.0000,  ..., 0.0000, 0.0000, 0.0000]]],


        [[[0.0000, 0.0000, 0.0000,  ..., 0.0000, 0.0000, 0.0000],
          [0.0000, 0.0000, 0.0000,  ..., 0.0000, 0.0000, 0.0000],
          [0.0000, 0.0000, 0.0000,  ..., 0.0000, 0.0000, 0.0000],
          ...,
          [0.0000, 0.0000, 0.0000,  ..., 0.0000, 0.0000, 0.0000],
          [0.0000, 0.0000, 0.0000,  ..., 0.0000, 0.0000, 0.0000],
          [0.0000, 0.0000, 0.0000,  ..., 0.0000, 0.0000, 0.0000]]],


        [[[0.0000, 0.0000, 0.0000,  ..., 0.0000, 0.0000, 0.0000],
          [0.0000, 0.0000, 0.0000,  ..., 0.0000, 0.0000, 0.0000],
          [0.0000, 0.0000, 0.0000,  ..., 0.0000, 0.0000, 0.0000],
          ...,
          [0.0000, 0.0000, 0.0000,  ..., 0.0000, 0.0000, 0.0000],
          [0.0000, 0.0000, 0.0000,  ..., 0.0000, 0.0000, 0.0000],
          [0.0000, 0.0000, 0.0000,  ..., 0.0000, 0.0000, 0.0000]]],


        ...,


        [[[0.0000, 0.0000, 0.0000,  ..., 0.0000, 0.0000, 0.0000],
          [0.0000, 0.0000, 0.0000,  ..., 0.0000, 0.0000, 0.0000],
          [0.0000, 0.0000, 0.0000,  ..., 0.0000, 0.0000, 0.0000],
          ...,
          [0.0000, 0.0000, 0.0000,  ..., 0.7059, 0.0000, 0.0000],
          [0.0000, 0.0000, 0.0000,  ..., 0.2824, 0.0000, 0.0000],
          [0.0000, 0.0000, 0.0000,  ..., 0.2745, 0.0000, 0.0000]]],


        [[[0.0000, 0.0000, 0.0000,  ..., 0.0000, 0.0000, 0.0000],
          [0.0000, 0.0000, 0.0000,  ..., 0.0000, 0.0000, 0.0000],
          [0.0000, 0.0000, 0.0000,  ..., 0.1529, 0.0039, 0.0000],
          ...,
          [0.0000, 0.0000, 0.0000,  ..., 0.9333, 0.0000, 0.0000],
          [0.0000, 0.0000, 0.0000,  ..., 0.5137, 0.0000, 0.0000],
          [0.0000, 0.0000, 0.0000,  ..., 0.0000, 0.0000, 0.0000]]],


        [[[0.0000, 0.0000, 0.0000,  ..., 0.0000, 0.0000, 0.0000],
          [0.0000, 0.0000, 0.0000,  ..., 0.0000, 0.0000, 0.0000],
          [0.0000, 0.0000, 0.0000,  ..., 0.0275, 0.0000, 0.0000],
          ...,
          [0.0000, 0.0000, 0.0000,  ..., 0.0000, 0.0353, 0.0000],
          [0.0000, 0.0000, 0.0000,  ..., 0.0000, 0.0118, 0.0000],
          [0.0000, 0.0000, 0.0000,  ..., 0.0000, 0.0000, 0.0000]]]]), tensor([9, 0, 0, 3, 0, 2, 7, 2, 5, 5])]

这张图是连在一起的,是由于torchvision.utils.make_grid(images,nrow=batch_size)
在这里插入图片描述
nrow表示一行放几张,填5则放两行。
在这里插入图片描述

#逆时针旋转90度
img = np.transpose(img, (1, 0, 2))
#目前没搞懂
img = np.transpose(img, (1, 2, 0))

import numpy as np
import pylab as plt
a=[[[0,127,255],[0,127,255],[0,127,255]]]
print(a)
a_trans=np.transpose(a, (1, 2, 0))
print(a_trans)
plt.imshow(a)
plt.imshow(a_trans)
plt.show()

a和a_trans分别为:
在这里插入图片描述
在这里插入图片描述

############数据集的制作
import torch.utils.data #可以跳转查看代码定义
batch_size = 10

print(train_dataset)
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
test_loader = torch.utils.data.DataLoader(val_dataset, batch_size=batch_size, shuffle=False)
print(train_loader)

from matplotlib import pyplot as plt
import numpy as np
def imshow(img):
    print("图片形状:",np.shape(img))
    npimg = img.numpy()
    plt.axis('off')
    plt.imshow(np.transpose(npimg, (1, 2, 0)))

classes = ('T-shirt', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle_Boot')
sample = iter(train_loader)
images, labels = sample.__next__()
print('样本形状:',np.shape(images))
print('样本标签:',labels)
imshow(torchvision.utils.make_grid(images,nrow=batch_size)) #是个tensor
print(','.join('%5s' % classes[labels[j]] for j in range(len(images))))

#样本形状: torch.Size([10, 1, 28, 28])
#样本标签: tensor([9, 0, 0, 3, 0, 2, 7, 2, 5, 5])
#图片形状: torch.Size([3, 32, 302])
#Sandal,Shirt, Coat,Sandal,Pullover,Sandal,Ankle_Boot,  Bag,Shirt,Pullover
############数据集的制作

输出结果一共四行:
第一行,形状4个维度,第1维的10代表有10个数据,第2维度的1代表1个通道,3、4维是图片长宽。
第二行,是样本标签。
第三行,可视化的图片形状,第1维的3代表图片是3通道。在合成过程中图片由1通道变成3通道了。
第四行是分类的具体类别。

构建并训练模型

定义模型类

#########################################################################################################################
#定义myConNet模型类,该模型包括 2个卷积层和3个全连接层
from torch.nn import functional as F

class myConNet(torch.nn.Module):
    def __init__(self):
        super(myConNet, self).__init__()
        #定义卷积层
        self.conv1 = torch.nn.Conv2d(in_channels=1, out_channels=6, kernel_size=5)
        self.conv2 = torch.nn.Conv2d(in_channels=6, out_channels=12, kernel_size=5)
        #定义全连接层
        self.fc1 = torch.nn.Linear(in_features=12*4*4, out_features=120)
        self.fc2 = torch.nn.Linear(in_features=120, out_features=60)
        self.out = torch.nn.Linear(in_features=60, out_features=10)

    def forward(self, t):#搭建正向结构
        #第一层卷积和池化处理
        t = self.conv1(t)
        t = F.relu(t)
        t = F.max_pool2d(t, kernel_size=2, stride=2)
        #第二层卷积和池化处理
        t = self.conv2(t)
        t = F.relu(t)
        t = F.max_pool2d(t, kernel_size=2, stride=2)

        #搭建全连接网络,第一层全连接
        t = t.reshape(-1, 12 * 4 * 4)#将卷积结果由4维变为2维
        t = self.fc1(t)
        t = F.relu(t)
        #第二层全连接
        t = self.fc2(t)
        t = F.relu(t)
        #第三层全连接
        t = self.out(t)
        return t

if __name__ == '__main__':  
#
    network = myConNet()
    print(network)#打印网络

#myConNet(
#  (conv1): Conv2d(1, 6, kernel_size=(5, 5), stride=(1, 1))
#  (conv2): Conv2d(6, 12, kernel_size=(5, 5), stride=(1, 1))
#  (fc1): Linear(in_features=192, out_features=120, bias=True)
#  (fc2): Linear(in_features=120, out_features=60, bias=True)
#  (out): Linear(in_features=60, out_features=10, bias=True)
#)

定义损失的计算方法及优化器

criterion = torch.nn.CrossEntropyLoss() #实例化损失函数类
optimizer = torch.optim.Adam(network.parameters(), lr=.01)

训练并保存模型

    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    print(device)
    network.to(device)
    for epoch in range(2): #数据集迭代2次
        running_loss = 0.0
        for i, data in enumerate(train_loader, 0): #循环取出批次数据
            inputs, labels = data
            inputs, labels = inputs.to(device), labels.to(device) #
            optimizer.zero_grad()#清空之前的梯度
            outputs = network(inputs)
            loss = criterion(outputs, labels)#计算损失
            loss.backward()  #反向传播
            optimizer.step() #更新参数
    
            running_loss += loss.item()
            if i % 1000 == 999:
                print('[%d, %5d] loss: %.3f' %
                    (epoch + 1, i + 1, running_loss / 2000))
                running_loss = 0.0
    
    print('Finished Training')
    # 保存模型
    torch.save(network.state_dict(), './CNNFashionMNIST.pth')
#   [1,  1000] loss: 0.430
#	[1,  2000] loss: 0.313
#	[1,  3000] loss: 0.288
#	[1,  4000] loss: 0.296
#	[1,  5000] loss: 0.267
#	[1,  6000] loss: 0.280
#	[2,  1000] loss: 0.264
#	[2,  2000] loss: 0.260
#	[2,  3000] loss: 0.267
#	[2,  4000] loss: 0.267
#	[2,  5000] loss: 0.257
#	[2,  6000] loss: 0.253

加载使用并测试模型

    network.load_state_dict(torch.load( './CNNFashionMNIST.pth'))#加载模型
    
    #使用模型
    dataiter = iter(test_loader)
    images, labels = dataiter.__next__()
    inputs, labels = images.to(device), labels.to(device)
    
    imshow(torchvision.utils.make_grid(images,nrow=batch_size))
    print('真实标签: ', ' '.join('%5s' % classes[labels[j]] for j in range(len(images))))
    outputs = network(inputs)
    _, predicted = torch.max(outputs, 1)
    
    
    print('预测结果: ', ' '.join('%5s' % classes[predicted[j]]
                                  for j in range(len(images))))
    
    
    #测试模型
    class_correct = list(0. for i in range(10))
    class_total = list(0. for i in range(10))
    with torch.no_grad():
        for data in test_loader:
            images, labels = data
            inputs, labels = images.to(device), labels.to(device)
            outputs = network(inputs)
            _, predicted = torch.max(outputs, 1)
            predicted = predicted.to(device)
            c = (predicted == labels).squeeze()
            for i in range(10):
                label = labels[i]
                class_correct[label] += c[i].item()
                class_total[label] += 1
    
    sumacc = 0
    for i in range(10):
        Accuracy = 100 * class_correct[i] / class_total[i]
        print('Accuracy of %5s : %2d %%' % (classes[i], Accuracy ))
        sumacc =sumacc+Accuracy
    print('Accuracy of all : %2d %%' % ( sumacc/10. ))


在这里插入图片描述
真实标签: Ankle_Boot Pullover Trouser Trouser Shirt Trouser Coat Shirt Sandal Sneaker
预测结果: Ankle_Boot Pullover Trouser Trouser Shirt Trouser Coat Shirt Sandal Sneaker
Accuracy of T-shirt : 88 %
Accuracy of Trouser : 95 %
Accuracy of Pullover : 54 %
Accuracy of Dress : 86 %
Accuracy of Coat : 77 %
Accuracy of Sandal : 96 %
Accuracy of Shirt : 42 %
Accuracy of Sneaker : 95 %
Accuracy of Bag : 92 %
Accuracy of Ankle_Boot : 92 %
Accuracy of all : 82 %

完整代码:

import torchvision
import torchvision.transforms as tranforms
data_dir = './data/fashion_mnist/'
tranform = tranforms.Compose([tranforms.ToTensor()])
train_dataset = torchvision.datasets.FashionMNIST(data_dir, train=True, transform=tranform,download=True)

print("训练数据集条数",len(train_dataset))
val_dataset  = torchvision.datasets.FashionMNIST(root=data_dir, train=False, transform=tranform)
print("测试数据集条数",len(val_dataset))
import pylab
im = train_dataset[0][0]
im = im.reshape(-1,28)
pylab.imshow(im)
pylab.show()
print("该图片的标签为:",train_dataset[0][1])

############数据集的制作
import torch
batch_size = 10
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
test_loader = torch.utils.data.DataLoader(val_dataset, batch_size=batch_size, shuffle=False)


from matplotlib import pyplot as plt
import numpy as np
def imshow(img):
    print("图片形状:",np.shape(img))
    npimg = img.numpy()
    plt.axis('off')
    plt.imshow(np.transpose(npimg, (1, 2, 0)))

classes = ('T-shirt', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle_Boot')
sample = iter(train_loader)
images, labels = sample.next()
print('样本形状:',np.shape(images))
print('样本标签:',labels)
imshow(torchvision.utils.make_grid(images,nrow=batch_size))
print(','.join('%5s' % classes[labels[j]] for j in range(len(images))))

############数据集的制作




#########################################################################################################################
#定义myConNet模型类,该模型包括 2个卷积层和3个全连接层
from torch.nn import functional as F

class myConNet(torch.nn.Module):
    def __init__(self):
        super(myConNet, self).__init__()
        #定义卷积层
        self.conv1 = torch.nn.Conv2d(in_channels=1, out_channels=6, kernel_size=5)
        self.conv2 = torch.nn.Conv2d(in_channels=6, out_channels=12, kernel_size=5)
        #定义全连接层
        self.fc1 = torch.nn.Linear(in_features=12*4*4, out_features=120)
        self.fc2 = torch.nn.Linear(in_features=120, out_features=60)
        self.out = torch.nn.Linear(in_features=60, out_features=10)

    def forward(self, t):#搭建正向结构
        #第一层卷积和池化处理
        t = self.conv1(t)
        t = F.relu(t)
        t = F.max_pool2d(t, kernel_size=2, stride=2)
        #第二层卷积和池化处理
        t = self.conv2(t)
        t = F.relu(t)
        t = F.max_pool2d(t, kernel_size=2, stride=2)

        #搭建全连接网络,第一层全连接
        t = t.reshape(-1, 12 * 4 * 4)#将卷积结果由4维变为2维
        t = self.fc1(t)
        t = F.relu(t)
        #第二层全连接
        t = self.fc2(t)
        t = F.relu(t)
        #第三层全连接
        t = self.out(t)
        return t

if __name__ == '__main__':  
#
    network = myConNet()
    print(network)#打印网络
    
    #
    
    #print(network.parameters())
    
    ##指定设备
    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    print(device)
    network.to(device)
    #print(network.parameters())
    
    criterion = torch.nn.CrossEntropyLoss()  #实例化损失函数类
    optimizer = torch.optim.Adam(network.parameters(), lr=.01)
    
    
    for epoch in range(2): #数据集迭代2次
        running_loss = 0.0
        for i, data in enumerate(train_loader, 0): #循环取出批次数据
            inputs, labels = data
            inputs, labels = inputs.to(device), labels.to(device) #
            optimizer.zero_grad()#清空之前的梯度
            outputs = network(inputs)
            loss = criterion(outputs, labels)#计算损失
            loss.backward()  #反向传播
            optimizer.step() #更新参数
    
            running_loss += loss.item()
            if i % 1000 == 999:
                print('[%d, %5d] loss: %.3f' %
                    (epoch + 1, i + 1, running_loss / 2000))
                running_loss = 0.0
    
    print('Finished Training')
    # 保存模型
    torch.save(network.state_dict(), './CNNFashionMNIST.pth')
    
    
    #from sklearn.metrics import accuracy_score
    #outputs = network(inputs)
    #_, predicted = torch.max(outputs, 1)
    #print("训练时的准确率:",accuracy_score(predicted.cpu().numpy(),labels.cpu().numpy()))
    
    
    network.load_state_dict(torch.load( './CNNFashionMNIST.pth'))#加载模型
    
    #使用模型
    dataiter = iter(test_loader)
    images, labels = dataiter.next()
    inputs, labels = images.to(device), labels.to(device)
    
    imshow(torchvision.utils.make_grid(images,nrow=batch_size))
    print('真实标签: ', ' '.join('%5s' % classes[labels[j]] for j in range(len(images))))
    outputs = network(inputs)
    _, predicted = torch.max(outputs, 1)
    
    
    print('预测结果: ', ' '.join('%5s' % classes[predicted[j]]
                                  for j in range(len(images))))
    
    
    #测试模型
    class_correct = list(0. for i in range(10))
    class_total = list(0. for i in range(10))
    with torch.no_grad():
        for data in test_loader:
            images, labels = data
            inputs, labels = images.to(device), labels.to(device)
            outputs = network(inputs)
            _, predicted = torch.max(outputs, 1)
            predicted = predicted.to(device)
            c = (predicted == labels).squeeze()
            for i in range(10):
                label = labels[i]
                class_correct[label] += c[i].item()
                class_total[label] += 1
    
    sumacc = 0
    for i in range(10):
        Accuracy = 100 * class_correct[i] / class_total[i]
        print('Accuracy of %5s : %2d %%' % (classes[i], Accuracy ))
        sumacc =sumacc+Accuracy
    print('Accuracy of all : %2d %%' % ( sumacc/10. ))



'''

当你需要输出tensor查看的时候,或许需要设置一下默认的输出选项:
torch.set_printoptions(precision=None, threshold=None, edgeitems=None, linewidth=None, profile=None)

其中precision是每一个元素的输出精度,默认是八位;threshold是输出时的阈值,当tensor中元素的个数大于该值时,进行缩略输出,默认时1000;edgeitems是输出的维度,默认是3;linewidth字面意思,每一行输出的长度;profile=None,修正默认设置(不太懂,感兴趣的可以试试))
为了防止一些不正常的元素产生,比如特别小的数,pytorch支持如下设置:
torch.set_flush_denormal(mode)

mode中可以填true或者false
例子如下:
>>> torch.set_flush_denormal(True)
True
>>> torch.tensor([1e-323], dtype=torch.float64)
tensor([ 0.], dtype=torch.float64)
>>> torch.set_flush_denormal(False)
True
>>> torch.tensor([1e-323], dtype=torch.float64)
tensor(9.88131e-324 *
       [ 1.0000], dtype=torch.float64)

可以看出设置了之后,当出现极小数时,直接置为0了。文档中提出该功能必须要系统支持。
'''
训练数据集条数 60000
测试数据集条数 10000
libpng warning: iCCP: cHRM chunk does not match sRGB
该图片的标签为: 9
样本形状: torch.Size([10, 1, 28, 28])
样本标签: tensor([0, 9, 4, 7, 6, 6, 3, 9, 7, 5])
图片形状: torch.Size([3, 32, 302])
T-shirt,Ankle_Boot, Coat,Sneaker,Shirt,Shirt,Dress,Ankle_Boot,Sneaker,Sandal
myConNet(
  (conv1): Conv2d(1, 6, kernel_size=(5, 5), stride=(1, 1))
  (conv2): Conv2d(6, 12, kernel_size=(5, 5), stride=(1, 1))
  (fc1): Linear(in_features=192, out_features=120, bias=True)
  (fc2): Linear(in_features=120, out_features=60, bias=True)
  (out): Linear(in_features=60, out_features=10, bias=True)
)
cpu
[1,  1000] loss: 0.414
[1,  2000] loss: 0.299
[1,  3000] loss: 0.294
[1,  4000] loss: 0.264
[1,  5000] loss: 0.276
[1,  6000] loss: 0.266
[2,  1000] loss: 0.260
[2,  2000] loss: 0.254
[2,  3000] loss: 0.253
[2,  4000] loss: 0.265
[2,  5000] loss: 0.256
[2,  6000] loss: 0.251
Finished Training
图片形状: torch.Size([3, 32, 302])
真实标签:  Ankle_Boot Pullover Trouser Trouser Shirt Trouser  Coat Shirt Sandal Sneaker
预测结果:  Ankle_Boot Pullover Trouser Trouser Shirt Trouser  Coat Shirt Sandal Sneaker
Accuracy of T-shirt : 88 %
Accuracy of Trouser : 95 %
Accuracy of Pullover : 54 %
Accuracy of Dress : 86 %
Accuracy of  Coat : 77 %
Accuracy of Sandal : 96 %
Accuracy of Shirt : 42 %
Accuracy of Sneaker : 95 %
Accuracy of   Bag : 92 %
Accuracy of Ankle_Boot : 92 %
Accuracy of all : 82 %
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PyTorch是一种深度学习框架,它提供了丰富的工具和函数,使得构建和训练神经网络变得更加简单和高效。它被广泛应用于计算机视觉、自然语言处理等领域。 深度学习是一种机器学习方法,其目标是通过模拟人脑神经网络的工作原理来实现各种人工智能任务。深度学习模型通常由许多层神经元组成,每一层都通过学习将输入转换为输出,最终实现复杂的模式识别和预测。 神经网络是一种扩展了传统神经网络的模型,用于处理数据。数据是由节点和边组成的数据结构,常用于表示社交网络、推荐系统等领域的关系。传统的神经网络无法直接处理数据,而神经网络通过引入积等操作,使神经网络能够有效地处理数据,从而提高了对结构的建模能力。 深度学习神经网络在很多领域都取得了显著的进展。例如,在计算机视觉中,深度学习模型可以通过大量的像数据进行训练,实现物体识别、像生成等任务。而神经网络则可以用于分析社交网络中的用户关系、预测交通网络中的交通流量等。它们的电子版提供了对应的理论和实践指导,帮助学者和工程师更好地理解和应用这些技术。 总而言之,PyTorch深度学习神经网络的电子版提供了学习和实践深度学习神经网络的材料,对于研究者和开发者来说是非常有价值的资源。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值