• 《PyTorch深度学习实践》第十三课(循环神经网络RNN高级版)


    b站刘二视频,地址:

    《PyTorch深度学习实践》完结合集_哔哩哔哩_bilibili

    网络模型

    通过RNN模型,实现输出名字,对应出国家的功能

    构造数据列表 

     长短不一,构造成一样

    将国家做成输出索引 

    导入数据

    如果以后数据集为pickle及其他的都可以用这种方法

    模型

    embedding层参数 

     

    GRU层参数

     bidirection双向神经网络

    双向,两边都走一遍,再拼接起来,起到了连接上下文的作用

    最终输出的output,hidden

    其中output是上面的h0到hn,output是【hnf,hnb】

    最终的hidden是两个 

    gru中因为序列长短不一,许多填充的是0,没必要参加运算,可以加速,使用 pack_padded_sequence

    embedding 过程

    返回一个PackedSquence object

     把为0的去除,其他的拼接在一起,但是他要求的是输入序列的长度递减,所以不行

    因此需要排序

    接下来是横着取值,按照时间序列取值,可以并行计算

    留下了batch_sizes,gru就可以据此得出需要取多少行

     由名字转换为tensor的过程

     step1 转换为ascII

     step2 做填充 

     step3做转置

     step4 排序

    完整代码

    1. import csv
    2. import gzip
    3. import math
    4. import time
    5. import torch
    6. import matplotlib.pyplot as plt
    7. import numpy as np
    8. from torch.nn.utils.rnn import pack_padded_sequence
    9. from torch.utils.data import Dataset
    10. from torch.utils.data import DataLoader
    11. HIDDEN_SIZE = 100
    12. BATCH_SIZE = 256
    13. N_LAYER = 2
    14. N_EPOCHS = 200
    15. N_CHARS = 128
    16. USE_GPU = False
    17. def time_since(since):
    18. s = time.time() - since
    19. m = math.floor(s / 60)
    20. s -= m * 60
    21. return '%dm %ds' %(m, s)
    22. def name2list(name):
    23. arr = [ord(c) for c in name]#得到ascii码
    24. return arr, len(arr)
    25. def create_tensor(tensor):
    26. if USE_GPU:
    27. device = torch.device("cuda:0")
    28. tensor = tensor.to(device)
    29. return tensor
    30. def make_tensors(names, countries):
    31. sequences_and_lengths = [name2list(name) for name in names]# s[0] name s[1] 长度
    32. name_sequences = [s1[0] for s1 in sequences_and_lengths]
    33. seq_lengths = torch.LongTensor([s1[1] for s1 in sequences_and_lengths])
    34. countries = countries.long()
    35. #make tensor of name, BatchSize x seqlen
    36. seq_tensor = torch.zeros(len(name_sequences), seq_lengths.max()).long()
    37. for idx, (seq, seqlen) in enumerate(zip(name_sequences, seq_lengths), 0):
    38. seq_tensor[idx, :seqlen] = torch.LongTensor(seq)
    39. #sort by length to use pack padded sequence
    40. seq_lengths, perm_idx = seq_lengths.sort(dim=0, descending=True) #sort 返回两个值 1.排序完的表 2.相对应的索引
    41. seq_tensor = seq_tensor[perm_idx]
    42. countries = countries[perm_idx]
    43. return create_tensor(seq_tensor), \
    44. create_tensor(seq_lengths), \
    45. create_tensor(countries)
    46. class NameDataset(Dataset):
    47. def __init__(self, is_train_set=True):
    48. filename = 'names_train.csv.gz' if is_train_set else 'name_test.csv.gz'
    49. with gzip.open(filename, 'rt') as f:
    50. reader = csv.reader(f)
    51. rows = list(reader)
    52. self.names = [row[0] for row in rows]
    53. self.len = len(self.names)
    54. self.countries = [row[1] for row in rows]
    55. self.country_list = list(sorted(set(self.countries)))
    56. self.country_dict = self.getCountryDict()
    57. self.country_num = len(self.country_list)
    58. def __getitem__(self, idx):
    59. return self.names[idx], self.country_dict[self.countries[idx]]
    60. def __len__(self):
    61. return self.len
    62. def getCountryDict(self):
    63. country_dict = dict()
    64. for idx, country_name in enumerate(self.country_list, 0):
    65. country_dict[country_name] = idx
    66. return country_dict
    67. def idx2country(self, index):
    68. return self.country_list[index]
    69. def getCountriesNum(self):
    70. return self.country_num
    71. trainset = NameDataset(True)
    72. trainloader = DataLoader(trainset, batch_size=BATCH_SIZE, shuffle=True)
    73. testset = NameDataset(True)
    74. testloader = DataLoader(testset, batch_size=BATCH_SIZE, shuffle=True)
    75. N_COUNTRY = trainset.getCountriesNum()
    76. class RNNClassifier(torch.nn.Module):
    77. def __init__(self, input_size, hidden_size, output_size, n_layers=1, bidirectional=True):
    78. super(RNNClassifier, self).__init__()
    79. self.hidden_size = hidden_size
    80. self.n_layers = n_layers
    81. self.n_directions = 2 if bidirectional else 1
    82. self.embedding = torch.nn.Embedding(input_size, hidden_size)
    83. self.gru = torch.nn.GRU(hidden_size, hidden_size, n_layers,
    84. bidirectional=bidirectional)
    85. self.fc = torch.nn.Linear(hidden_size * self.n_directions, output_size)
    86. # 如果是双向的,最终hidden是两,要乘上2
    87. def init_hidden(self, batch_size):
    88. hidden = torch.zeros(self.n_layers * self.n_directions,
    89. batch_size, self.hidden_size)
    90. return create_tensor(hidden)
    91. def forward(self, input, seq_lengths):
    92. # input shape : B x S -> S x B
    93. input = input.t()
    94. batch_size = input.size(1)
    95. hidden = self.init_hidden(batch_size)
    96. embedding = self.embedding(input)
    97. #pack them up
    98. gru_input = pack_padded_sequence(embedding, seq_lengths)
    99. output, hidden = self.gru(gru_input, hidden)
    100. if self.n_directions == 2:
    101. hidden_cat = torch.cat([hidden[-1], hidden[-2]], dim=1)
    102. else:
    103. hidden_cat = hidden[-1]
    104. fc_output = self.fc(hidden_cat)
    105. return fc_output
    106. def trainModel():
    107. total_loss = 0
    108. for i, (names, countries) in enumerate(trainloader, 1):#1 代表索引i从1开始,也代表轮数
    109. inputs, seq_lengths, target = make_tensors(names, countries)
    110. output = classifier(inputs, seq_lengths)
    111. loss = criterion(output, target)
    112. optimizer.zero_grad()
    113. loss.backward()
    114. optimizer.step()
    115. total_loss += loss.item()
    116. if i % 10 == 0:
    117. print(f'[{time_since(start)}] Epoch {epoch}', end='')
    118. print(f'[{i * len(inputs)} / {len(trainset)}]', end='')
    119. print(f'loss={total_loss / (i * len(inputs))}')
    120. return total_loss
    121. def testModel():
    122. correct = 0
    123. total = len(testset)
    124. print('evaluating trained model ...')
    125. with torch.no_grad():
    126. for i, (names, countries) in enumerate(testloader, 1):
    127. inputs, seq_lengths, target = make_tensors(names, countries)
    128. output = classifier(inputs, seq_lengths)
    129. pred = output.max(dim=1, keepdim=True)[1]
    130. correct += pred.eq(target.view_as(pred)).sum().item()
    131. percent = '%.2f' % (100 * correct / total)
    132. print(f'Test set: Accuracy {correct} / {total} {percent}%')
    133. return correct / total
    134. if __name__ == '__main__':
    135. classifier = RNNClassifier(N_CHARS, HIDDEN_SIZE, N_COUNTRY, N_LAYER)
    136. # 字母表的个数 隐层 国家数 层数
    137. if USE_GPU: #用GPU训练
    138. device = torch.device("cuda:0")
    139. classifier.to(device)
    140. criterion = torch.nn.CrossEntropyLoss()
    141. optimizer = torch.optim.Adam(classifier.parameters(), lr=0.001)
    142. start = time.time()
    143. print("Training for %d epochs..." % (N_EPOCHS + 1))
    144. acc_list = []
    145. for epoch in range(1, N_EPOCHS + 1):
    146. trainModel()
    147. acc = testModel()
    148. acc_list.append(acc)
    149. epoch = np.arange(1, len(acc_list) + 1, 1)
    150. acc_list = np.array(acc_list)
    151. plt.plot(epoch, acc_list)
    152. plt.xlabel('Epoch')
    153. plt.ylabel('Accuracy')
    154. plt.grid()
    155. plt.show()

  • 相关阅读:
    【开发小记】vue项目打包可视化
    SpringBoot 整合 数据库连接池(Druid、HicariCP、C3P0等等)
    Spring Boot技术知识点:如何解读@Valid注解
    Linux安装Nginx详细步骤
    面试算法12:左右两边子数组的和相等
    CSS基础选择器
    AI聊天ChatGPT系统源码卡密验证开源版
    【C++笔记】第二十五篇 内建函数对象
    TiDB、OceanBase、PolarDB-X、CockroachDB二级索引写入性能测评
    触发器,寄存器,三态输出电路
  • 原文地址:https://blog.csdn.net/falldeep/article/details/126691899