当前位置:   article > 正文

【李宏毅机器学习网课作业一】简单的RNN实现与结果(cuda加速),附模型_cuda rnn

cuda rnn

工程结构:

 

training.py: 

数据预处理部分显得非常笨拙……请大家指教。

  1. import numpy as np
  2. import pandas as pd
  3. from network import RNN
  4. from dataset import MyDataset
  5. from sklearn.model_selection import KFold
  6. import torch
  7. import torch.nn as nn
  8. import torch.utils.data.dataloader as DataLoader
  9. import matplotlib.pyplot as plt
  10. # Prepare data
  11. data = pd.DataFrame(pd.read_csv("train.csv"))
  12. pmData = data.query('測項=="PM2.5"')
  13. trainData = np.array(pmData.drop(['日期', '測站', '測項'], axis=1))
  14. trainData = np.delete(trainData, 0, 0)
  15. trainData = np.delete(trainData, 0, 1)
  16. trainData = trainData.flatten()
  17. (n,) = trainData.shape
  18. print(n)
  19. cycleData = trainData[0:9]
  20. cycleData = cycleData.reshape((1, 9))
  21. cycleLabel = trainData[9:]
  22. cycleLabel = cycleLabel.reshape((-1, 1))
  23. for i in range(1, n - 9):
  24. cycleData = np.append(cycleData, trainData[i:i + 9].reshape((1, 9)), 0)
  25. cycleData = cycleData.astype(np.float32)
  26. cycleLabel = cycleLabel.astype(np.float32)
  27. print(cycleData.shape) # [5488,9]
  28. print(cycleLabel.shape) # [5488,1]
  29. # cuda setting
  30. assert torch.cuda.is_available()
  31. cuda_device = torch.device("cuda") # device object representing GPU
  32. # training setting
  33. errors = []
  34. k_folds = 8 # 8折
  35. epochs = 30
  36. lr = [0.001, 0.001, 0.004, 0.008, 0.01, 0.04, 0.08, 0.1] # 学习率
  37. batch_size = 7
  38. criterion = nn.MSELoss(reduce=True)
  39. criterion.cuda()
  40. h_state = torch.zeros([1, batch_size, 32]) # 32对应网络定义中的hidden size即隐藏神经元个数
  41. kf = KFold(n_splits=k_folds)
  42. fold = 0
  43. for train_index, test_index in kf.split(cycleData):
  44. # 为节约时间,此处实际上只进行了一折
  45. if (fold != 0):
  46. break
  47. dataset = MyDataset(cycleData[train_index], cycleLabel[train_index])
  48. dataloader = DataLoader.DataLoader(dataset, batch_size=batch_size, shuffle=True)
  49. net = RNN()
  50. net = net.float()
  51. net.cuda()
  52. optimizer = torch.optim.Adam(net.parameters(), lr=lr[fold])
  53. # training loss
  54. err_list = []
  55. print("\ntraining...")
  56. for _ in range(epochs):
  57. epoch_loss = 0
  58. for i, (x, lbs) in enumerate(dataloader):
  59. outputs, h_state = net(x.float().cuda(), h_state.cuda())
  60. # print(outputs.shape)
  61. # print(h_state.shape)
  62. outputs = outputs[:, -1, :]
  63. h_state = h_state.detach()
  64. lbs = lbs.squeeze(1)
  65. loss = criterion(outputs, lbs.cuda())
  66. # backpropagation
  67. optimizer.zero_grad()
  68. loss.backward()
  69. optimizer.step()
  70. epoch_loss += torch.sum((outputs.cuda() - lbs.cuda()) ** 2).item() / batch_size
  71. err_list.append(epoch_loss / i)
  72. print(err_list)
  73. errors.append(err_list)
  74. # paint the learning curve
  75. plt.figure(fold)
  76. x = range(len(errors[-1]))
  77. y = errors[-1]
  78. plt.plot(x, y)
  79. plt.title("k=" + str(fold) + ", lr=" + str(lr[fold]))
  80. plt.show()
  81. fold += 1
  82. torch.save(net, 'RNN_' + str(fold) + '.pkl')

network.py:

一个网上到处都是的简单结构

  1. import torch.nn as nn
  2. class RNN(nn.Module):
  3. def __init__(self):
  4. super(RNN, self).__init__()
  5. self.rnn = nn.RNN(
  6. input_size=1,
  7. hidden_size=32,
  8. num_layers=1,
  9. batch_first=True
  10. )
  11. self.out = nn.Linear(32, 1)
  12. def forward(self, x, h):
  13. out, h = self.rnn(x, h)
  14. prediction = self.out(out)
  15. return prediction, h

dataset.py:

简单粗暴的dataset,好像使用的必要性不大,但是习惯了这种……

  1. from torch.utils.data import Dataset
  2. import torch
  3. class MyDataset(Dataset):
  4. def __init__(self, a, b):
  5. self.file = torch.from_numpy(a).unsqueeze(-1)
  6. self.label = torch.from_numpy(b).unsqueeze(-1)
  7. def __getitem__(self, index):
  8. seq = self.file[index]
  9. label = self.label[index]
  10. return seq, label
  11. def __len__(self):
  12. return self.label.shape[0]

testing.py

把training.py改了改……其实数据处理都是重复的

  1. import numpy as np
  2. import pandas as pd
  3. from network import RNN
  4. from dataset import MyDataset
  5. from sklearn.model_selection import KFold
  6. import torch
  7. import torch.nn as nn
  8. import torch.utils.data.dataloader as DataLoader
  9. import matplotlib.pyplot as plt
  10. #Prepare data
  11. data = pd.DataFrame(pd.read_csv("train.csv"))
  12. pmData = data.query('測項=="PM2.5"')
  13. trainData = np.array(pmData.drop(['日期','測站','測項'],axis=1))
  14. trainData = np.delete(trainData,0,0)
  15. trainData = np.delete(trainData,0,1)
  16. trainData = trainData.flatten()
  17. (n,) = trainData.shape
  18. print(n)
  19. cycleData = trainData[0:9]
  20. cycleData = cycleData.reshape((1,9))
  21. cycleLabel = trainData[9:]
  22. cycleLabel = cycleLabel.reshape((-1,1))
  23. for i in range(1,n-9):
  24. cycleData = np.append(cycleData,trainData[i:i+9].reshape((1,9)),0)
  25. cycleData = cycleData.astype(np.float32)
  26. cycleLabel = cycleLabel.astype(np.float32)
  27. print(cycleData.shape)
  28. print(cycleLabel.shape)
  29. #cuda setting
  30. assert torch.cuda.is_available()
  31. cuda_device = torch.device("cuda") # device object representing GPU
  32. #training setting
  33. errors = []
  34. k_folds = 8
  35. epochs = 30
  36. lr = [0.001, 0.001, 0.004, 0.008, 0.01, 0.04, 0.08, 0.1]
  37. batch_size = 1 #注意修改此处!!
  38. criterion = nn.MSELoss(reduce=True)
  39. criterion.cuda()
  40. h_state = torch.zeros([1,batch_size,32])
  41. kf = KFold(n_splits=8)
  42. fold = 0
  43. for train_index, test_index in kf.split(cycleData):
  44. #实际上只测试了一个模型
  45. if(fold!=0):
  46. break
  47. testset = MyDataset(cycleData[test_index], cycleLabel[test_index])
  48. testloader = DataLoader.DataLoader(testset)
  49. labels = cycleLabel[test_index].flatten().tolist()
  50. net = torch.load('RNN_1.pkl')#实际上只测试了一个模型
  51. net.eval()
  52. predict = []
  53. with torch.no_grad():
  54. for x, lbs in testloader:
  55. outputs, h_state = net(x.float().cuda(), h_state.cuda())
  56. outputs = outputs[:, -1, :]
  57. h_state = h_state.detach()
  58. lbs = lbs.squeeze(1)
  59. loss = criterion(outputs, lbs.cuda())
  60. predict.append(outputs.squeeze(1).item())
  61. plt.figure(fold)
  62. x = range(len(predict))
  63. plt.plot(x, labels, color='orange', label='label')
  64. plt.plot(x, predict, color='cyan', label='predict')
  65. plt.legend()
  66. plt.title("model RNN_1")
  67. plt.show()
  68. fold += 1

结果:

总结:

1、个人认为,按此方法处理数据以后,其实并没有使用RNN的必要,普通NN将九个输入视为九个特征完全可以达到差不多的效果。但显然RNN参数更少。时间有限,此模型没有调参,但基于样本量,完全可以使RNN结构更复杂一点。

2、代码学习借鉴了网络上各种博客,感谢!同时欢迎纠错和提问。

3、模型资源以上传,审核通过后会附上链接。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/617269
推荐阅读
相关标签
  

闽ICP备14008679号