1 原因
- 可能在图片数据集加载时,shuffle设置为True了,需要改为False
- 在模型中,一些层中Dropout,Normalization等具有随机性,需要设置一下种子
- 没有开启net.eval()模式
2 解决方法
import 各种包
seed = 0 # 设置一个种子,确保可以复现
torch.manual_seed(seed)
torch.cuda.manual_seed(seed)
torch.cuda.manual_seed_all(seed) # if you are using multi-GPU.
np.random.seed(seed) # Numpy module.
random.seed(seed) # Python random module.
torch.manual_seed(seed)
torch.backends.cudnn.benchmark = False
torch.backends.cudnn.deterministic = True
def train():
test_loader = DataLoader(dataset=test_dataset,batch_size=batch_size, shuffle=False, drop_last=False)
net.eval()
for i in range(epoch):
...
- seed设置
- shuffle=False
- net.eval() 打开
之所以每次在测试集上的结果不同的原因持续更新中。。。
3 评价指标计算方式代码
def Precision(predict, target): # 计算Precision
if torch.is_tensor(predict): # 模型本身有sigmoid函数
predict = predict.data.cpu().numpy()
if torch.is_tensor(target):
target = target.data.cpu().numpy()
total_pre = 0.0
for i in range(predict.shape[0]): # 这是batch_size的大小,计算这个batch_size中所有图片的precision
pre_split = predict[i]
tar_split = target[i]
pre_split = pre_split.astype(numpy.bool)
tar_split = tar_split.astype(numpy.bool)
tn = numpy.count_nonzero(~pre_split & ~tar_split)
tp = numpy.count_nonzero(pre_split & tar_split)
fn = numpy.count_nonzero(~pre_split & tar_split)
fp = numpy.count_nonzero(~tar_split & pre_split)
try:
pre = tp / float(tp + fp)
except ZeroDivisionError:
pre = 0.0
total_pre += pre
return total_pre
total_pre = 0.0
for i, (image, label) in enumerate(test_loader):
...
total_pre += Precision(pred, label)
...
print(total_spe/len(test_dataset)) # 这里除的是图片的数量,而不是batch_size的数量。