当前位置:   article > 正文

pytorch 写模型 tensor 常用的操作_x.to(device)

x.to(device)

目录

某个维度上做扩张 自身重复

tensor 定义数据类型 避免模型训练出错 

增加一个1维度.unsqueeze(0)  删除一个1维度squeeze(0)

tensor 拼接 cat 其余唯独应该一致

tensor 转换唯独 .transpose(0,1)

tensor 改变形状 reshape

完整的pytorch 开发模板


某个维度上做扩张 自身重复

  1. import torch
  2. from torch import nn
  3. x = torch.randn(1,2,64)
  4. print(x.shape)
  5. y = x.expand(50,2,64)#此时做expand,可以发现(3,)和(2, 3)是第二个维度相同,因此按第一个维度扩张
  6. print(y.shape)

tensor 定义数据类型 避免模型训练出错 

x = x.type(torch.FloatTensor)
  1. def forward(self, x, batch_size):
  2. x = x.type(torch.FloatTensor)
  3. x = x.to(device)

增加一个1维度.unsqueeze(0)  删除一个1维度squeeze(0)

tensor 拼接 cat 其余唯独应该一致

  1. print("137",x_input.shape,temp_aspect.shape)
  2. # 137 torch.Size([50, 2, 64]) torch.Size([50, 2, 64])
  3. x_input=torch.cat((x_input,temp_aspect),dim=2)

tensor 转换唯独 .transpose(0,1)

x_input=x_input.transpose(0,1)

tensor 改变形状 reshape

lstm_out=lstm_out.reshape(batch_size,-1)

完整的pytorch 开发模板

  1. # -*- coding: utf-8 -*-
  2. import pandas as pd
  3. import gensim
  4. import jieba
  5. import re
  6. import matplotlib.pyplot as plt
  7. import numpy as np
  8. from tqdm import tqdm
  9. from sklearn.model_selection import train_test_split
  10. from gensim.models import KeyedVectors
  11. from gensim.scripts.glove2word2vec import glove2word2vec
  12. import torch
  13. from torch import nn
  14. import torch.utils.data as data
  15. import torch.nn.functional as F
  16. from torch import tensor
  17. from sklearn.metrics import f1_score
  18. from datetime import datetime
  19. from torch.utils.data import Dataset, DataLoader
  20. from torch.utils.data import random_split
  21. from tqdm import tqdm
  22. def data_process():
  23. data=pd.read_excel("pre_process_level_2_table(1).xlsx")
  24. data_neirong=list(data['内容'].values)
  25. data_1_aspect=list(data['1_aspect'].values)
  26. data_label=list(data['label'].values)
  27. aspect_vec_dict={}
  28. with open("ceshi_1_aspect_vec.txt","r") as f:
  29. f=f.readlines()
  30. for line in f:
  31. temp_word=line.split("_||_")[0]
  32. temp_vec=line.split("_||_")[1].split(" ")[:-1]
  33. temp_vec=[float(i) for i in temp_vec]# 转化为数值型列表
  34. aspect_vec_dict[temp_word]=temp_vec
  35. print(aspect_vec_dict)
  36. data_neirong_word_list=[]
  37. text_len=[]
  38. for line in data_neirong:
  39. line=line.strip()
  40. line=line.split(" ")
  41. print(line)
  42. while 1 :
  43. print(1)
  44. if '' in line:line.remove('')
  45. if '' not in line:break
  46. data_neirong_word_list.append(line)
  47. text_len.append(len(line))
  48. print("48-----------------------")
  49. # print(max(text_len),np.mean(text_len))# 393 14.989528010696924
  50. # 对句子进行截断重复 设置句子长度是 50
  51. # pading_data_neirong_word_list=[]
  52. data_x = []
  53. temp_data_y=[]
  54. for idx,line in tqdm(enumerate(data_neirong_word_list)):
  55. # print("54",idx, len(line),line)
  56. temp_line = line.copy()
  57. # 会有数据只有空格这样子 这个while 循环会出问题
  58. temp_idx = 0 # 设置while循环标志位 来解决这个问题
  59. if len(line) <60:
  60. while 1:
  61. line=line+temp_line
  62. # print(len(line))
  63. temp_idx+=1
  64. if len(line)>=50:break
  65. if temp_idx==50:break
  66. if temp_idx != 50:
  67. line = line[:50]
  68. data_x.append(line + [data_1_aspect[idx]])
  69. temp_data_y.append(data_label[idx])
  70. print("62----数据数目:---------",len(data_x))
  71. # 矩阵生成
  72. wd2 = gensim.models.Word2Vec.load("wd2.bin")#print(wd2.wv['hotel'])
  73. data_x_vec=[]
  74. # data_x_aspect=[]
  75. data_y=[]
  76. for idx,line in tqdm(enumerate(data_x)):
  77. try:
  78. # print(line)
  79. temp_vec=[]
  80. line_neirong=line[:-1]
  81. line_1_aspect=line[-1]
  82. for word in line_neirong:
  83. temp_vec.append(wd2.wv[word])
  84. temp_vec.append(np.array(aspect_vec_dict[line_1_aspect]))
  85. data_x_vec.append(temp_vec)
  86. data_y.append(temp_data_y[idx])
  87. except KeyError:
  88. pass
  89. return np.array(data_y),np.array(data_x_vec)#,np.array(data_x_aspect)
  90. class mydataset(Dataset):
  91. def __init__(self): # 读取加载数据
  92. data_y,data_x=data_process()
  93. self._x = torch.tensor(np.array(data_x).astype(float))
  94. self._y = torch.tensor(np.array(data_y).astype(float))
  95. print(len(data_x),data_y.shape,data_y)
  96. # self._aspect= torch.tensor(np.array(data_x_aspect).astype(float))
  97. self._len = len(data_y)
  98. def __getitem__(self, item):
  99. return self._x[item], self._y[item]#,self._aspect[item]
  100. def __len__(self): # 返回整个数据的长度
  101. return self._len
  102. mydata = mydataset()
  103. # 划分 训练集 测试集
  104. train_data, test_data = random_split(mydata, [round(0.8 * mydata._len), round(0.2 * mydata._len)]) # 这个参数有的版本没有 generator=torch.Generator().manual_seed(0)
  105. # 随机混乱顺序划分的 四舍五入
  106. #
  107. # train_loader =DataLoader(train_data, batch_size =2, shuffle = True, num_workers = 0 , drop_last=False)
  108. #
  109. # # for step,(train_x,train_y) in enumerate(train_loader):
  110. # # print(step,':',(train_x.shape,train_y.shape),(train_x,train_y))
  111. # # break
  112. #
  113. # # 测试 loader
  114. # test_loader =DataLoader(test_data, batch_size = 2, shuffle = True, num_workers = 0 , drop_last=False)
  115. # # dorp_last 是说最后一组数据不足一个batch的时候 能继续用还是舍弃。 # num_workers 多少个进程载入数据
  116. #
  117. # # 测试
  118. # # for step,(test_x,test_y) in enumerate(test_loader):
  119. # # print(step,':',(test_x.shape,test_y.shape),(test_x,test_y))
  120. device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
  121. class LSTM_attention(nn.Module): # 注意Module首字母需要大写
  122. def __init__(self, ):
  123. super().__init__()
  124. input_size = 64
  125. hidden_size = 64
  126. output_size = 64
  127. # input_size:输入lstm单元向量的长度 ,hidden_size输出lstm单元向量的长度。也是输入、输出隐藏层向量的长度
  128. self.lstm = nn.LSTM(input_size, output_size, num_layers=1) # ,batch_first=True
  129. self.ReLU = nn.ReLU()
  130. self.attention = nn.Linear(6400,64)
  131. self.liner=nn.Linear(128,5)
  132. def forward(self, x, batch_size):
  133. x = x.type(torch.FloatTensor)
  134. x = x.to(device)
  135. x_input=x[:,:50]
  136. x_input=x_input.transpose(0,1)
  137. temp_aspect=x[:,-1]
  138. temp_aspect=temp_aspect.unsqueeze(0)
  139. temp_aspect =temp_aspect.expand(50,batch_size, 64)
  140. #print("137",x_input.shape,temp_aspect.shape)# 137 torch.Size([50, 2, 64]) torch.Size([50, 2, 64])
  141. x_input=torch.cat((x_input,temp_aspect),dim=2)
  142. #print("137",x_input.shape,temp_aspect.shape)# 137 torch.Size([50, 2, 128]) torch.Size([50, 2, 64])
  143. # 输入 lstm的矩阵形状是:[序列长度,batch_size,每个向量的维度] [序列长度,batch, 64]
  144. lstm_out, (h_n, c_n) = self.lstm(x, None)
  145. lstm_out=self.ReLU(lstm_out)
  146. last_lstm=lstm_out[:,-1]# 取最后一个
  147. lstm_out=lstm_out[:,:-1]
  148. lstm_out=lstm_out.transpose(0, 1)
  149. #print("154",lstm_out.shape,temp_aspect.shape)
  150. lstm_out=torch.cat((lstm_out,temp_aspect),dim=2)
  151. lstm_out=lstm_out.transpose(0, 1)
  152. lstm_out=lstm_out.reshape(batch_size,-1)
  153. lstm_out = self.ReLU(lstm_out)
  154. lstm_out = self.attention(lstm_out)
  155. lstm_out = self.ReLU(lstm_out)
  156. # print("157",lstm_out.shape,last_lstm.shape)
  157. out_sum= torch.cat((lstm_out,last_lstm), dim=1)
  158. # print(out_sum.shape)
  159. prediction=self.liner(out_sum)
  160. return prediction
  161. # 这个函数是测试用来测试x_test y_test 数据 函数
  162. def eval_test(model): # 返回的是这10个 测试数据的平均loss
  163. test_epoch_loss = []
  164. with torch.no_grad():
  165. optimizer.zero_grad()
  166. for step, (test_x, test_y) in enumerate(test_loader):
  167. y_pre = model(test_x, batch_size)
  168. test_y = test_y.to(device)
  169. test_loss = loss_function(y_pre, test_y.long())
  170. test_epoch_loss.append(test_loss.item())
  171. return np.mean(test_epoch_loss)
  172. epochs = 50
  173. batch_size = 128
  174. # 在模型测试中 这两个值:batch_size = 19 固定得 epochs = 随便设置
  175. test_loader = DataLoader(test_data, batch_size=batch_size, shuffle=True, num_workers=0, drop_last=True)
  176. train_loader = DataLoader(train_data, batch_size=batch_size, shuffle=True, num_workers=0, drop_last=True)
  177. # 创建LSTM()类的对象,定义损失函数和优化器
  178. model = LSTM_attention().to(device)
  179. loss_function = torch.nn.CrossEntropyLoss().to(device) # 损失函数的计算 交叉熵损失函数计算
  180. optimizer = torch.optim.SGD(model.parameters(), lr=0.01) # 建立优化器实例
  181. print(model)
  182. sum_train_epoch_loss = [] # 存储每个epoch 下 训练train数据的loss
  183. sum_test_epoch_loss = [] # 存储每个epoch 下 测试 test数据的loss
  184. best_test_loss = 10000
  185. for epoch in tqdm(range(epochs)):
  186. epoch_loss = []
  187. for step, (train_x, train_y) in enumerate(train_loader):
  188. y_pred = model(train_x, batch_size)
  189. # 训练过程中,正向传播生成网络的输出,计算输出和实际值之间的损失值
  190. # print(y_pred,train_y)
  191. single_loss = loss_function(y_pred.cpu(), train_y.long())
  192. # print("single_loss",single_loss)
  193. single_loss.backward() # 调用backward()自动生成梯度
  194. optimizer.step() # 使用optimizer.step()执行优化器,把梯度传播回每个网络
  195. epoch_loss.append(single_loss.item())
  196. train_epoch_loss = np.mean(epoch_loss)
  197. test_epoch_loss = eval_test(model) # 测试数据的平均loss
  198. if test_epoch_loss < best_test_loss:
  199. best_test_loss = test_epoch_loss
  200. print("best_test_loss", best_test_loss)
  201. best_model = model
  202. sum_train_epoch_loss.append(train_epoch_loss)
  203. sum_test_epoch_loss.append(test_epoch_loss)
  204. print("epoch:" + str(epoch) + " train_epoch_loss: " + str(train_epoch_loss) + " test_epoch_loss: " + str(
  205. test_epoch_loss))
  206. torch.save(best_model, 'best_model.pth')
  207. # 画图
  208. # sum_train_epoch_loss=[]
  209. # sum_test_epoch_loss=[]
  210. fig = plt.figure(facecolor='white', figsize=(10, 7))
  211. plt.xlabel('第几个epoch')
  212. plt.ylabel('loss值')
  213. plt.xlim(xmax=len(sum_train_epoch_loss), xmin=0)
  214. plt.ylim(ymax=max(sum_train_epoch_loss), ymin=0)
  215. # 画两条(0-9)的坐标轴并设置轴标签x,y
  216. x1 = [i for i in range(0, len(sum_train_epoch_loss), 1)] # 随机产生300个平均值为2,方差为1.2的浮点数,即第一簇点的x轴坐标
  217. y1 = sum_train_epoch_loss # 随机产生300个平均值为2,方差为1.2的浮点数,即第一簇点的y轴坐标
  218. x2 = [i for i in range(0, len(sum_test_epoch_loss), 1)]
  219. y2 = sum_test_epoch_loss
  220. colors1 = '#00CED4' # 点的颜色
  221. colors2 = '#DC143C'
  222. area = np.pi * 4 ** 1 # 点面积
  223. # 画散点图
  224. plt.scatter(x1, y1, s=area, c=colors1, alpha=0.4, label='train_loss')
  225. plt.scatter(x2, y2, s=area, c=colors2, alpha=0.4, label='val_loss')
  226. # plt.plot([0,9.5],[9.5,0],linewidth = '0.5',color='#000000')
  227. plt.legend()
  228. # plt.savefig(r'C:\Users\jichao\Desktop\大论文\12345svm.png', dpi=300)
  229. plt.show()
  230. import sklearn
  231. from sklearn.metrics import accuracy_score
  232. # 模型加载:
  233. model.load_state_dict(torch.load('best_model.pth').cpu().state_dict())
  234. model.eval()
  235. test_pred = []
  236. test_true = []
  237. with torch.no_grad():
  238. optimizer.zero_grad()
  239. for step, (test_x, test_y) in enumerate(test_loader):
  240. y_pre = model(test_x, batch_size).cpu()
  241. y_pre = torch.argmax(y_pre, dim=1)
  242. for i in y_pre:
  243. test_pred.append(i)
  244. for i in test_y:
  245. test_true.append(i)
  246. Acc = accuracy_score(test_pred, test_true)
  247. print(Acc)

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

闽ICP备14008679号