1. import torch
    2. import torch.nn as nn
    3. import torch.utils.data as Data
    4. import torchvision
    5. import matplotlib.pyplot as plt
    6. torch.manual_seed(1) # reproducible
    7. # Hyper Parameters
    8. EPOCH = 5 # 训练整批数据多少次, 为了节约时间, 我们只训练一次
    9. BATCH_SIZE = 50
    10. LR = 0.001 # 学习率
    11. DOWNLOAD_MNIST = True # 如果你已经下载好了mnist数据就写上 False
    12. # Mnist 手写数字
    13. train_data = torchvision.datasets.MNIST(
    14. root='mnist', # 保存或者提取位置
    15. train=True, # this is training data
    16. transform=torchvision.transforms.ToTensor(),
    17. download=DOWNLOAD_MNIST,
    18. )
    19. test_data = torchvision.datasets.MNIST(root='mnist', train=False)
    20. # 批训练 50samples, 1 channel, 28x28 (50, 1, 28, 28)
    21. train_loader = Data.DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True)
    22. # 为了节约时间, 我们测试时只测试前2000个
    23. test_x = torch.unsqueeze(test_data.data, dim=1).type(torch.FloatTensor)[:2000]/255. # shape from (2000, 28, 28) to (2000, 1, 28, 28), value in range(0,1)
    24. test_y = test_data.targets[:2000]
    25. class CNN(nn.Module):
    26. def __init__(self):
    27. super(CNN, self).__init__()
    28. self.conv1 = nn.Sequential( # input shape (1, 28, 28)
    29. nn.Conv2d(
    30. in_channels=1, # input height
    31. out_channels=16, # n_filters
    32. kernel_size=5, # filter size
    33. stride=1, # filter movement/step
    34. padding=2, # 如果想要 con2d 出来的图片长宽没有变化, padding=(kernel_size-1)/2 当 stride=1
    35. ), # output shape (16, 28, 28)
    36. nn.ReLU(), # activation
    37. nn.MaxPool2d(kernel_size=2), # 在 2x2 空间里向下采样, output shape (16, 14, 14)
    38. )
    39. self.conv2 = nn.Sequential( # input shape (16, 14, 14)
    40. nn.Conv2d(16, 32, 5, 1, 2), # output shape (32, 14, 14)
    41. nn.ReLU(), # activation
    42. nn.MaxPool2d(2), # output shape (32, 7, 7)
    43. )
    44. self.out = nn.Linear(32 * 7 * 7, 10) # fully connected layer, output 10 classes
    45. def forward(self, x):
    46. x = self.conv1(x)
    47. x = self.conv2(x)
    48. x = x.view(x.size(0), -1) # 展平多维的卷积图成 (batch_size, 32 * 7 * 7)
    49. output = self.out(x)
    50. return output
    51. cnn = CNN()
    52. print(cnn) # net architecture
    53. cnn=cnn.cuda()
    54. optimizer = torch.optim.Adam(cnn.parameters(), lr=LR) # optimize all cnn parameters
    55. loss_func = nn.CrossEntropyLoss() # the target label is not one-hotted
    56. # training and testing
    57. for epoch in range(EPOCH):
    58. to=0
    59. ac=0
    60. for step, (b_x, b_y) in enumerate(train_loader): # 分配 batch data, normalize x when iterate train_loader
    61. b_x=b_x.cuda()
    62. b_y=b_y.cuda()
    63. output = cnn(b_x) # cnn output
    64. loss = loss_func(output, b_y) # cross entropy loss
    65. optimizer.zero_grad() # clear gradients for this training step
    66. loss.backward() # backpropagation, compute gradients
    67. optimizer.step() # apply gradients
    68. pred_y = torch.max(output, 1)[1].data.cpu().numpy().squeeze()
    69. acc_y=b_y.data.cpu().numpy()
    70. for i in range(len(pred_y)):
    71. if acc_y[i]==pred_y[i]:
    72. ac+=1
    73. to+=1
    74. print("Epoch:",epoch+1,"Acc",ac/to)
    75. test=test_x[:10].cuda()
    76. test_output = cnn(test)
    77. pred_y = torch.max(test_output, 1)[1].data.cpu().numpy().squeeze()
    78. print(pred_y, 'prediction number')
    79. print(test_y[:10].cpu().numpy(), 'real number')

    image.png