同一测试数据集,多次预测结果出现不一致,如何解决?
收藏
###### 问题遇到的现象和发生背景
问题1:
同一测试数据集,多次预测结果出现不一致。
```
模型在测试集上准确率为:12.73%
模型在测试集上准确率为:11.82%
```
问题2:
预测准确率和验证准确率相差甚大,这是何因?
```bash
Epoch 326/500
step 277/277 - loss: 1.0348 - acc: 0.9214 - 77ms/step
save checkpoint at /home/aistudio/data/checkpoint/325
Eval begin...
step 31/31 - loss: 1.6716 - acc: 0.2215 - 60ms/step
Eval samples: 492
Epoch 327/500
step 277/277 - loss: 1.0705 - acc: 0.9225 - 75ms/step
save checkpoint at /home/aistudio/data/checkpoint/326
Eval begin...
step 31/31 - loss: 1.7314 - acc: 0.2236 - 56ms/step
```
###### 问题相关代码,请勿粘贴截图
```python
class SampleNet(paddle.nn.Layer):
"""
构建网络Embedding
"""
def __init__(self, tag_dict: dict, size_dict: dict, emb_size, emb_linear_size, type_size):
# 继承Model
super().__init__()
# 新建一个隐藏层列表,用于存储各字段隐藏层对象
self.hidden_layers_list = []
# 定义一个用于记录输出层的输入大小变量,经过一个emb的网络结构就增加该结构的output_dim,以此类推
out_layer_input_size = 0
self.relu = paddle.nn.LeakyReLU() # relu函数,全连接层默认的激活函数是None
self.drop = paddle.nn.Dropout(p=0.2) # 正则化方法
# dict_list为需要处理的数据列表,forward中使用。注意如果前面字段改了,这里也需要改
self.dict_list = tag_dict.values()
for tag, tag_method in tag_dict.items():
# ===== 网络结构方法注册 =====
# Embedding方法注册
if tag_method == "emb":
emb = nn.Embedding(num_embeddings=size_dict[tag], embedding_dim=emb_size) # 定义多个字段的emb处理方法,添加到一个列表中
self.hidden_layers_list.append(emb)
elif tag_method == "norm":
continue
elif tag_method is None:
continue
else:
raise Exception(str(tag_method) + "为未知的处理方案")
self.lstm = nn.LSTM(emb_size, 128, 1)
self.lin_emb = nn.Linear(in_features=128, out_features=emb_linear_size)
self.lin_norm1 = nn.Linear(in_features=1, out_features=3)
self.lin_norm2 = nn.Linear(in_features=3, out_features=1)
# self.hidden_layers_list.append(hidden_layer)
# 定义输出层
self.out_layers = nn.Linear(in_features=1674, # 注意,如果层数改了,这个地方需要重新计算
out_features=200)
self.out_layers1 = nn.Linear(in_features=200,
out_features=type_size)
# 前向推理部分 `*input_data`的`*`表示传入任一数量的变量
def forward(self, *input_data):
"""
:param input_data:
:return:
"""
layer_list = [] # 用于存储各字段特征结果
num_id = 0
for sample_data, tag_method in zip(input_data, self.dict_list): # 读取前面定义的字段
tmp = sample_data
if tag_method == "emb":
emb = self.hidden_layers_list[num_id]
tmp = emb(tmp)
tmp, (_, _) = self.lstm(tmp)
tmp = self.lin_emb(tmp)
tmp = self.relu(tmp)
num_id += 1
elif tag_method == "norm":
tmp = self.lin_norm1(tmp)
tmp = self.relu(tmp)
tmp = self.lin_norm2(tmp)
tmp = self.relu(tmp)
elif tag_method is None:
continue
else:
raise Exception(str(tag_method) + "为未知的处理方案")
layer_list.append(tensor.flatten(tmp, start_axis=1)) # flatten是因为原始shape为[batch size, 1 , *n], 需要变换为[bs, n]
# 对所有字段的特征合并
layers = tensor.concat(layer_list, axis=1)
# 把特征放入用于输出层的网络
layers = self.out_layers(layers)
layers = self.relu(layers)
layers = self.drop(layers) # 将42个神经单元随机丢失0.2
layers = self.out_layers1(layers)
layers = self.relu(layers)
layers = paddle.nn.functional.softmax(layers)
# 返回分类结果
return layers
```
```python
def emb_train(mtype, mtype_size, is_infer=False, test_batch_size=32, epochs=10, train_batch_size=10,
emb_size=128, emb_linear_size=64, num_workers=0):
"""
emb_train
:param mtype: 模型类型
:param mtype_size: 类型值
:param is_infer: 是否为推理模式
:param test_batch_size: 若因内存/显存发生报错,请优先调整为1
:param epochs: 训练多少个循环
:param train_batch_size: mini_batch 大小
:param emb_size: Embedding特征大小
:param emb_linear_size: Embedding后接Linear层神经元数量
:param num_workers: 线程数
"""
set_seed(args.seed)
# 配置训练环境
USE_MINI_DATA = False # 默认使用小数据集,此方法可加快模型产出速度,但可能会影响准确率
USE_GPU = True # 线性任务GPU可能提升不明显甚至掉速
print(paddle.CUDAPlace(0))
paddle.set_device("gpu")
paddle.disable_static(place=paddle.CUDAPlace(0) if USE_GPU else paddle.CPUPlace())
# 定义网络输入
inputs = []
for tag_name, tag_m in TAGS.items():
d_type = "float32"
if tag_m == "emb":
d_type = "int64"
if tag_m is None:
continue
inputs.append(InputSpec(shape=[-1, 1], dtype=d_type, name=tag_name))
# 定义Label
labels = [InputSpec([-1, 1], 'int64', name='label')]
# 实例化SampleNet以及Reader
model = paddle.Model(SampleNet(TAGS, get_dict(), emb_size, emb_linear_size, mtype_size), inputs=inputs,
labels=labels)
# 推理部分
if is_infer:
infer_reader = ReaderEmb(mtype=mtype, is_infer=is_infer)
model.load(os.path.join(args.model, mtype + "/final"))
# 开始推理
model.prepare()
infer_output = model.predict(infer_reader, test_batch_size)
# 获取原始表中的字段并添加推理结果
result_df = infer_reader.df.loc[:, ["new_issue", "result", "label"]]
pack = []
for batch_out in infer_output[0]:
for sample in batch_out:
pack.append(np.argmax(sample))
acc_score = accuracy_score(result_df["label"], pack)
print('模型在测试集上准确率为:%.2f%%' % (acc_score * 100))
result_df.rename(columns={'label': 'label_' + mtype}, inplace=True)
result_df.to_csv(args.result_dir + "result_{}.csv".format(mtype), index=False)
print("结果文件保存至:", args.result_dir)
# 直接训练完推理结果
else:
# 定义学习率,并加载优化器参数到模型中
# total_steps = (int(450000) + 1)
# lr = paddle.fluid.dygraph.PolynomialDecay(0.01, total_steps, 0.001)
# 获取训练集和测试集数据读取器
# lr = paddle.optimizer.lr.PolynomialDecay(learning_rate=0.0008, decay_steps=total_steps*3, end_lr = 0.00008),用了这个发现效果更差,干脆不用
# model.load(os.path.join(SAVE_DIR, "1"))
# lr = paddle.optimizer.lr.PiecewiseDecay(boundaries=[1, 2], values=[0.001, 0.0001, 0.00001], verbose=True)
train_reader = ReaderEmb(mtype=mtype, use_mini_train=USE_MINI_DATA)
val_reader = ReaderEmb(mtype=mtype, use_mini_train=USE_MINI_DATA, is_val=True)
# 定义优化器
optimizer = paddle.optimizer.Adam(learning_rate=0.0007, parameters=model.parameters()) # 直接将学习率设置为固定0.0007
# 模型训练配置
model.prepare(optimizer, paddle.nn.loss.CrossEntropyLoss(), Accuracy())
# 开始训练
model.fit(train_data=train_reader, # 训练集数据
eval_data=val_reader, # 交叉验证集数据
batch_size=train_batch_size, # Batch size大小
epochs=epochs, # 训练轮数
log_freq=1000, # 日志打印间隔
save_dir=args.model + mtype, # checkpoint保存路径
num_workers=num_workers)
```
###### 运行结果及报错内容
W0707 11:38:35.289726 4444 device_context.cc:447] Please NOTE: device: 0, GPU Compute Capability: 6.1, Driver API Version: 11.6, Runtime API Version: 10.1
CUDAPlace(0)
W0707 11:38:35.314658 4444 device_context.cc:465] device: 0, cuDNN Version: 7.6.
Predict begin...
step 4/4 [==============================] - 49ms/step
Predict samples: 110
模型在测试集上准确率为:12.73%
结果文件保存至: ./data/result/
--------------
CUDAPlace(0)
W0707 14:30:54.401885 6108 device_context.cc:447] Please NOTE: device: 0, GPU Compute Capability: 6.1, Driver API Version: 11.6, Runtime API Version: 10.1
W0707 14:30:54.423830 6108 device_context.cc:465] device: 0, cuDNN Version: 7.6.
Predict begin...
step 4/4 [==============================] - 58ms/step
Predict samples: 110
模型在测试集上准确率为:11.82%
结果文件保存至: ./data/result/
0
收藏
请登录后评论