高维数组的矩阵操作
模型要输出6个标签,相互不互斥,每个子标签又三个结果分别是0,1,2互斥。
所以模型出的结果用list将6个tensor进行append。
这6个tensor每一个都是一个batch(体现gpu批量加速,批量前提是是执行相同的操作),数据标签的shape为[batch_size,6],注意这是输入进去的真是label的size,pytorch的celoss不需要onehot。
模型输出的是list,内含6个tensor,每个tensor shape为[batch_size,3]。
实例:
class Model(nn.Module):
def __init__(self,config):
super(Model,self).__init__()
self.bert = BertModel.from_pretrained(config.bert_path)
self.class_list = config.class_list
for param in self.bert.parameters():
param.requires_grad = True
self.fc = nn.Linear(config.hidden_size,config.num_class)
def forward(self,x):
context = x[0]
mask = x[2]
_,pooled = self.bert(context,attention_mask=mask)
# out = self.fc(pooled)
# return out
res_lst = []
for _ in range(len(self.class_list)):
res_lst.append(self.fc(pooled))
return res_lst
在预测时候,因为有六个标签,最一般的做法是遍历方法如下,需要遍历6次,数据量大速度慢。
def multioutput_keyf1(outputs,labels):
'''
:param outputs:
:param labels:
:return: this batch all datas' 6 key_f1 scores(scale), and all predict result shape like labels(np)
'''
softmax = nn.Softmax(dim=1)
measurement = []
for j in range(len(outputs)):
predic = torch.argmax(softmax(outputs[j]), dim=1)
predic_np = np.expand_dims(predic.data.cpu().numpy(),0)#输出是向量,为了后面转至和label格式相同
if j == 0:
predict_all = predic_np
else:
predict_all = np.append(predict_all, predic_np,axis=0)
# 不加权,特别关注模型预测1而且正确的f1值,0很容易对,不要综合
f1 = metrics.f1_score(labels[:, j].view(-1).data.cpu().numpy(), predic.view(-1).data.cpu().numpy(),
labels=[0,1,2],average=None)
tmp_mean = np.mean([f1[0],f1[1]])
measurement.append(tmp_mean)#得到6个值的list,代表6个标签的keyf1_score
return np.mean(measurement),predict_all.T
使用矩阵的操作方法:
def predict(config, model, predict_iter):
model.load_state_dict(torch.load(config.save_path))
model.eval()
with torch.no_grad():
for texts, _ in predict_iter:
outputs = model(texts)
outputs = torch.cat(outputs,axis=1)
outputs = outputs.reshape([-1, len(config.class_list), 3])
outputs = torch.argmax(outputs, axis=-1)
return outputs.numpy()
- torch.cat(outputs,axis=1)将list拼接起来,axis=1是按照列拼接,实例如下:
t1 = torch.randn(2,3)
t2 = torch.randn(2,3)
t3 = torch.randn(2,3)
t4 = torch.randn(2,3)
l = [t1,t2,t3,t4]
l2 = torch.cat(l,axis=1)
print(t1)
print(t1)
print(t2)
t1
tensor([[ 1.8190, 1.8762, 0.8932],
[-0.8871, 0.9053, 0.2084]])
t2
tensor([[-1.1744, -1.6724, 0.2678],
[-0.4754, -0.3456, 1.8783]])
l2
tensor([[ 1.8190, 1.8762, 0.8932, -1.1744, -1.6724, 0.2678, -0.1065, -1.8081,
0.3286, 0.3663, 0.1786, -1.8346],
[-0.8871, 0.9053, 0.2084, -0.4754, -0.3456, 1.8783, -1.2582, 1.5560,
-0.9482, 0.5541, -0.0414, -0.8095]])
#4个标签组,每个三个标签,batchsize=2
l4= l2.reshape([-1, 4, 3])
np.argmax(l4, axis=-1)
tensor([[[ 1.8190, 1.8762, 0.8932],
[-1.1744, -1.6724, 0.2678],
[-0.1065, -1.8081, 0.3286],
[ 0.3663, 0.1786, -1.8346]],
[[-0.8871, 0.9053, 0.2084],
[-0.4754, -0.3456, 1.8783],
[-1.2582, 1.5560, -0.9482],
[ 0.5541, -0.0414, -0.8095]]])
tensor([[1, 2, 2, 0],
[1, 2, 1, 0]])
数据拼接
得到若干个numpy想要拼接成一个numpy。
res = 0
if index == 0:
res = outputs.numpy()
else:
res = np.append(res,outputs.numpy(),axis=0)
- 注意np.append的结果需要赋值出来才行