创建神经网络: - 图1前向传播:
y=torch.mul(w,x) #等价于w*x
y=torch.mm(w,x)
z=torch.add(y,b) #等价于y+b

  1. #定义输入张量x
  2. x = torch.tensor(2.0, requires_grad=True)
  3. # 初始化权重参数W,偏移量b、并设置require_grad属性为True,自动跟踪历史导数
  4. w=torch.randn(1,requires_grad=True) # torch.rand(2,2,requires_grad=True)
  5. b=torch.randn(1,requires_grad=True)
  6. # 实现前向传播
  7. y=torch.mul(w,x) #等价于w*x
  8. z=torch.add(y,b) #等价于y+b
  9. #查看x,w,b页子节点的requite_grad属性
  10. # requires_grad(自动获取梯度)设置为True
  11. print("x,w,b的require_grad属性分别为:{},{},{}".format(x.requires_grad,w.requires_grad,b.requires_grad))
  12. print(x)
  13. print("w",w)
  14. print('b',b)
  15. print('y',y)
  16. print('z',z)

反向传播:

  1. y3.backward()

手动实现机器学习:

  1. import torch
  2. from IPython import display
  3. from matplotlib import pyplot as plt
  4. import numpy as np
  5. import random
  6. %matplotlib inline

微信图片_20201207232553.jpg
微信图片_20201207232606.jpg
微信图片_20201207232914.jpg

构建神经网络:

定义模型 类创建,CLASS Net(父类:nn.moudle)
初始化函数: 参数-n_feature 特征个数
继承:super(Net,self).__init—(), 初始化父类
初始化自己:self.linear=nn.linear(输入特征维度,输出维度,偏置=True默认)
遍历 for item in self.linear.params:
参数出来了
初始化参数: nn.init.normul(item,m=,)
定义前向传播
y = self.linear(x)
return y
实例化对象

  1. import numpy as np
  2. import torch
  3. from torch import nn

初始化模型参数

损失函数:
优化算法:
训练模型
单独611.png
image.pngimage.pngimage.pngimage.pngimage.png

  1. class Net(nn.Module):
  2. """
  3. 使用sequential构建网络,Sequential()函数的功能是将网络的层组合到一起
  4. """
  5. #indim 输入维度. n_hidden 隐藏层个数
  6. def __init__(self, in_dim, n_hidden_1, n_hidden_2, out_dim):
  7. #继承父类属性
  8. super(Net, self).__init__()
  9. #定义自己每一层,Sequential,拼接每一层方法(第一步线性连接nn.linear(输入,输出),第二归一化处理nn.BatchNorm1d(n_hidden_1))
  10. self.layer1 = nn.Sequential(nn.Linear(in_dim, n_hidden_1),nn.BatchNorm1d(n_hidden_1))
  11. self.layer2 = nn.Sequential(nn.Linear(n_hidden_1, n_hidden_2),nn.BatchNorm1d(n_hidden_2))
  12. self.layer3 = nn.Sequential(nn.Linear(n_hidden_2, out_dim))
  13. def forward(self, z):
  14. #
  15. z = F.relu(self.layer1(z))
  16. z = F.relu(self.layer2(z))
  17. z = self.layer3(z)
  18. return z
  19. model = Net(28 * 28, 300, 100, 10)

字体识别

  1. import numpy as np
  2. import torch
  3. # 导入 pytorch 内置的 mnist 数据
  4. from torchvision.datasets import mnist
  5. #导入预处理模块
  6. import torchvision.transforms as transforms
  7. from torch.utils.data import DataLoader
  8. #导入nn及优化器
  9. import torch.nn.functional as F
  10. import torch.optim as optim
  11. from torch import nn
  12. import matplotlib.pyplot as plt
  13. %matplotlib inlin

说明

①transforms.Compose可以把一些转换函数组合在一起;
②Normalize([0.5], [0.5])对张量进行归一化,这里两个0.5分别表示对张量进行归一化的全局平均值和方差。因图像是灰色的只有一个通道,如果有多个通道,需要有多个数字,如三个通道,应该是Normalize([m1,m2,m3], [n1,n2,n3])
③download参数控制是否需要下载,如果./data目录下已有MNIST,可选择False。
④用DataLoader得到生成器,这可节省内存。

  1. train_batch_size = 64
  2. test_batch_size = 128
  3. learning_rate = 0.01
  4. num_epoches = 20
  5. lr = 0.01
  6. momentum = 0.5
  1. #定义预处理函数,这些预处理依次放在Compose函数中。
  2. transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize([0.5], [0.5])])
  3. #下载数据,并对数据进行预处理
  4. train_dataset = mnist.MNIST('./data', train=True, transform=transform, download=True)
  5. test_dataset = mnist.MNIST('./data', train=False, transform=transform)
  6. #dataloader是一个可迭代对象,可以使用迭代器一样使用。
  7. train_loader = DataLoader(train_dataset, batch_size=train_batch_size, shuffle=True)
  8. test_loader = DataLoader(test_dataset, batch_size=test_batch_size, shuffle=False)
  9. examples = enumerate(test_loader)
  10. batch_idx, (example_data, example_targets) = next(examples)
  11. fig = plt.figure()
  12. for i in range(6):
  13. plt.subplot(2,3,i+1)
  14. plt.tight_layout()
  15. # example_data[i][0] 这个操作是拿出
  16. plt.imshow(example_data[i][0], cmap='summer', interpolation='none')
  17. plt.title("Ground Truth: {}".format(example_targets[i]))

创建神经网络预测:

  1. class Net(nn.Module):
  2. """
  3. 使用sequential构建网络,Sequential()函数的功能是将网络的层组合到一起
  4. """
  5. def __init__(self, in_dim, n_hidden_1, n_hidden_2, out_dim):
  6. super(Net, self).__init__()
  7. self.layer1 = nn.Sequential(nn.Linear(in_dim, n_hidden_1),nn.BatchNorm1d(n_hidden_1))
  8. self.layer2 = nn.Sequential(nn.Linear(n_hidden_1, n_hidden_2),nn.BatchNorm1d(n_hidden_2))
  9. self.layer3 = nn.Sequential(nn.Linear(n_hidden_2, out_dim))
  10. def forward(self, z):
  11. z = F.relu(self.layer1(z))
  12. z = F.relu(self.layer2(z))
  13. z = self.layer3(z)
  14. return z
  1. #检测是否有可用的GPU,否则使用CPU
  2. # device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
  3. #实例化网络,定义隐藏层个数
  4. model = Net(28 * 28, 300, 100, 10)
  5. # model.to(device)
  6. # 定义损失函数和优化器
  7. # 定义交叉熵损失
  8. criterion = nn.CrossEntropyLoss()
  9. # 梯度下降model.parameters() 所有参数,矩阵
  10. optimizer = optim.SGD(model.parameters(), lr=lr, momentum=momentum)

训练模型

  1. # 开始训练
  2. losses = [] #训练
  3. acces = []
  4. eval_losses = [] #评估
  5. eval_acces = []
  6. for epoch in range(num_epoches):
  7. train_loss = 0
  8. train_acc = 0
  9. # 训练模式
  10. model.train()
  11. #动态修改参数学习率
  12. if epoch%5==0:
  13. optimizer.param_groups[0]['lr']*=0.1
  14. # 做训练
  15. for img, label in train_loader:
  16. # img=img.to(device)
  17. # label = label.to(device)
  18. # n行一列
  19. img = img.view(img.size(0), -1)
  20. # 前向传播
  21. out = model(img)
  22. # 计算损失
  23. loss = criterion(out, label)
  24. # 反向传播
  25. optimizer.zero_grad()
  26. loss.backward()
  27. # 参数更新
  28. optimizer.step()
  29. # 记录误差
  30. train_loss += loss.item() #python
  31. # 计算分类的准确率
  32. _, pred = out.max(1)
  33. num_correct = (pred == label).sum().item()
  34. acc = num_correct / img.shape[0]
  35. train_acc += acc
  36. losses.append(train_loss / len(train_loader))
  37. acces.append(train_acc / len(train_loader))
  38. # 在测试集上检验效果
  39. eval_loss = 0
  40. eval_acc = 0
  41. # 将模型改为预测模式
  42. model.eval()
  43. for img, label in test_loader:
  44. img=img.to(device)
  45. label = label.to(device)
  46. img = img.view(img.size(0), -1)
  47. out = model(img)
  48. loss = criterion(out, label)
  49. # 记录误差
  50. # .item() 转化为python可以识别的类型
  51. eval_loss += loss.item()
  52. # 记录准确率
  53. _, pred = out.max(1)
  54. #判断布尔索引是否相等,求和
  55. num_correct = (pred == label).sum().item()
  56. acc = num_correct / img.shape[0]
  57. # 每一层循环的损失都累加一次,
  58. eval_acc += acc
  59. eval_losses.append(eval_loss / len(test_loader))
  60. eval_acces.append(eval_acc / len(test_loader))
  61. print('epoch: {}, Train Loss: {:.4f}, Train Acc: {:.4f}, Test Loss: {:.4f}, Test Acc: {:.4f}'
  62. .format(epoch, train_loss / len(train_loader), train_acc / len(train_loader),
  63. eval_loss / len(test_loader), eval_acc / len(test_loader)))