精华内容
下载资源
问答
  • obj模型加载

    2018-08-27 10:39:50
    用于学习learnOpenGL时加载外部obj模型所实现的简单的c++类,本人是用codeblocks编写的,所以打包了codeblocks项目,类函数也在其中,包含测试代码。 注:此c++类只能加载三角面模型!!
  • 本程序为OpenGL模型加载小程序,模型数据格式为.obj。代码中如有疑问请指出,会为你一一解答。
  • pytorch 模型加载与保存

    千次阅读 2019-04-07 14:25:19
    保存和与加载模型,有三个核心函数需要熟悉: torch.save: 保存一个序列化的对象至硬盘,。该函数使用了Python的pickle包用于序列化。模型、张亮和各种对象的字典都可以使用该函数保存; torch.load:使用pickle的...

    翻译自https://pytorch.org/tutorials/beginner/saving_loading_models.html

    保存和与加载模型,有三个核心函数需要熟悉:

    1. torch.save: 保存一个序列化的对象至硬盘,。该函数使用了Python的pickle包用于序列化。模型、张量和各种对象的字典都可以使用该函数保存;
    2. torch.load:使用pickle的反序列化功能将序列化的对象文件反序列化到内存。这个功能可以用帮助设备加载数据。
    3. torch.nn.Module.load_state_dict:使用一个反序列化的state_dict加载一个模型的参数字典。

    什么是 state_dict

    在PyTorch中,一个torch.nn.Module模型的可训练参数(即权重与偏移项)保存在模型的参数parameters,使用model.parameters()获得)中。一个state_dict就是一个简单的Python字典,将每层映射到其参数张量。注意:,只有具有可训练参数的层(卷积层、线性层等)和注册的缓存(batchnorm的running_running_mean)在模型的state_dict中有接口。优化器对象(torch.optim)也有一个state_dict,其中包含了优化器的信息,以及使用的超参数。

    由于state_dict是Python字典,它们可以很容易被保存、更新、更新和加载,增加了PyTroch模型和优化器的组织模块性。

    例子,一个分类器模型中的state_dict

     Define model
    class TheModelClass(nn.Module):
        def __init__(self):
            super(TheModelClass, self).__init__()
            self.conv1 = nn.Conv2d(3, 6, 5)
            self.pool = nn.MaxPool2d(2, 2)
            self.conv2 = nn.Conv2d(6, 16, 5)
            self.fc1 = nn.Linear(16 * 5 * 5, 120)
            self.fc2 = nn.Linear(120, 84)
            self.fc3 = nn.Linear(84, 10)
    
        def forward(self, x):
            x = self.pool(F.relu(self.conv1(x)))
            x = self.pool(F.relu(self.conv2(x)))
            x = x.view(-1, 16 * 5 * 5)
            x = F.relu(self.fc1(x))
            x = F.relu(self.fc2(x))
            x = self.fc3(x)
            return x
    
    # Initialize model
    model = TheModelClass()
    
    # Initialize optimizer
    optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)
    
    # Print model's state_dict
    print("Model's state_dict:")
    for param_tensor in model.state_dict():
        print(param_tensor, "\t", model.state_dict()[param_tensor].size())
    
    # Print optimizer's state_dict
    print("Optimizer's state_dict:")
    for var_name in optimizer.state_dict():
        print(var_name, "\t", optimizer.state_dict()[var_name])
    

    运行结果:
    在这里插入图片描述

    与parameters(),named_parameters()的区别

    model.parameters()model.named_parameters()返回一个生成器,保存了模型参数。返回的每个元素是模型的一个参数,区别是前者是一个nn.parameter.Parameter的对象,后者是一个长度为2的tuple,(str, nn.parameter.Parameter),即参数的名字和参数):

    for k in model.parameters():
    	print(type(k), k.shape)
    for k in model.named_parameters():
    	print(isinstance(k, tuple), 'len{:d}'.format(len(k)), k[0], k[1].shape)
    

    输出为:
    在这里插入图片描述

    用于测试的模型加载与保存

    保存/加载 state_dict(推荐)

    保存:

    torch.save(model.state_dict(), PATH)
    

    加载:

    model = TheModelClass(*args, **kwargs)
    model.load_state_dict(torch.load(PATH))
    model.eval()
    

    当用于保存模型用于测试时,只需要保存模型的可训练参数。使用torch.save()保存模型的state_dict可以在加载模型时给予最大的灵活度,这也是为什么推荐使用的保存模型的方法。

    PyTorch约定是使用.pt.pth后缀命名保存文件。

    **切记:**在测试之前, 必须调用model.eval()将dropout和batch normalization层设置为测试模式,不然会导致不一致的结果。

    注意:load_state_dict()函数的参数是一个字典对象,不是保存对象的文件名。这意味着,在将保存的state_dict传递给load_state_dict()之前必须将其反序列化。

    保存/加载整个模型

    保存:

    torch.save(model.state_dict(), PATH)
    

    加载:

    model = torch.load(PATH)
    model.eval()
    

    这种保存/加载的方法使用了最直观的语法,涉及到最少量的程序。使用这种方法保存整个模型使用了Python的pickle模块。这种方法的劣势是,序列化的数据被限制于模型包存时所使用的特定类型和准确的字典结构。这是因为pickle不能保存模型类型本身。而是保存一个加载时使用的包含类的文件的地址。因此,你的程序在其他项目中使用、或改变之后可能会各种崩溃。

    PyTorch约定是使用.pt.pth后缀命名保存文件。

    **切记:**在测试之前, 必须调用model.eval()将dropout和batch normalization层设置为测试模式,不然会导致不一致的结果。

    用于一般checkpoint的模型加载与保存

    保存:

    torch.save({
                'epoch': epoch,
                'model_state_dict': model.state_dict(),
                'optimizer_state_dict': optimizer.state_dict(),
                'loss': loss,
                ...
                }, PATH)
    

    加载:

    model = TheModelClass(*args, **kwargs)
    optimizer = TheOptimizerClass(*args, **kwargs)
    
    checkpoint = torch.load(PATH)
    model.load_state_dict(checkpoint['model_state_dict'])
    optimizer.load_state_dict(checkpoint['optimizer_state_dict'])
    epoch = checkpoint['epoch']
    loss = checkpoint['loss']
    
    model.eval()
    # - or -
    model.train()
    

    当保存一般的、用于恢复训练或测试的checkpoint时,你必须保存比模型的stae_dict更多的内容。保存优化器的stae_dict也很重要,它包含了在模型训练期间更新的缓存和参数。其他希望保存的内容有结束上次训练时的epoch,最新记录的训练损失,以及外部的torch.nn.Embedding层等。

    为了保存多个组件,将其组织在字典内,然后使用torch.save()将字典序列化。这样,当你希望是,可以通过查询字典轻松得到保存的组件。

    **切记:**在测试之前, 必须调用model.eval()将dropout和batch normalization层设置为测试模式,不然会导致不一致的结果。如果你想恢复训练,可以调用model.train()保证这些层都在训练模式。

    在一个文件内保存多个模型

    保存:

    torch.save({
                'modelA_state_dict': modelA.state_dict(),
                'modelB_state_dict': modelB.state_dict(),
                'optimizerA_state_dict': optimizerA.state_dict(),
                'optimizerB_state_dict': optimizerB.state_dict(),
                ...
                }, PATH)
    

    加载:

    modelA = TheModelAClass(*args, **kwargs)
    modelB = TheModelBClass(*args, **kwargs)
    optimizerA = TheOptimizerAClass(*args, **kwargs)
    optimizerB = TheOptimizerBClass(*args, **kwargs)
    
    checkpoint = torch.load(PATH)
    modelA.load_state_dict(checkpoint['modelA_state_dict'])
    modelB.load_state_dict(checkpoint['modelB_state_dict'])
    optimizerA.load_state_dict(checkpoint['optimizerA_state_dict'])
    optimizerB.load_state_dict(checkpoint['optimizerB_state_dict'])
    
    modelA.eval()
    modelB.eval()
    # - or -
    modelA.train()
    modelB.train()
    

    当保存的模型由多个torch.nn.Modules组成时,例如GAN,一个序列到序列的模型,或多个模型的集合,你可以安装保存为checkpoint的方法保存模型。即,保存每个模型的state_dict和对应的优化其组成的字典。之前提到了,你可以通过向字典中添加对恢复训练有帮助的任何项,以保存它们。

    PyTorch的约定是使用.tar后缀命名保存这种checkpoint。

    **切记:**在测试之前, 必须调用model.eval()将dropout和batch normalization层设置为测试模式,不然会导致不一致的结果。如果你想恢复训练,可以调用model.train()保证这些层都在训练模式。

    使用不同模型的参数预热模型

    保存:

    torch.save(modelA.state_dict(), PATH)
    

    加载:

    modelB = TheModelBClass(*args, **kwargs)
    modelB.load_state_dict(torch.load(PATH), strict=False)
    

    部分地加载一个模型,或者加载模型的一部分在迁移学习或训练一个新的复杂模型时经常用到。利用训练的参数,即使只有少部分可用,将有助于预热训练模型,并有希望有助于加快模型的收敛速度。

    无论记载一个缺少部分keys的部分state_dict,还是加载一个比模型有更多keys的stat_dict,你可以将load_state_dict()中的strict参数设置为False,以忽略没有匹配到的key。

    如果你想把一个层参数加载到到其他层,但是一些key并不匹配,你可以改变加载的state_dict中参数key的名字为加载的模型中的对应的key的名字。

    在设备间保存与加载模型

    GPU上保存,CPU加载

    保存:

    torch.save(model.state_dict(), PATH)
    

    加载:

    device = torch.device('cpu')
    model = TheModelClass(*args, **kwargs)
    model.load_state_dict(torch.load(PATH, map_location=device))
    

    当在CPU上加载在GPU上训练的模型时,将torch.load()函数中的map_location参数设置为torch.device('cpu')。在这种情况下,保存这些张量的内存被自动重新映射到CPU上。

    GPU上保存,CPU加载

    保存:

    torch.save(model.state_dict(), PATH)
    

    加载:

    device = torch.device('cuda')
    model = TheModelClass(*args, **kwargs)
    model.load_state_dict(torch.load(PATH))
    model.to(device)
    

    当在GPU上加载一个在GPU上训练并保存的模型时,使用model.to(torch.device('cuda')将初始化的模型转换为CUDA优化的模型。同样,确保在所有模型的输入上使用.to(torch.device('cuda'))函数以为模型准备数据。注意:,调用my_tensor.to(device)返回一个在GPU上my_tensor的拷贝。这没有覆盖my_tensor。因此,记得手动覆盖张量:
    my_tensor = my_tensor.to(torch.device('cuda'))

    CPU上保存,GPU加载

    保存:

    torch.save(model.state_dict(), PATH)
    

    加载:

    device = torch.device('cuda')
    model = TheModelClass(*args, **kwargs)
    model.load_state_dict(torch.load(PATH, map_location='cuda:0'))
    model.to(device)
    

    当在GPU上加载一个在CPU上训练并保存的模型是,将torch.load()中的map_location参数设置为cuda:device_id。这将模型加载到给定的GPU设备。然后,切记调用model.to(torch.device('cuda'))以将模型的参数张量转换为CUAD张量。最后,确保在所有模型的输入上使用.to(torch.device('cuda'))函数以为模型准备数据。注意:,调用my_tensor.to(device)返回一个在GPU上my_tensor的拷贝。这没有覆盖my_tensor。因此,记得手动覆盖张量:
    my_tensor = my_tensor.to(torch.device('cuda'))

    保存torch.nn.DataParaller模型

    保存:

    torch.save(model.module.state_dict(), PATH)
    

    加载:

    # load to whatever device you want
    

    torch.nn.DataPatallel是一个模型的wrapper,保证了并行GPU的使用。为了一般地保存DtaParallel模型,保存model.module.state_dict(). 这样,你有将模型加载至任意设备的灵活性。

    展开全文
  • ncnn模型加载的三种方式

    千次阅读 2020-05-11 21:54:02
    本文主要讲解ncnn模型加载的三种方式,模型以上文(https://blog.csdn.net/Enchanted_ZhouH/article/details/105861646)的resnet18模型为示例,模型文件如下: resnet18.param //模型结构文件 resnet18.bin //模型...

           本文主要讲解ncnn模型加载的三种方式,模型以上文(https://blog.csdn.net/Enchanted_ZhouH/article/details/105861646)的resnet18模型为示例,模型文件如下:

    resnet18.param    //模型结构文件
    resnet18.bin     //模型参数文件
    
           第一种方式:直接加载param和bin

           最简单的方式为直接加载param和bin文件,适合快速测试模型效果,加载模型代码如下:

    ncnn::Net net;
    net.load_param("resnet18.param");
    net.load_model("resnet18.bin");
    

           param为模型文件,打开如下:

    7767517
    78 86
    Input            x                        0 1 x
    Convolution      123                      1 1 x 123 0=64 1=7 11=7 2=1 12=1 3=2 13=2 
                                    .
                                    .
                                    .
    Flatten          190                      1 1 189 190
    InnerProduct     y                        1 1 190 y 0=1000 1=1 2=512000
    

           模型的输入为x,输出为y。因此,定义输入和输出的代码如下:

    ncnn::Mat in;
    ncnn::Mat out;
    ncnn::Extractor ex = net.create_extractor();
    ex.set_light_mode(true);
    ex.set_num_threads(4);
    ex.input("x", in);
    ex.extract("y", out);
    

           测试一张图片,test.jpg换成自己的图片即可,整体代码如下:

    #include <opencv2/highgui/highgui.hpp>
    #include <vector>
    #include "net.h"
    
    using namespace std;
    
    int main()
    {
    	cv::Mat img = cv::imread("test.jpg");
    	int w = img.cols;
    	int h = img.rows;
    	ncnn::Mat in = ncnn::Mat::from_pixels_resize(img.data, ncnn::Mat::PIXEL_BGR, w, h, 224, 224);
    	
    	ncnn::Net net;
    	net.load_param("resnet18.param");
    	net.load_model("resnet18.bin");
    	ncnn::Extractor ex = net.create_extractor();
    	ex.set_light_mode(true);
    	ex.set_num_threads(4);
    
    	ncnn::Mat out;
    	ex.input("x", in);
    	ex.extract("y", out);
    
    	ncnn::Mat out_flattened = out.reshape(out.w * out.h * out.c);
    	vector<float> score;
    	score.resize(out_flattened.w);
    	for (int i = 0; i < out_flattened.w; ++i) {
    		score[i] = out_flattened[i];
    	}
    	vector<float>::iterator max_id = max_element(score.begin(), score.end());
    	printf("predicted class: %d, predicted value: %f", max_id - score.begin(), score[max_id - score.begin()]);
    
    	net.clear();
    	return 0;
    }
    

           运行结果如下:

    predicted class: 588, predicted value: 154.039322
    
           第二种方式:加载二进制的 param.bin 和 bin

           第一种方式有个明显的问题,param模型文件是明文的,如果直接发布出去,任何使用者都可以窥探到模型结构,这很不利于加密工作的进行。

           因此,引出第二种模型加载方式,将param转换成二进制文件,ncnn编译好后,tools里有个ncnn2mem工具,使用此工具可以生成param.bin、id.h和mem.h三个文件,命令如下:

    ncnn2mem resnet18.param resnet18.bin resnet18.id.h resnet18.mem.h
    

           生成三个文件如下:

    resnet18.param.bin    //二进制的模型结构文件
    resnet18.id.h        //模型结构头文件
    resnet18.mem.h       //模型参数头文件
    

           param.bin不是明文的,没有可见字符串,适合模型的发布,加载模型代码如下:

    ncnn::Net net;
    net.load_param_bin("resnet18.param.bin");
    net.load_model("resnet18.bin");
    

           由于param.bin窥探不到模型结构,因此,需要导入id.h头文件来获取模型的输入和输出,resnet18.id.h文件如下:

    namespace resnet18_param_id {
    const int LAYER_x = 0;
    const int BLOB_x = 0;
            .
            .
            .
    const int LAYER_y = 77;
    const int BLOB_y = 85;
    } // namespace resnet18_param_id
    

           如上可见,模型的输入为resnet18_param_id::BLOB_x,输出为resnet18_param_id::BLOB_y,定义输入和输出的代码如下:

    #include "resnet18.id.h"
    ncnn::Mat in;
    ncnn::Mat out;
    ncnn::Extractor ex = net.create_extractor();
    ex.set_light_mode(true);
    ex.set_num_threads(4);
    ex.input(resnet18_param_id::BLOB_x, in);
    ex.extract(resnet18_param_id::BLOB_y, out);
    

           同理,整体预测代码如下:

    #include <opencv2/highgui/highgui.hpp>
    #include <vector>
    #include "net.h"
    #include "resnet18.id.h"
    
    using namespace std;
    
    int main()
    {
    	cv::Mat img = cv::imread("test.jpg");
    	int w = img.cols;
    	int h = img.rows;
    	ncnn::Mat in = ncnn::Mat::from_pixels_resize(img.data, ncnn::Mat::PIXEL_BGR, w, h, 224, 224);
    	
    	ncnn::Net net;
    	net.load_param_bin("resnet18.param.bin");
    	net.load_model("resnet18.bin");
    	ncnn::Extractor ex = net.create_extractor();
    	ex.set_light_mode(true);
    	ex.set_num_threads(4);
    
    	ncnn::Mat out;
    	ex.input(resnet18_param_id::BLOB_x, in);
    	ex.extract(resnet18_param_id::BLOB_y, out);
    
    	ncnn::Mat out_flattened = out.reshape(out.w * out.h * out.c);
    	vector<float> score;
    	score.resize(out_flattened.w);
    	for (int i = 0; i < out_flattened.w; ++i) {
    		score[i] = out_flattened[i];
    	}
    	vector<float>::iterator max_id = max_element(score.begin(), score.end());
    	printf("predicted class: %d, predicted value: %f", max_id - score.begin(), score[max_id - score.begin()]);
    
    	net.clear();
    	return 0;
    }
    

           运行结果如下:

    predicted class: 588, predicted value: 154.039322
    
           第三种方式:从内存加载param 和 bin

           虽然第二种模型加载方式可以避免模型结构的泄露,但是模型和代码还是处于分离状态的,如果将其打包发布,那么模型文件需要独立出来进行打包。

           打个比方,如果写了一个算法的.so接口供前端调用,不仅需要发布.so文件,还需要发布model文件,这样着实不太方便。如若可以将model一起打包进.so接口,直接将包含了代码和模型的.so扔给前端人员调用,这样更为便利。

           第二种方式中,已经生成了id.h和mem.h两个头文件,此处,只需要这两个头文件即可,不需要再调用param和bin文件。

           从内存加载模型的代码如下:

    #include "resnet18.mem.h"
    ncnn::Net net;
    net.load_param(resnet18_param_bin);
    net.load_model(resnet18_bin);
    

           定义输入和输出的代码和第二种方式保持一致,如下:

    #include "resnet18.id.h"
    ncnn::Mat in;
    ncnn::Mat out;
    ncnn::Extractor ex = net.create_extractor();
    ex.set_light_mode(true);
    ex.set_num_threads(4);
    ex.input(resnet18_param_id::BLOB_x, in);
    ex.extract(resnet18_param_id::BLOB_y, out);
    

           整体预测代码如下:

    #include <opencv2/highgui/highgui.hpp>
    #include <vector>
    #include "net.h"
    #include "resnet18.id.h"
    #include "resnet18.mem.h"
    
    using namespace std;
    
    int main()
    {
    	cv::Mat img = cv::imread("test.jpg");
    	int w = img.cols;
    	int h = img.rows;
    	ncnn::Mat in = ncnn::Mat::from_pixels_resize(img.data, ncnn::Mat::PIXEL_BGR, w, h, 224, 224);
    	
    	ncnn::Net net;
    	net.load_param(resnet18_param_bin);
    	net.load_model(resnet18_bin);
    	ncnn::Extractor ex = net.create_extractor();
    	ex.set_light_mode(true);
    	ex.set_num_threads(4);
    
    	ncnn::Mat out;
    	ex.input(resnet18_param_id::BLOB_x, in);
    	ex.extract(resnet18_param_id::BLOB_y, out);
    
    	ncnn::Mat out_flattened = out.reshape(out.w * out.h * out.c);
    	vector<float> score;
    	score.resize(out_flattened.w);
    	for (int i = 0; i < out_flattened.w; ++i) {
    		score[i] = out_flattened[i];
    	}
    	vector<float>::iterator max_id = max_element(score.begin(), score.end());
    	printf("predicted class: %d, predicted value: %f", max_id - score.begin(), score[max_id - score.begin()]);
    
    	net.clear();
    	return 0;
    }
    

           运行结果如下:

    predicted class: 588, predicted value: 154.039322
    

           至此,三种ncnn模型加载方式全部介绍完毕,做个简单的总结如下:

           1. 直接加载ncnn模型可以快速测试模型效果,但是param是明文的,打开文件可以直接看到模型结构,不利于加密;

           2. 将param文件转为二进制,可以起到一定的加密作用;

           3. 将模型结构和参数直接读进内存,和代码整合在一起,利于打包发布,只需提供一个打包好的库即可(.so/.dll等),不用将模型文件单独拷贝到部署机器上,大大方便了算法的部署以及加密。

           参考资料:https://github.com/Tencent/ncnn/wiki/use-ncnn-with-alexnet.zh

    展开全文
  • 模型加载库 Assimp

    千次阅读 2020-04-06 15:46:27
    大家好,接下来将为大家介绍模型加载库 Assimp 。 Assimp 全称为 Open Asset Import Library,可以支持几十种不同格式的模型文件的解析(同样也可以导出部分模型格式),Assimp 本身是 C++ 库,可以跨平台使用。 ...

    大家好,接下来将为大家介绍模型加载库 Assimp 。

    1、Assimp介绍

    Assimp 全称为 Open Asset Import Library,可以支持几十种不同格式的模型文件的解析(同样也可以导出部分模型格式),Assimp 本身是 C++ 库,可以跨平台使用。

    Assimp 可以将几十种模型文件都转换为一个统一的数据结构,所有无论我们导入何种格式的模型文件,都可以用同一个方式去访问我们需要的模型数据。

    当导入一个模型文件时,即Assimp加载一整个包含所有模型和场景数据的模型文件到一个scene对象时,Assimp会为这个模型文件中的所有场景节点、模型节点都生成一个具有对应关系的数据结构,且将这些场景中的各种元素与模型数据对应起来。下图展示了一个简化的Assimp生成的模型文件数据结构:

    a、所有的模型、场景数据都包含在scene对象中,如所有的材质和Mesh。同样,场景的根节点引用也包含在这个scene对象中。

    b、场景的根节点可能也会包含很多子节点和一个指向保存模型点云数据mMeshes[]的索引集合。根节点上的mMeshes[]里保存了实际了Mesh对象,而每个子节点上的mMesshes[]都只是指向根节点中的mMeshes[]的一个引用。

    c、一个Mesh对象本身包含渲染所需的所有相关数据,比如顶点位置、法线向量、纹理坐标、面片及物体的材质。

    d、一个Mesh会包含多个面片。一个Face(面片)表示渲染中的一个最基本的形状单位,即图元(基本图元有点、线、三角面片、矩形面片)。一个面片记录了一个图元的顶点索引,通过这个索引,可以在mMeshes[]中寻找到对应的顶点位置数据。顶点数据和索引分开存放,可以便于我们使用缓存(VBO、NBO、TBO、IBO)来高速渲染物体。

    e、一个Mesh还会包含一个Material(材质)对象用于指定物体的一些材质属性。如颜色、纹理贴图(漫反射贴图、高光贴图等)。

    所以我们要做的第一件事,就是加载一个模型文件为scene对象,然后获取每个节点对应的Mesh对象(我们需要递归搜索每个节点的子节点来获取所有的节点),并处理每个Mesh对象对应的顶点数据、索引以及它的材质属性。最终我们得到一个只包含我们需要的数据的Mesh集合。

     

    2、构建Assimp

    Assimp 源代码地址:https://github.com/assimp/assimp

    a:设置的几个环境变量如下:

    export ANDROID_NDK_PATH=/Users/liao/Library/Android/sdk/ndk-bundle // 设置DNK路径
    export ANDROID_SDK_PATH=/Users/liao/Library/Android/sdk // 设置SDK路径
    export CMAKE_TOOLCHAIN=/Users/liao/Library/Android/sdk/ndk-bundle/build/cmake/android.toolchain.cmake // 设置交叉编译用到的toolchain,这个用NDK默认提供的就行
    export ANDROID_NDK_TOOLCHAIN=/Users/liao/Library/Android/sdk/android-toolchain // 这个也必须设置,其中android-toolchain就是上面生成的啦
    export PATH=$PATH:/Users/liao/Library/Android/sdk/android-toolchain/bin // 必须设置

    b:设置了环境变量之后,我们就可以通过cmake生成makefile了。

    首先执行下面的命令:

    cd xxx/assimp // 下载assimp,然后解压,进入assimp根目录
    mkdir buildAndroid // 创建文件夹
    cd buildAndroid // 进入这个文件夹

    然后执行下面的命令

    cmake -DCMAKE_TOOLCHAIN_FILE=$CMAKE_TOOLCHAIN -DCMAKE_INSTALL_PREFIX=/assimp -DANDROID_ABI=armeabi-v7a -DANDROID_NATIVE_API_LEVEL=android-14 -DANDROID_FORCE_ARM_BUILD=TRUE -DANDROID_STL=c++_shared -DASSIMP_BUILD_OBJ_IMPORTER=TRUE -DASSIMP_BUILD_FBX_IMPORTER=TRUE -DANDROID_NDK=$ANDROID_NDK_PATH -DCMAKE_BUILD_TYPE=Release -DANDROID_FORCE_ARM_BUILD=TRUE -DCMAKE_CXX_FLAGS=-Wno-c++11-narrowing -DANDROID_TOOLCHAIN=clang -DASSIMP_BUILD_TESTS=OFF -DASSIMP_NO_EXPORT=TRUE -DASSIMP_BUILD_ASSIMP_TOOLS=FALSE -DASSIMP_BUILD_SAMPLES=FALSE -DASSIMP_BUILD_ALL_IMPORTERS_BY_DEFAULT=FALSE ..

    参数解释

    -DCMAKE_TOOLCHAIN_FILE=$CMAKE_TOOLCHAIN 指向上面生成的toolchain
    -DCMAKE_INSTALL_PREFIX=/assimp 最终生成的.so文件的名称
    -DANDROID_ABI=armeabi-v7a 应用程序二进制接口类型,详见[ABI Management](https://developer.android.com/ndk/guides/abis)
    -DANDROID_NATIVE_API_LEVEL=android-14 api版本,设成这个就行
    -DANDROID_FORCE_ARM_BUILD=TRUE 强制编译arm架构
    -DANDROID_STL=c++_shared c++类型
    -DASSIMP_BUILD_OBJ_IMPORTER=TRUE 支持OBJ格式的3D模型文件导入
    -DASSIMP_BUILD_FBX_IMPORTER=TRUE 支持FBX格式的3D模型文件导入
    -DASSIMP_BUILD_ALL_IMPORTERS_BY_DEFAULT=FALSE assimp默认支持很多种3D模型格式,这里只指定常用的一两种格式即可,减小.so包的大小
    -DASSIMP_BUILD_TESTS=OFF 这个要关掉,不然make时会有一些奇怪的错误
    -DASSIMP_NO_EXPORT=TRUE 只需要解析3D模型,不需要生成3D模型
    

    c:上面的步骤生成了makefile文件,下面进行make批处理。

    make -j8 // 在buildAndroid目录下执行make操作。其中-j8是指多线程个数,根据自己电脑配置,选择不同线程数,线程数越多编译的越快。

    上面make如果没出错的话,直接去assimp/buildAndroid/code目录下寻找libassimp.so文件。

     

     

     

     

    展开全文
  • pytorch模型加载 基本的情形: 一、单卡训练好的模型文件,推理阶段的加载(即加载模型文件和model定义的是一致的) state_dict = torch.load('checkpoint.pth.tar') Mymodel.load_state_dict(state_dict) 二、多...

    pytorch模型加载

    基本的情形:

    一、单卡训练好的模型文件,推理阶段的加载(即加载模型文件和model定义的是一致的)

    state_dict = torch.load('checkpoint.pth.tar')
    Mymodel.load_state_dict(state_dict)
    

    二、多gpu训练保存的模型,在单卡情况下加载

    当出现以第一种的写法会有问题时,自然的就需要检查Mymodel和要加载的模型文件的差异

    # 打印你自己定义的模型的键值对
    params = Mymodel.state_dict()  # 获得模型的原始状态以及参数, orderdict数据类型
    for k, v in params.items():
        print(k)  # 只打印key值,不打印具体参数值
        
    # 打印加载的checkpoint文件的键值对
    state_dict = torch.load('checkpoint.pth.tar')
    for k, v in checkpoint.items():
        print(k)
    

    然后你就会发现有些key值多了module,这时候我们只需要去掉多余的名字使得两者的key值相同就可以正常加载了。主要有3种:

    • 从key中的第7个字符开始取

      from collections import OrderedDict
      state_dict = torch.load('checkpoint.pth.tar')
      new_state_dict = OrderedDict()
      for k,v in state_dict.items():
          name = k[7:] # remove `module`
          new_state_dict[name] = v
      # load params
      Mymodel.load_state_dict(new_state_dict)
      
    • module 替换为空字符

      name = k.replace('module.', '')
      
    • 最简单的方法,加载模型之后,接着将模型DataParallel,此时就可以load_state_dict。
      如果有多个GPU,将模型并行化,用DataParallel来操作。这个过程会将key值加一个module.

      Mymodel = resnet18()# 实例化自己的模型;
      state_dict = torch.load('checkpoint.pt', map_location='cpu') 
      if torch.cuda.device_count() > 1:
          model = nn.DataParallel(model) 
      model.load_state_dict(checkpoint) # 可以直接将模型参数load进模型。
      

    三、加载模型文件与当前构建模型相同部分层的权重

    主要有两种写法:

    1. 在写模型类时,在训练好的模型基础上搭建自己的模型。即先带预训练模型建model,然后再修改、删除或者添加模块;

      featureExtract = resnet18(pretrained=True) # load weight
      self.featureEncoder = nn.Sequential(*list(featureExtract.children())[:-2])
      
    2. 整个模型类已经实现,调用后加载部分层参数

      使用前最好打印检查下,因为设置了strict=false,如果只差了module是不会报错的。

      #第一种方法:
      mymodelB = TheModelBClass(*args, **kwargs)
      # strict=False,设置为false,只保留键值相同的参数
      mymodelB.load_state_dict('checkpoint.pt', strict=False)
      
      #第二种方法:
      # 加载模型
      model_pretrained = torch.load('checkpoint.pt')
      
      # mymodel's state_dict,
      # 如:  conv1.weight 
      #     conv1.bias  
      mymodelB_dict = mymodelB.state_dict()
      
      # 将model_pretrained的建与自定义模型的建进行比较,剔除不同的
      pretrained_dict = {k: v for k, v in model_pretrained.items() if k in mymodelB_dict}
      # 更新现有的model_dict
      mymodelB_dict.update(pretrained_dict)
      
      # 加载我们真正需要的state_dict
      mymodelB.load_state_dict(mymodelB_dict)
      

    参考

    https://zhuanlan.zhihu.com/p/48524007

    讨论:checkpoint 里的module导致键值不匹配

    参考blog1

    参考bolg2

    展开全文
  • Three.js模型加载速度

    千次阅读 2020-11-02 10:25:48
    Threejs开发项目加载模型,可能会比较大,模型三角形面数越多,一方面是threejs渲染模型的性能下降,另一方面是加载模型的时间比较长,影响体验。 因为三维模型文件往往比较大,所以Web3D项目相比较普通的前端web...
  • 今天小编就为大家分享一篇TensorFlow加载模型时出错的解决方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • tensorflow2.0入门实例三(模型加载

    万次阅读 2019-10-21 13:47:07
    做东西,最重要的就是动手了,所以这篇文章主要教...文章使用的是tensorflow2.0框架,该框架集成了keras,在模型的训练方面极其简洁,不像tf1.x那么复杂,综合其他深度学习框架,发现这个是最适合新手使用的一种。 ...
  • pytorch 模型加载部分权重与部分模型加载权重

    千次阅读 多人点赞 2019-06-20 21:20:38
    模型加载部分权重 model = ... model_dict = model.state_dict() pretrained_dict = torch.load(load_name) # 1. filter out unnecessary keys pretrained_dict = {k: v for k, v in model_dict.items() if k in ...
  • 现代OpenGL,利用Assimp进行3d模型加载的一个Demo,提供了两个3d模型,能很好的加载含纹理的.obj格式的3d模型。博客地址:https://blog.csdn.net/lady_killer9/article/details/89458246
  • 前面介绍了光照基础...本节开始介绍模型加载,通过加载丰富的模型,能够丰富我们的场景,变得好玩。本节的示例代码均可以在我的github下载。 加载模型可以使用比较好的库,例如obj模型加载的库,Assimp加载库。本节
  • PyTorch 实战(模型训练、模型加载、模型测试)

    万次阅读 多人点赞 2019-07-30 10:25:18
    加载模型->测试模型 自定义数据集 参考我的上一篇博客:自定义数据集处理 数据加载 默认小伙伴有对深度学习框架有一定的了解,这里就不做过多的说明了。 好吧,还是简单的说一下吧: 我们在做好了自定义数据...
  • python训练好的模型保存与加载 当我们训练好一个模型model后,如果在其他程序中或者下次想继续使用这个model,我们就需要把这个model保存下来,下次使用时直接导入就好了,不需要重新训练。 方式一: 采用joblib模块...
  • 主要介绍了Keras 加载已经训练好的模型进行预测操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • Cesium bim模型加载并与模型树关联(分层加载)

    千次阅读 多人点赞 2019-10-21 17:24:57
    最近没事儿写了个模型树和模型关联的功能,处理工具是用的cesiumlab。 说明一下为什么要用cesiumlab: 网上现在有很多的模型转换工具,如obj23dtiles等均可以对非3dtiles的模型进行处理,为何非得用cesiumlab呢?...
  • Cesium从入门到放弃6:模型加载

    千次阅读 2020-03-04 14:51:26
    Cesium支持的模型有两种:一是gltf/glb,二是3dtileset,其它格式的模型需要转换成这两种格式才能在Cesium上添加,通常来说大数据的模型一般使用3dtileset,因为它是做了LOD在gltf,性能更好。 ...
  • PyTorch GPU上训练的模型加载到CPU

    千次阅读 2021-01-05 10:20:14
    PyTorch GPU上训练的模型加载到CPU net.load_state_dict(torch.load(model_file, map_location='cpu')) 不设置map_location参数则会报错: RuntimeError: Attempting to deserialize object on a CUDA device but ...
  • Keras中实现.H5模型加载与测试

    千次阅读 2020-01-09 09:36:06
    Keras中实现.H5模型加载与测试 安装命令(使用清华镜像): pip install -i https://pypi.tuna.tsinghua.edu.cn/simple 要安装的库 相关的库: import os from keras.models import load_model import numpy as np ...
  • 今天小编就为大家分享一篇Pytorch加载部分预训练模型的参数实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • 详见:https://www.cnblogs.com/wmlj/p/9917827.html
  • pytorch模型加载.pth文件与使用心得

    万次阅读 多人点赞 2019-09-04 20:59:13
    pyroch使用心得1.pytorch模型加载的方法1.1 保存整个神经网络的结构信息和模型的参数信息,save的对象是网络net1.2. 只保存神经网络的训练模型**参数**,save的对象是net.state_dict()1.3pytorch预训练模型1.4只加载...
  • torch 模型加载和保存模型

    千次阅读 2019-01-04 10:38:20
    先有一个模型: my_resnet = MyResNet(*args, **kwargs) 两种加载权重方法: 1.基于推荐保存的方式 保存方式: torch.save(my_resnet.state_dict(), &quot;my_resnet.pth&quot;) 对应的加载方式: my_...
  • THREE 大量模型加载优化

    千次阅读 2019-03-27 15:12:01
    THREE 大量模型加载优化 测试10W以上盒子性能 第一种方法加载完毕后FPS为60; 第二种加载完毕后15 //第一种 const random = () => { let number = Math.random() * 5000; return Math.random() < 0.5 ? 0 - ...
  • 可以从官网加载预训练好的模型: import torchvision.models as models model = models.vgg16(pretrained = True) print(model) 但是经常会出现因为下载速度太慢而出现requests.exceptions.ConnectionError: (...
  • mxnet——模型加载与保存

    千次阅读 2018-12-04 16:28:32
    一、加载模型与pretrain模型network相同 # loading predict module data_shape_G = 96 Batch = namedtuple('Batch',['data']) sym, arg_params, aux_params = mx.model.load_checkpoint(prefix=r"~/meh_cla&...
  • Opengl学习之模型加载——Assimp

    万次阅读 2017-08-13 14:27:24
    Assimp首先介绍一下Assimp库,它是Opengl中常使用的模型加载库,全称 Open Asset Import Library。它支持多种格式的模型文件,如obj、3ds、c4e等。模型一般通过Blender、3DS Max 或者Maya这样的工具软件制作,然后...
  • Android OpenGLES2.0(十四)——Obj格式3D模型加载

    万次阅读 热门讨论 2017-01-10 02:11:19
    自然是通过其他工具类似于Maya、3DMax等3D建模工具,做好模型导出来,然后用OpenGLES加载导出的模型文件。模型加载大同小异,本篇博客是以Obj格式的3D模型为例。 模型文件 本篇博客例子中加载的是一个帽子,
  • Three.js之模型加载

    千次阅读 2018-08-20 16:05:35
    外部模型 Three.js有一系列导入外部文件的辅助函数,是在three.js之外的,使用前需要额外下载,在https://github.com/mrdoob/three.js/tree/master/examples/js/loaders可以找到。 *.obj是最常用的模型格式,导入*...
  • Spark ML关于模型保存,模型加载案例

    千次阅读 2019-04-28 17:07:00
    package ... import org.apache.spark.SparkConf import org.apache.spark.ml.{Pipeline, PipelineModel} import org.apache.spark.ml.classification.LogisticRegression import org.apache.spark....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 524,383
精华内容 209,753
关键字:

模型加载