任务介绍

一维:计算内积dot(1xn,1xn)——>一个数
二维:dot(nxm.mxn)——>nxn

  • 对应元素相乘:Numpy.multiply或“*”

nxm*nxm——>nxm

三层网络的架构

image.png
使用numpy实现神经网络的前向传播过程,并算出输出层的最终输出结果。为了完成上述任务我们需要进行如下假设:
1.输入的值为[3,5]
2.隐藏层h1的两个权重为[2,4]、[4,-5]
3.隐藏层h2的两个权重为[-1,1]、[2,2]
4.输出层的权重为[-3,7]
5.所有层不使用偏置
6.所有隐藏层需添加tanh激活函数

  1. input_data = np.array([3, 5])
  2. # 定义数据,作为输入数据
  3. input_data = np.array([3, 5])
  4. # 定义各个节点权重
  5. weights = {
  6. 'h11': np.array([2, 4]),
  7. 'h12': np.array([4, -5]),
  8. 'h21': np.array([-1, 1]),
  9. 'h22': np.array([2, 2]),
  10. 'out': np.array([-3, 7])
  11. }
  12. # 定义tanh激活函数
  13. def tanh(x):
  14. return (np.exp(x) - np.exp(-x)) / (np.exp(x) + np.exp(-x))
  15. # 输入层数据与第一隐层权重相乘、求和,并输入激活函数中
  16. hidden_11_value = tanh( (input_data * weights['h11']).sum() )
  17. hidden_12_value = tanh( (input_data * weights['h12']).sum() )
  18. hidden_1_output = np.array([hidden_11_value, hidden_12_value])
  19. # 第一层输出数据与第二层隐层权重相乘、求和,并输入到激活函数
  20. hidden_21_value = tanh( (hidden_1_output * weights['h21']).sum() )
  21. hidden_22_value = tanh( (hidden_1_output * weights['h22']).sum() )
  22. hidden_2_output = np.array([hidden_21_value, hidden_22_value])
  23. # 输出层,无激活函数
  24. output = (hidden_2_output * weights['out']).sum()
  25. print(output)

CIFAR-10图像分类

神经网络训练步骤如下:

1.清空优化器梯度
2.读入data和label
3.运行模型前向传播过程
4.基于模型输出生成最终结果
5.计算损失
6.基于损失计算梯度
7.基于梯度更新参数

  1. outputs = net(inputs) # 模型前向传播
  2. loss.backwards() # 用于计算梯度
  3. optimizer.step() # 用于参数更新
  4. optimizer.zero_grad() # 用于清空优化器梯度
  5. inputslabel = data # 用于读取data和label
  6. inputs = inputs.view(-1, 32*32*3) # 用于对输入形状进行变化
  7. preds

模型测评过程中的数据导入、前向传播过程与训练过程基本相同。

完整步骤
1.大for循环-epochs,用于管理一套数据循环训练几遍
2.小for循环-step,用于以batchsize为单位,从dataloader中调取数据
3.清空优化器的梯度
4.读入data和label,并进行形状变换(可做可不做)
5.运行模型前向传播过程
6.基于模型输出生成最终结果
7.计算损失
8.基于损失计算梯度
9.基于梯度更新参数

  1. # 基础运算库
  2. import numpy as np
  3. # 深度学习库
  4. import torch
  5. import torch.nn as nn
  6. import torch.optim as optim
  7. import torchvision
  8. import torch.nn.functional as F
  9. import torchvision.transforms as transforms
  10. # 辅助绘图库
  11. import matplotlib.pyplot as plt
  12. # 时间操作库
  13. import time
  14. # 进度条控制库
  15. from tqdm import tqdm
  16. transform = transforms.Compose([
  17. transforms.ToTensor(),
  18. transforms.Normalize(
  19. (0.49140, 0.48216, 0.44653),
  20. (0.24703, 0.24349, 0.26159) )
  21. ])
  22. trainset = torchvision.datasets.CIFAR10(root=r'.', train=True, download=True, transform=transforms)
  23. testset = torchvision.datasets.CIFAR10(root='.', train=False, download=True, transform=transforms)
  24. trainloader = torch.utils.data.DataLoader(trainset, batch_size=16, shuffle=16)
  25. testloader = torch.utils.data.DataLoader(testset, batch_size=16, shuffle=16)
  26. print(trainset.classes) # 查看类别
  27. # 搭建简单神经网络
  28. class Net(nn.Module):
  29. def __init__(self):
  30. super(Net, self).__init__()
  31. self.fc1 = nn.Linear(32*32*3, 1000)
  32. self.fc2 = nn.Linear(1000, 500)
  33. self.fc3 = nn.Linear(500, 10)
  34. def forward(self, x):
  35. x = F.relu(self.fc1(x))
  36. x = F.relu(self.fc2(x))
  37. return self.fc3(x)
  38. net = Net()
  39. # 定义损失函数
  40. criteria = nn.CrossEntropyLoss()
  41. # 定义优化器,将神经网络参数传入,并定义学习率
  42. optimizer = optim.Adam(net.parameters(), lr=1e-4)
  43. # 神经网络训练
  44. num_epochs = 10
  45. since = time.time()
  46. net.train()
  47. for epoch in range(num_epochs):
  48. print(f"Epoch {epoch + 1}/{num_epochs}")
  49. running_loss = 0.0
  50. running_correct = 0
  51. for data in tqdm(trainloader):
  52. # 清空梯度
  53. optimizer.zero_grad()
  54. inputs, labels = data
  55. outputs = net(inputs.view(-1, 32*32*3))
  56. loss = criteria(outputs, labels)
  57. loss.backward()
  58. optimizer.step()
  59. _, preds = torch.max(outputs, 1)
  60. running_loss += loss.item() * inputs.size(0)
  61. running_correct += torch.sum(preds == labels)
  62. epoch_loss = running_loss / trainloader.dataset.data.shape[0]
  63. epoch_acc = running_correct.double() / trainloader.dataset.data.shape[0]
  64. print("train loss: {:.4f} Acc: {:.4f}".format(epoch_loss, epoch_acc))
  65. print('+++'*10)
  66. time_elapsed = time.time() - since
  67. print('Training complete in "{:0f}m{:.0f}s'.format(time_elapsed // 60, time_elapsed % 60))
  68. # 模型评估
  69. correct, total = 0, 0
  70. net.eval()
  71. for data in tqdm(testloader):
  72. inputs, labels = data
  73. inputs = inputs.view(-1, 32*32*3)
  74. outputs = net(inputs)
  75. _, predict = torch.max(outputs, 1)
  76. total += labels.size(0)
  77. correct += (predict == labels).sum().item()
  78. print("The test set accuracy of network is: %d %%" % (100 * correct / total))

可视化查看图片

  1. #把图片进行可视化展示
  2. #定义画图的函数
  3. def imshow(inp, title=None):
  4. """Imshow for Tensor."""
  5. #定义画图的画布
  6. fig = plt.figure(figsize=(30, 30))
  7. #转换图片的纬度
  8. inp = inp.numpy().transpose((1, 2, 0))
  9. mean = np.array([0.485, 0.456, 0.406])
  10. std = np.array([0.229, 0.224, 0.225])
  11. #对图片进行标准化
  12. inp = std * inp + mean
  13. #整个图片数组的值限制在指定值a_min,与a_max之间
  14. inp = np.clip(inp, 0, 1)
  15. #对图片进行可视化展示
  16. plt.imshow(inp, )
  17. # 获取一个batch的数据
  18. inputs, classes = next(iter(trainloader))
  19. # 以网格的格式展示,作用是将若干幅图像拼成一幅图像
  20. out = torchvision.utils.make_grid(inputs)
  21. # plt.imshow()就可显示图片同时也显示其格式。
  22. imshow(out, title=[trainset.classes[x] for x in classes])