Computer vision 为什么我从两个参数和输入相同的模型中得到两个不同的结果?

Computer vision 为什么我从两个参数和输入相同的模型中得到两个不同的结果?,computer-vision,conv-neural-network,pytorch,transfer-learning,Computer Vision,Conv Neural Network,Pytorch,Transfer Learning,我将resnet18加载到我的两个模型(model1和model2)中,并带有预训练的权重 我想把它们用作功能提取器 对于model1:我冻结了除最后一个线性层model1.fc之外的参数,然后对其进行训练。培训后,我将model1.fc设置为torch.nn.Identity() 对于model2:我直接将model2.fc设置为torch.nn.Identity() 那么这两个模型应该是相同的,但是我从相同的输入中得到不同的正向结果 如果没有完成model1的训练,它们将得到相同的结果,可能

我将resnet18加载到我的两个模型(model1和model2)中,并带有预训练的权重

我想把它们用作功能提取器 对于model1:我冻结了除最后一个线性层model1.fc之外的参数,然后对其进行训练。培训后,我将model1.fc设置为torch.nn.Identity() 对于model2:我直接将model2.fc设置为torch.nn.Identity()

那么这两个模型应该是相同的,但是我从相同的输入中得到不同的正向结果

如果没有完成model1的训练,它们将得到相同的结果,可能是参数冻结有问题。 然而,在对model1进行培训并将两个模型的最后一层设置为identity layer之后,我检查了它们的参数,它们似乎是相同的

将numpy导入为np
进口火炬
导入torch.nn作为nn
将torch.optim导入为optim
从torchvision导入数据集、转换、模型
#在ImageNet上预训练的负载权重
def装载重量(型号):
model_dir=“…”
model.load\u state\u dict(tor`enter code here`ch.utils.model\u zoo.load\u url(“https://download.pytorch.org/models/resnet18-5c106cde.pth“,model_dir=model_dir))
回归模型
model1=models.resnet18()
模型1=荷载重量(模型1)
对于model1.parameters()中的参数:
param.requires_grad=False
model1.fc=nn.Linear(512,2)
模型1.cuda()
optimizer=optim.SGD(model1.fc.parameters(),lr=1e-2,momentum=0.9)
结果\u冻结=\
运行训练(模型1,优化器,设备,训练装载机,val装载机,次数=10)
model2=models.resnet18()
模型2=荷载重量(模型2)
model2.fc=nn.Identity()
模型2.cuda()
model1.fc=nn.Identity()
模型1.cuda()
#检查转发结果(提取特征)
#这里的批量是1
对于枚举(X\u序列)中的批处理(数据,目标):
数据,目标=数据到(设备),目标到(设备)
d=数据
X_系列特征[batch_idx]=model1(数据).cpu().detach().numpy()
y_train[batch_idx]=target.cpu().detach().numpy()
X_train2_特性[batch_idx]=model2(d).cpu().detach().numpy()
y_train2[batch_idx]=target.cpu().detach().numpy()
打印(总和(X列特征[batch\u idx]==X列特征[batch\u idx]))
打印(总和(y_列[batch_idx]==y_列2[batch_idx]))
打印(torch.sum(d==数据))
对于枚举(X_测试)中的批处理(数据,目标):
数据,目标=数据到(设备),目标到(设备)
d=数据
X_测试_功能[batch_idx]=model1(data).cpu().detach().numpy()
y_test[batch_idx]=target.cpu().detach().numpy()
X_test2_功能[batch_idx]=model2(d).cpu().detach().numpy()
y_test2[batch_idx]=target.cpu().detach().numpy()
打印(总和(X_测试特征[batch_idx]==X_测试2_特征[batch_idx]))
打印(总和(y_测试[batch_idx]==y_测试2[batch_idx]))
打印(torch.sum(d==数据))
#检查参数
对于zip中的a、b(model1.parameters()、model2.parameters()):
打印(火炬总数(a!=b))

期望从model1和model2获得相同的正向结果,但它们是不同的。如果它们产生不同的正向结果,为什么它们有完全相同的参数?

您考虑过层可能发生的变化吗?
批处理规范层的行为与正常层不同——它们的内部参数通过计算数据的运行平均值和标准差来修改,而不是通过梯度下降来修改。

尝试在微调之前设置
model1.eval()
,然后检查。

您是否考虑到图层可能发生的更改?
批处理规范层的行为与正常层不同——它们的内部参数通过计算数据的运行平均值和标准差来修改,而不是通过梯度下降来修改。

尝试在微调之前设置
model1.eval()
,然后检查。

两个模型的fc层中的参数应该不同。事实上,它们有不同数量的输出类;当您在model1中将resnet的输出大小修改为2时,默认情况下resnet的输出大小为1000。两个模型的fc层中的参数应该不同。事实上,它们有不同数量的输出类;当您在model1中将其修改为2时,resnet默认有1000个输出大小。非常感谢!此外,如果没有
model2.eval()
,未联网的model2将导致无法线性分离的功能,在运行
model2.eval()
后,model2的功能几乎可以线性分离。对不起,我忘了,可能是我单击错误,可能是其他人工作,非常感谢!此外,如果没有
model2.eval()
,未联网的model2将导致无法线性分离的功能,在运行
model2.eval()
后,model2的功能几乎可以线性分离。对不起,我忘了,可能是我单击错误,可能是其他人单击错误