• pytorch 写模型 tensor 常用的操作


    目录

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

    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)

  • 相关阅读:
    YOLO学习
    Linux上部署Jupyter notebook
    SAP 系统License查看申请及导入
    如何避免阿里云对象储存OSS被盗刷
    婴幼儿蛋白质过敏怎么回事
    kubectl资源管理命令-陈述式
    JavaWeb-jdbc的mysql驱动问题
    电路中的常见电源符号的含义VCC,VDD,AVCC,AVDD,GND,AGND,VSS
    c#中的扩展方法
    Node.js 安装配置
  • 原文地址:https://blog.csdn.net/qq_38735017/article/details/126469631