昨天跑了一个模型,本身测试结果很好,但是试图加载模型后测试的时候效果很差。
可以看到这里明明已经到了62.55了。这里所谓验证集实际上就是测试集
不知道为什么。为了验证这一点,先只训一个epoch看一下结果,大概2分钟就能跑完。然后看看模型的结果是否和测试准备的一致。
当然,我们也需要看一下模型训出的结果长什么样子。
我们可以看到保存的两个线性层的权重。这两个模型应该是一模一样的,说明读取模型没有问题。
那么更大的可能性是数据load有问题。我们再确认一下测试数据。
这是训练模型搞到的数据
这是测试搞到的数据
这个值也是一模一样的。这说明只有可能是测试的时候测炸了。我们再看这时候的测试代码。
有一个问题很奇怪啊,虽然我知道tqdm用的不对,但是测试数据应该比训练数据少啊,为什么会要4000多个数据呢?
我们直接到最原始的步骤,看每次输入输出。计划看三次。先看训完就测试的。
好像现在唯一的不一样就是,train后的test数据是有batch的。
这是因为,训练的时候所有的batch只会返回一个loss。实际上它输出了更多的脑电数据。但是测试的时候不可以这样。
这样结果就又一样了。因此,这次所谓的bug其实来自于我们在测试的时候给了太多的数据。因此这里的测试结果实际上是假的。实际给的数据是想象数据的batch倍
这次复现的结果就和之前一样了。。。
所以这其实跑了个假模型,怎么说呢,是一个batch的数据才能返回一个差不多的值。这实际上是假的。
后来在师兄的帮助下,才找到correlation是有问题的。这是更正的correlation代码,之前求均值的时候求的是(batch,length)这个矩阵的均值,所以这是一个假的。整个学的都是假的。所以所有东西学不到都是理所当然的。
def correlation(y_pred, y_true):
x = y_pred
y = y_true
xmean = torch.mean(x,1, keepdim=True)
ymean = torch.mean(y,1, keepdim= True)
vx = x - xmean
vy = y - ymean
cov = torch.sum(vx * vy,1, keepdim=True)
corr = cov / (torch.sqrt(torch.sum(vx ** 2,1, keepdim=True)) * torch.sqrt(torch.sum(vy ** 2,1, keepdim=True)) + 1e-12)
corr = torch.maximum(torch.minimum(corr,torch.tensor(1)), torch.tensor(-1))
return corr
在师兄的指导下,以后都会用matlab先算一个结果再来确定python写的对不对,不然每次都被坑,啥也训不出来。这是写的验证程序
import torch
import h5py
import numpy as np
from torch.utils.data import DataLoader
from tqdm import tqdm
from torch.utils.data import Dataset
import torch.nn as nn
def from_mat_to_tensor(raw_data):
#transpose, the dimention of mat and numpy is contrary
Transpose = np.transpose(raw_data)
Nparray = np.array(Transpose)
Torcharray = torch.from_numpy(Nparray)
return Torcharray
def correlation(y_pred, y_true):
x = y_pred
y = y_true
xmean = torch.mean(x,1, keepdim=True)
ymean = torch.mean(y,1, keepdim= True)
vx = x - xmean
vy = y - ymean
cov = torch.sum(vx * vy,1, keepdim=True)
corr = cov / (torch.sqrt(torch.sum(vx ** 2,1, keepdim=True)) * torch.sqrt(torch.sum(vy ** 2,1, keepdim=True)) + 1e-12)
corr = torch.maximum(torch.minimum(corr,torch.tensor(1)), torch.tensor(-1))
return corr.mean()
testing_data = h5py.File('check_correlation.mat')
a1 = from_mat_to_tensor(testing_data['a1'])
a2 = from_mat_to_tensor(testing_data['a2'])
corr_res = from_mat_to_tensor(testing_data['corr_res'])
mean_corr = from_mat_to_tensor(testing_data['mean_corr'])
tmp = correlation(a1,a2)
print(tmp)
这是matlab计算的原始代码
c3;
a1 = rand(32,128);
a2 = rand(32,128);
corr_res = zeros(32,1);
for i = 1:32
corr_res(i) = corr(a1(i,:)',a2(i,:)');
end
mean_corr = mean(corr_res);
save('check_correlation.mat')
经过验证的确是一样的。
再次验证,通过对比训练测试的结果和单独测试的结果
这是训练测试的模型结果
这是训练结束的结果
这是载入测试的结果。可以看到loss和acc都是一样的。说明模型应该没有问题了。我们将batchsize调成1 再试试。理论上由于我们的loss和acc都是在batch平均的,因此结果应该是一致的。如果是一致的说明代码应该没有问题,可以重写其它几个模型了。
发现这个结果和之前的结果完全一致(只是batchsize调成1,测试数据轮次需要4480而batchsize32的时候只需要140) .
因此,导致测试失败的根本原因是损失函数写炸了。直接原因是batchsize的变化(但是实际上损失函数不写炸batchsize变化没问题)