当前位置:   article > 正文

本文简单教学一下Pytorch实现对数据的DNN、RNN、CNN等操作(基于面向对象的CPU版本)_dnn torch 实现

dnn torch 实现

1.导入模块、库和框架

  1. import numpy as np
  2. from sklearn.datasets import load_iris, load_digits
  3. import torch
  4. from sklearn.metrics import accuracy_score, classification_report
  5. from sklearn.model_selection import train_test_split
  6. from transformers import get_cosine_schedule_with_warmup
  7. from transformers import AdamW
  8. import warnings
  9. import torch.nn.functional as F
  10. warnings.filterwarnings('ignore')

2.定义一个类用来设置随机种子以及复现代码

  1. class SetSeed:
  2. def same_seeds(self, seed):
  3. torch.manual_seed(seed) # 固定随机种子(CPU)
  4. if torch.cuda.is_available(): # 固定随机种子(GPU)
  5. torch.cuda.manual_seed(seed) # 为当前GPU设置
  6. torch.cuda.manual_seed_all(seed) # 为所有GPU设置
  7. np.random.seed(seed) # 保证后续使用random函数时,产生固定的随机数
  8. torch.backends.cudnn.benchmark = False # GPU、网络结构固定,可设置为True
  9. torch.backends.cudnn.deterministic = True # 固定网络结构
'
运行

3. 定义数据处理类

  1. class ProcessData: # 数据处理类
  2. def __init__(self):
  3. self.dataX, self.dataY = load_digits(return_X_y=True) # 导入数据:手写字体数据集(分类任务)
  4. self.dataX, self.dataY = np.float32(self.dataX), torch.Tensor(self.dataY).long() # 将数字转为tensor或者可以输入进网络的格式
  5. def dataToLoader(self): # 这个方法可以作为DataLoader的中间件,其中包含数据集划分等操作
  6. self.trainDataX, self.midDataX, self.trainDataY, self.midDataY = train_test_split(
  7. self.dataX,
  8. self.dataY,
  9. stratify=self.dataY, # 采样分布同总体一样,克服采样不均匀问题
  10. random_state=1,
  11. test_size=0.2
  12. )
  13. self.testDataX, self.devDataX, self.testDataY, self.devDataY = train_test_split(
  14. self.midDataX,
  15. self.midDataY,
  16. stratify=self.midDataY,
  17. random_state=1,
  18. test_size=0.5
  19. )
  20. trainDataForLoader = list(zip(self.trainDataX, self.trainDataY))
  21. devDataForLoader = list(zip(self.devDataX, self.devDataY))
  22. testDataForLoader = list(zip(self.testDataX, self.testDataY))
  23. self.trainLoader = torch.utils.data.DataLoader(dataset=trainDataForLoader,
  24. batch_size=8,
  25. # collate_fn=False,
  26. shuffle=True,
  27. drop_last=True)
  28. self.devLoader = torch.utils.data.DataLoader(dataset=devDataForLoader,
  29. batch_size=8,
  30. # collate_fn=False,
  31. shuffle=True,
  32. drop_last=True)
  33. self.testLoader = torch.utils.data.DataLoader(dataset=testDataForLoader,
  34. batch_size=8,
  35. # collate_fn=False,
  36. shuffle=True,
  37. drop_last=True)
  38. return self.trainLoader, self.devLoader, self.testLoader
'
运行

4.定义一些基础的模型类

  1. class FNN(torch.nn.Module):
  2. def __init__(self):
  3. super(FNN, self).__init__()
  4. self.fc = torch.nn.Linear(64, 256)
  5. self.fc2 = torch.nn.Linear(256, 10)
  6. self.softmax = torch.nn.Softmax()
  7. self.dropout = torch.nn.Dropout(p=0.5)
  8. self.tanh = torch.nn.Tanh()
  9. # self.bn = torch.nn.BatchNorm1d()
  10. def forward(self, x):
  11. # out = self.bn(x)
  12. # print(x)
  13. out = self.fc(x)
  14. out = self.dropout(out)
  15. out = self.tanh(out)
  16. out = self.fc2(out)
  17. out = self.dropout(out)
  18. logits = self.tanh(out)
  19. # print(logits)
  20. # prob = self.softmax(logits)
  21. return logits
  22. class SelfAttention(torch.nn.Module):
  23. def __init__(self, hidden_dim):
  24. super().__init__()
  25. self.projection = torch.nn.Sequential(
  26. torch.nn.Linear(hidden_dim, 64),
  27. torch.nn.ReLU(True),
  28. torch.nn.Linear(64, 1))
  29. def forward(self, encoder_outputs):
  30. energy = self.projection(encoder_outputs) # (B, L, H) -> (B , L, 1)
  31. weights = F.softmax(energy, dim=1)
  32. outputs = encoder_outputs * weights # (B, L, H)
  33. return outputs
  34. class RNN(torch.nn.Module):
  35. def __init__(self):
  36. super(RNN, self).__init__()
  37. self.fc = torch.nn.Linear(200, 10)
  38. self.fc2 = torch.nn.Linear(256, 10)
  39. self.softmax = torch.nn.Softmax()
  40. self.dropout = torch.nn.Dropout(p=0.5)
  41. self.tanh = torch.nn.Tanh()
  42. self.bn = torch.nn.BatchNorm1d(64)
  43. self.lstm = torch.nn.LSTM(64, 100, 2, bidirectional=True, batch_first=True, dropout=0.5)
  44. def forward(self, x):
  45. # out = self.bn(x)
  46. x = x.unsqueeze(dim=1)
  47. out, _ = self.lstm(x)
  48. out = self.tanh(out)
  49. out = self.fc(out)
  50. out = self.dropout(out)
  51. out = self.tanh(out)
  52. # out = self.fc2(out)
  53. # out = self.tanh(out)
  54. # logits = self.dropout(out)
  55. # prob = self.softmax(logits)
  56. prob = out.squeeze(dim=1)
  57. return prob
  58. class RNN_ATT(torch.nn.Module):
  59. def __init__(self):
  60. super(RNN_ATT, self).__init__()
  61. self.fc = torch.nn.Linear(200, 10)
  62. self.fc2 = torch.nn.Linear(256, 10)
  63. self.softmax = torch.nn.Softmax()
  64. self.dropout = torch.nn.Dropout(p=0.5)
  65. self.tanh = torch.nn.Tanh()
  66. self.bn = torch.nn.BatchNorm1d(64)
  67. self.lstm = torch.nn.LSTM(64, 100, 2, bidirectional=True, batch_first=True, dropout=0.5)
  68. self.attention = SelfAttention(100 * 2)
  69. def forward(self, x):
  70. # out = self.bn(x)
  71. x = x.unsqueeze(dim=1)
  72. out, _ = self.lstm(x)
  73. out = self.tanh(out)
  74. out=self.attention(out)
  75. out = self.tanh(out)
  76. out = self.fc(out)
  77. out = self.dropout(out)
  78. out = self.tanh(out)
  79. # out = self.fc2(out)
  80. # out = self.tanh(out)
  81. # logits = self.dropout(out)
  82. # prob = self.softmax(logits)
  83. prob = out.squeeze(dim=1)
  84. return prob
  85. class CNN(torch.nn.Module):
  86. def __init__(self):
  87. super(CNN, self).__init__()
  88. self.fc = torch.nn.Linear(64, 256)
  89. self.fc2 = torch.nn.Linear(64, 10)
  90. self.softmax = torch.nn.Softmax()
  91. self.dropout = torch.nn.Dropout(p=0.5)
  92. self.tanh = torch.nn.Tanh()
  93. self.conv1d = torch.nn.Conv1d(64, 10, kernel_size=1)
  94. self.conv1d_t = torch.nn.Conv1d(8, 8, kernel_size=1)
  95. # self.maxpool1d = torch.nn.MaxPool1d(kernel_size=4, stride=None, padding=0, dilation=1,
  96. # return_indices=False, ceil_mode=False)
  97. self.flatten = torch.nn.Flatten(start_dim=0, end_dim=1)
  98. # self.bn = torch.nn.BatchNorm1d()
  99. def forward(self, x):
  100. x = x.unsqueeze(dim=2)
  101. print(x.size())
  102. out = self.conv1d(x)
  103. out = self.flatten(out)
  104. prob = self.softmax(out)
  105. # ------------------------------------
  106. # x = x.unsqueeze(dim=0)
  107. # out = self.conv1d_t(x)
  108. # # out = self.maxpool1d(out)
  109. # out = self.flatten(out)
  110. # out = self.fc2(out)
  111. # # print(out)
  112. # # print(out.size())
  113. # prob = self.softmax(out)
  114. return prob
  115. class CNN2(torch.nn.Module):
  116. def __init__(self):
  117. super(CNN2, self).__init__()
  118. self.conv1 = torch.nn.Conv2d(1, 10, kernel_size=2)
  119. self.conv2 = torch.nn.Conv2d(10, 20, kernel_size=2)
  120. self.conv2_drop = torch.nn.Dropout2d()
  121. self.fc1 = torch.nn.Linear(720, 50)
  122. self.fc2 = torch.nn.Linear(490, 10)
  123. self.flatten = torch.nn.Flatten()
  124. def forward(self, x):
  125. x = np.array(x)
  126. x = x.reshape(8, 1, 8, 8)
  127. x = np.float32(x)
  128. x = torch.tensor(x)
  129. x = self.conv1(x)
  130. # x = F.dropout2d(x)
  131. x = F.max_pool2d(x, kernel_size=1)
  132. x = F.relu(x)
  133. x = self.flatten(x)
  134. x = F.dropout(x, training=self.training)
  135. x = self.fc2(x)
  136. return x

5.定义主类(包括训练、验证和测试方法)

  1. class Main(ProcessData, SetSeed):
  2. def __init__(self, model):
  3. super(Main, self).__init__()
  4. self.model = model
  5. self.trainLoader = self.dataToLoader()[0]
  6. self.devLoader = self.dataToLoader()[1]
  7. self.testLoader = self.dataToLoader()[2]
  8. self.optimizer = AdamW(model.parameters(), lr=2e-5, weight_decay=1e-4) # 使用Adam优化器
  9. # 设置学习率
  10. self.schedule = get_cosine_schedule_with_warmup(self.optimizer, num_warmup_steps=len(self.trainLoader),
  11. num_training_steps=10 * len(self.testLoader))
  12. self.criterion = torch.nn.CrossEntropyLoss()
  13. def train(self):
  14. self.same_seeds(20)
  15. bestAcc = 0.0
  16. for i in range(400):
  17. self.model.train() # 开始训练
  18. print("***************Running training epoch{}************".format(i + 1))
  19. train_loss_sum = 0.0
  20. for idx, (X, y) in enumerate(self.trainLoader):
  21. yPred = self.model(X)
  22. # print(yPred)
  23. # print(y)
  24. loss = self.criterion(yPred, y)
  25. # loss=self.criterion()
  26. self.optimizer.zero_grad()
  27. loss.backward()
  28. self.optimizer.step()
  29. self.schedule.step()
  30. train_loss_sum += loss.item()
  31. devAcc = self.__evaluate(self.model, self.devLoader)
  32. print(devAcc)
  33. if devAcc > bestAcc:
  34. bestAcc = devAcc
  35. torch.save(self.model.state_dict(), "checkpoint/best_model.pth")
  36. testAcc = self.__predict(self.model, self.testLoader)
  37. torch.save(self.model.state_dict(), "checkpoint/best_model2.pth")
  38. print(testAcc)
  39. def __evaluate(self, model, data_loader):
  40. model.eval() # 防止模型训练改变权值
  41. devTrue, devPred = [], []
  42. with torch.no_grad(): # 计算的结构在计算图中,可以进行梯度反转等操作
  43. for idx, (X, y) in enumerate(data_loader): # 得到的y要转换一下数据格式
  44. yPred = model(X) # 此时得到的是概率矩阵
  45. yPred = torch.argmax(yPred, dim=1).detach().cpu().numpy().tolist() # 将概率矩阵转换成标签并变成list类型
  46. devPred.extend(yPred) # 将标签值放入列表
  47. devTrue.extend(y.squeeze().cpu().numpy().tolist()) # 将真实标签转换成list放在列表中
  48. return accuracy_score(devTrue, devPred)
  49. def __predict(self, model, data_loader):
  50. model.eval() # 防止模型训练改变权值
  51. testTrue, testPred = [], []
  52. with torch.no_grad(): # 计算的结构在计算图中,可以进行梯度反转等操作
  53. for idx, (X, y) in enumerate(data_loader): # 得到的y要转换一下数据格式
  54. yPred = model(X) # 此时得到的是概率矩阵
  55. yPred = torch.argmax(yPred, dim=1).detach().cpu().numpy().tolist() # 将概率矩阵转换成标签并变成list类型
  56. testPred.extend(yPred) # 将标签值放入列表
  57. testTrue.extend(y.squeeze().cpu().numpy().tolist()) # 将真实标签转换成list放在列表中
  58. return classification_report(testTrue, testPred)

定义测试类,可供调试以及部署API模型

  1. class Test(SetSeed):
  2. def __init__(self):
  3. self.path = 'checkpoint/best_model2.pth'
  4. def test(self, model, data):
  5. self.same_seeds(1)
  6. data = torch.Tensor(data)
  7. model = model
  8. model.eval()
  9. model.load_state_dict(torch.load(self.path))
  10. y_pred_prob = model(data) # 此时得到的是概率矩阵
  11. y_pred = torch.argmax(y_pred_prob, dim=1).detach().cpu().numpy().tolist()
  12. # print(y_pred_prob)
  13. print('预测值:', y_pred[0])

6.主函数入口

  1. if __name__ == '__main__':
  2. model = RNN_ATT()
  3. main = Main(model)
  4. main.train()
  5. # index = 348
  6. # dataX, _ = load_digits(return_X_y=True)
  7. # dataMidList = []
  8. # data = dataX[index, :].reshape(8, -1)
  9. # print('真实数据:', _[index])
  10. # import matplotlib.pyplot as plt
  11. # plt.imshow(data, cmap='gray', interpolation='none')
  12. # plt.show()
  13. # data = dataX[index, :]
  14. # dataMidList.append(data)
  15. # for _ in range(7):
  16. # vecMid = [0 for _ in range(64)]
  17. # dataMidList.append(vecMid)
  18. # # print(dataMidList)
  19. # # data = dataX[1, :].reshape(1, -1)
  20. # data = np.array(dataMidList).reshape(8, 1, 8, 8)
  21. # # print(data)
  22. # test = Test()
  23. # test.test(model, data)
  24. # data = torch.rand([3, 3])
  25. # # print(data)
  26. # data1 = data.unsqueeze(dim=0)
  27. # print(data1)

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/酷酷是懒虫/article/detail/897160
推荐阅读
相关标签
  

闽ICP备14008679号