Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从python导出的模型在C++; 问题描述_Python_C++_Pytorch_Libtorch_Torchscript - Fatal编程技术网

从python导出的模型在C++; 问题描述

从python导出的模型在C++; 问题描述,python,c++,pytorch,libtorch,torchscript,Python,C++,Pytorch,Libtorch,Torchscript,因此,我使用pythorch用python编写了模型类: class ResBlock(nn.Module,ABC): def_uuuinit_uuu(self,in_通道:int,过滤器:int,conv_num:int): 超级(ResBlock,self)。\uuuu init\uuuuu() self.filters=过滤器 self.conv_num=conv_num self.input\u conv=torch.nn.Conv1d(输入通道=输入通道,输出通道=过滤器,内核大小=1

因此,我使用pythorch用python编写了模型类:

class ResBlock(nn.Module,ABC):
def_uuuinit_uuu(self,in_通道:int,过滤器:int,conv_num:int):
超级(ResBlock,self)。\uuuu init\uuuuu()
self.filters=过滤器
self.conv_num=conv_num
self.input\u conv=torch.nn.Conv1d(输入通道=输入通道,输出通道=过滤器,内核大小=1)
self.internal\u conv=torch.nn.Conv1d(in\u channels=in\u channels,out\u channels=filters,kernel\u size=3,padding=1)
self.outer\u conv=torch.nn.Conv1d(in\u channels=filters,out\u channels=filters,kernel\u size=3,padding=1)
self.max\u pool=torch.nn.MaxPool1d(内核大小=2,步幅=2)
def前进(自身,x):
y=x
对于范围内的i(self.conv_num-1):
如果i==0:
y=自内循环(y)
其他:
y=自外循环(y)
y=火炬。relu(y)
y=自外循环(y)
s=自输入转换(x)
y=s+y
y=火炬。relu(y)
返回自最大池(y)
班级网络(nn.Module,ABC):
定义初始化(self,类的数量:int):
超级(网络,自我)。\uuuu初始化
self.block_1=ResBlock(1,16,2)
self.block_2=ResBlock(16,32,2)
self.block_3=ResBlock(32,64,3)
self.block_4=ResBlock(64、128、3)
self.block_5=ResBlock(128、128、3)
self.avg_pool=torch.nn.AvgPool1d(内核大小=3,步幅=3)
self.flatte=torch.nn.flatte()
self.density_1=torch.nn.Linear(
in_features=self.block_5.filters*(249//self.avg_pool.kernel_size[0]),
out_功能=256
)
self.density_2=torch.nn.Linear(输入特征=256,输出特征=128)
self.classifier=torch.nn.Linear(in_features=128,out_features=num_of_类)
def前进(自身,x):
x=自块_1(x)
x=自块2(x)
x=自块_3(x)
x=自块_4(x)
x=自块_5(x)
x=自平均池(x)
x=自展平(x)
x=自密实_1(x)
x=自密实_2(x)
x=自分类器(x)
返回x
在python环境中使用时,它工作得非常好。我已经训练了它,获得了测试集的65%的准确度,并希望使用Trrcript脚本导出它,然后导入C++应用程序。 以下是用于导出的代码:

#为了简化,跳过了培训代码。。。
#在这里,模型被实际训练,权重被更新等等
jit_model=torch.jit.script(模型)
jit_model.save('torchscript-model.pt'))

在导入到C++之前,我检查了模型是否正确导入,通过使用Python脚本,并再次对我的测试数据集进行检查,以获得预期的相同精度的65%。 下一个逻辑步骤是将模型导入C++程序,并使用相同的数据对加载模型进行评估。代码如下:

#包括
#包括
#包括“constants.hh”
int main(){
火炬:手动种子(1);
火炬::装置装置(火炬::kCPU);
auto model=torch::jit::load(“./torchscript model.pt”);
型号至(装置);
自动测试\u原始\u数据集=CsvDataset(常数::kTestCsv);
自动测试数据集=测试原始数据集.map(torch::data::transforms::Stack());
自动测试数据加载器=火炬::数据::制作数据加载器(标准::移动(测试数据集),火炬::数据::数据加载器选项(常数::kBatchSize));
大小\u t正确\u计数=0;
用于(常量自动和批处理:*测试数据加载程序){
自动输入=批处理数据到(设备);
自动标签=batch.target.to(设备);
输入=输入。取消查询(1);
标签=标签。挤压(1);
自动输出=model.forward(输入).toTensor();
自动预测=输出。argmax(1);
正确的计数+=预测.eq(标签).sum().item();
}
自动精度=正确的计数/测试数据集.size().value();
//为清晰起见,已删除其余代码。。。
}
实际问题 但是发生的事情是C++中计算的精度等于12%。为什么?

到目前为止,我尝试/发现了什么: 当模型加载到C++中时,所有的预测都是相同的(等于<代码> 6 <代码>)。在python中加载模型时,一切都很好 在Python和C++中,获得<<代码>输出的所有计算都是相同的,所以问题不在计算精度的方式。
  • 使用
    torch::manual_seed
    不起任何作用。(它不应该改变任何东西,但为什么不尝试……)
  • 火炬:NoGradGuard也什么都不做
  • <> Li >还确保测试数据以Python和C++的相同顺序进入模型。
  • 在这两种情况下,模型均以评估模式运行
  • 更新1

    静态加载输入的模型采用 Tror,其中的和Python和C++仍然有不同的结果。 更新2 @gspr请求的Python代码:

    dataset=CsvDataset(os.path.join(constants.CSV_DIR,'train.CSV'))
    sampler=torch.utils.data.sampler.RandomSampler(数据集)
    dataloader=torch.utils.data.dataloader(数据集,批大小=常量。批大小,采样器=采样器)
    列车测试尺寸=长度(数据集)
    批次计数=math.ceil(序列测试大小/常数。批次大小)
    test_dataset=CsvDataset(os.path.join(constants.CSV_DIR,'test.CSV'))
    test\u dataloader=torch.utils.data.dataloader(test\u dataset,batch\u size=constants.batch\u size)
    测试集大小=len(测试数据集)
    model=Net(dataset.num\u classes())
    标准=torch.nn.CrossEntropyLoss()
    optimizer=torch.optim.Adam(model.parameters(),lr=constants.LEARNING\u RATE)
    对于范围内的历元(常数.历元):
    运行损耗=0.0
    正确计数=0
    对于i,枚举中的数据(dataloader,1):
    输入、标签=数据
    输入=输入。取消查询(1)
    标签=标签