深度学习框架:ONNX:ONNX模型的动态图与静态图转换_第1页
深度学习框架:ONNX:ONNX模型的动态图与静态图转换_第2页
深度学习框架:ONNX:ONNX模型的动态图与静态图转换_第3页
深度学习框架:ONNX:ONNX模型的动态图与静态图转换_第4页
深度学习框架:ONNX:ONNX模型的动态图与静态图转换_第5页
已阅读5页,还剩13页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

深度学习框架:ONNX:ONNX模型的动态图与静态图转换1深度学习与ONNX简介1.1深度学习框架概述深度学习框架是构建和训练深度学习模型的软件工具,它们提供了高级API,使得开发者能够轻松地定义、训练和部署神经网络模型。常见的深度学习框架包括TensorFlow、PyTorch、Keras、Caffe、MXNet等。这些框架各有特点,例如TensorFlow以其强大的图形计算能力著称,而PyTorch则以动态计算图和易于调试的特性受到欢迎。1.1.1示例:使用TensorFlow定义一个简单的神经网络importtensorflowastf

#定义输入和输出数据

X=tf.placeholder(tf.float32,[None,784])

Y=tf.placeholder(tf.float32,[None,10])

#定义模型参数

W=tf.Variable(tf.zeros([784,10]))

b=tf.Variable(tf.zeros([10]))

#定义模型

pred=tf.nn.softmax(tf.matmul(X,W)+b)

#定义损失函数和优化器

cost=tf.reduce_mean(-tf.reduce_sum(Y*tf.log(pred),reduction_indices=1))

optimizer=tf.train.GradientDescentOptimizer(0.5).minimize(cost)

#初始化所有变量

init=tf.global_variables_initializer()

#启动会话

withtf.Session()assess:

sess.run(init)

#假设我们有训练数据train_x和train_y

forstepinrange(1000):

sess.run(optimizer,feed_dict={X:train_x,Y:train_y})1.2ONNX的作用与优势ONNX(OpenNeuralNetworkExchange)是一个开放的格式,用于表示深度学习模型。ONNX使得模型可以在不同的框架之间进行转换和共享,从而提高了模型的可移植性和可重用性。ONNX支持多种深度学习框架,包括TensorFlow、PyTorch、Keras等,以及多种推理引擎,如TensorRT、OpenVINO、CoreML等。ONNX的主要优势包括:-跨框架兼容性:ONNX模型可以在不同的框架和硬件上运行,无需重新训练。-优化和加速:ONNX模型可以被优化工具进一步优化,提高推理速度。-标准化:ONNX提供了一种标准化的模型表示,便于模型的管理和部署。1.2.1示例:将TensorFlow模型转换为ONNX模型importtensorflowastf

fromtf2onnximporttf2onnx,processing

#假设我们有已经训练好的模型

#model是一个tf.keras.Model实例

spec=(tf.TensorSpec((None,784),tf.float32,name="input"),)

output_path="model.onnx"

#转换模型

tf2onnx.convert.from_keras(model,input_signature=spec,opset=13,output_path=output_path)1.3ONNX模型的基本概念ONNX模型由一系列的节点(Node)组成,每个节点代表一个操作,如加法、乘法、卷积等。节点之间通过张量(Tensor)连接,张量可以是模型的输入、输出或中间结果。ONNX模型还包含一个图(Graph),图中包含了所有节点和张量的连接关系,以及模型的输入和输出信息。ONNX模型的结构可以使用ONNX的可视化工具进行查看,如Netron。这有助于理解模型的内部结构和操作流程。1.3.1示例:使用ONNX查看模型结构#假设我们有名为model.onnx的ONNX模型

netron.model.onnx(model.onnx)注意:上述示例中的Netron是一个独立的可视化工具,需要在本地安装并运行。在命令行中使用netronmodel.onnx可以打开模型的可视化界面。1.4结论ONNX作为深度学习模型的开放标准,极大地促进了模型的跨框架共享和部署。通过将模型转换为ONNX格式,开发者可以轻松地在不同的框架和硬件上运行模型,同时利用各种优化工具提高模型的推理速度。理解ONNX模型的基本概念和操作流程,对于深度学习模型的管理和部署具有重要意义。2静态图与动态图基础2.1静态图模型解释在深度学习框架中,静态图模型是一种常见的计算图表示方式。在静态图模型中,计算图在训练或推理开始前就已经完全定义好,这意味着所有的操作和数据流在模型构建阶段就已经确定,不会在运行时改变。这种模型构建方式在TensorFlow1.x和PyTorch的静态图模式中得到广泛应用。2.1.1原理静态图模型的核心在于图构建和图执行两个阶段。在图构建阶段,开发者通过API定义计算图的结构,包括输入、输出、操作节点和数据流。在图执行阶段,计算图被优化并执行,通常在GPU或TPU上进行,以加速计算过程。2.1.2代码示例以下是一个使用TensorFlow1.x构建静态图模型的示例:importtensorflowastf

#创建占位符,用于输入数据

x=tf.placeholder(tf.float32,shape=[None,784])

y=tf.placeholder(tf.float32,shape=[None,10])

#定义模型参数

W=tf.Variable(tf.zeros([784,10]))

b=tf.Variable(tf.zeros([10]))

#定义计算图

y_pred=tf.nn.softmax(tf.matmul(x,W)+b)

#定义损失函数和优化器

cross_entropy=tf.reduce_mean(-tf.reduce_sum(y*tf.log(y_pred),reduction_indices=[1]))

train_step=tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)

#初始化所有变量

init=tf.global_variables_initializer()

#创建会话并执行计算图

withtf.Session()assess:

sess.run(init)

#假设`mnist_data`是MNIST数据集

for_inrange(1000):

batch=mnist_data.train.next_batch(100)

sess.run(train_step,feed_dict={x:batch[0],y:batch[1]})在这个例子中,我们定义了一个简单的线性模型,用于手写数字识别。tf.placeholder用于定义输入数据的占位符,tf.Variable用于定义模型参数。计算图在y_pred和cross_entropy中定义,而train_step则定义了优化过程。最后,我们通过tf.Session执行计算图,使用MNIST数据集进行训练。2.2动态图模型解释动态图模型,也称为动态计算图,允许在运行时构建和修改计算图。这意味着模型的结构可以基于输入数据或运行时条件动态调整。动态图模型在PyTorch和TensorFlow2.x中得到了广泛支持,提供了更灵活的编程模型。2.2.1原理动态图模型的核心在于即时编译(Just-In-TimeCompilation,JIT)。在运行时,框架会根据代码动态构建计算图,并在需要时即时编译和执行。这种模式下,开发者可以使用更接近Python的编程方式,如循环、条件语句和变量赋值,来构建模型。2.2.2代码示例以下是一个使用PyTorch构建动态图模型的示例:importtorch

importtorch.nnasnn

#定义模型类

classDynamicModel(nn.Module):

def__init__(self):

super(DynamicModel,self).__init__()

self.fc1=nn.Linear(784,128)

self.fc2=nn.Linear(128,10)

defforward(self,x):

x=torch.relu(self.fc1(x))

x=self.fc2(x)

returntorch.softmax(x,dim=1)

#实例化模型

model=DynamicModel()

#定义损失函数和优化器

criterion=nn.CrossEntropyLoss()

optimizer=torch.optim.SGD(model.parameters(),lr=0.01)

#假设`mnist_data`是MNIST数据集

forepochinrange(10):

forbatch,(inputs,labels)inenumerate(mnist_data.train_loader):

optimizer.zero_grad()

outputs=model(inputs)

loss=criterion(outputs,labels)

loss.backward()

optimizer.step()在这个例子中,我们定义了一个包含两个全连接层的动态模型。nn.Module是PyTorch中定义模型的基础类,forward方法用于定义模型的前向传播过程。我们使用torch.relu和torch.softmax作为激活函数,这些函数在运行时根据输入数据动态执行。模型的训练过程通过循环和条件语句实现,这在静态图模型中是不可行的。2.3静态图与动态图的差异静态图和动态图模型在深度学习框架中有着本质的区别:构建方式:静态图模型在构建阶段定义整个计算流程,而动态图模型在运行时根据代码动态构建计算图。灵活性:动态图模型提供了更高的灵活性,支持更复杂的控制流结构,如循环和条件语句。优化和执行:静态图模型在执行前可以进行更深入的优化,如操作融合和内存优化,而动态图模型的优化通常在运行时进行,可能不如静态图模型高效。调试和可视化:静态图模型的计算图可以更容易地进行调试和可视化,因为图结构在构建阶段就已经确定。动态图模型的计算图在运行时构建,调试和可视化可能更复杂。选择静态图还是动态图模型,取决于具体的应用场景和需求。静态图模型在大规模训练和高性能推理场景中表现更优,而动态图模型则在需要高度灵活性和动态调整模型结构的场景中更为适用。3ONNX模型的静态图转换3.1静态图转换的准备工作在开始将静态图模型转换为ONNX格式之前,有几个关键的准备工作需要完成:安装必要的库:确保你的环境中已经安装了ONNX和你所使用的深度学习框架(如TensorFlow,PyTorch等)的库。例如,对于TensorFlow,你可以使用以下命令安装ONNX和TensorFlow的ONNX转换工具:pipinstallonnx

pipinstalltf2onnx模型准备:确保你的模型已经训练完成并且保存为静态图模型。静态图模型在构建时定义了所有操作,而这些操作在运行时不会改变。例如,在TensorFlow中,你可以使用tf.saved_model.save来保存模型。数据准备:虽然转换过程不需要数据,但在模型优化和验证阶段,你需要准备一些数据样本来测试模型的输出是否正确。3.2使用ONNX将静态图模型转换为ONNX格式3.2.1TensorFlow模型转换示例假设你有一个已经训练好的TensorFlow模型,保存在saved_model目录下,现在你想要将其转换为ONNX格式。以下是使用tf2onnx进行转换的步骤:importtf2onnx

importtensorflowastf

#加载TensorFlow模型

model=tf.saved_model.load('saved_model')

#获取模型的输入和输出节点

input_signature=tf.TensorSpec(shape=(None,224,224,3),dtype=tf.float32)

output_path="model.onnx"

#转换模型

tf2onnx.convert.from_keras(model,input_signature=[input_signature],opset=13,output_path=output_path)在这个例子中,我们首先加载了保存的TensorFlow模型。然后,我们定义了模型的输入签名,这告诉ONNX模型的输入形状和类型。最后,我们使用tf2onnx.convert.from_keras函数将模型转换为ONNX格式,并指定了输出文件的路径。3.2.2PyTorch模型转换示例如果你使用的是PyTorch框架,转换过程会略有不同:importtorch

importonnx

#加载PyTorch模型

model=torch.load('model.pth')

#定义模型的输入

dummy_input=torch.randn(1,3,224,224)

#转换模型

torch.onnx.export(model,dummy_input,"model.onnx",verbose=True,opset_version=13)在这个PyTorch的例子中,我们首先加载了模型。然后,我们创建了一个虚拟的输入张量,这将用于模型的转换。最后,我们使用torch.onnx.export函数将模型转换为ONNX格式,同时指定了输出文件的路径。3.3静态图模型的优化与验证3.3.1模型优化ONNX模型转换完成后,可以使用ONNX优化工具来进一步优化模型,例如,使用onnx-simplifier库:pipinstallonnx-simplifier

#使用onnx-simplifier优化模型

python-monnxsimmodel.onnxmodel_optimized.onnx优化过程可以减少模型的冗余,提高模型的运行效率。3.3.2模型验证验证ONNX模型的正确性是转换过程中的重要一步。你可以使用ONNX的check函数来验证模型的结构是否正确:importonnx

#加载ONNX模型

model=onnx.load("model.onnx")

#验证模型

onnx.checker.check_model(model)如果模型结构正确,onnx.checker.check_model函数将不会抛出任何异常。此外,你还可以使用数据样本来验证模型的输出是否与原始框架中的输出一致。例如,使用TensorFlow和ONNX模型进行预测,并比较结果:importonnxruntime

importnumpyasnp

#使用ONNX模型进行预测

ort_session=onnxruntime.InferenceSession("model.onnx")

ort_inputs={ort_session.get_inputs()[0].name:np.random.randn(1,224,224,3).astype(np.float32)}

ort_outs=ort_session.run(None,ort_inputs)

#使用TensorFlow模型进行预测

tf_outs=model(np.random.randn(1,224,224,3).astype(np.float32))

#比较输出

np.testing.assert_allclose(ort_outs[0],tf_outs[0],rtol=1e-03,atol=1e-05)在这个例子中,我们首先加载了ONNX模型,并使用ONNX运行时(onnxruntime)进行预测。然后,我们使用相同的输入数据在原始的TensorFlow模型中进行预测。最后,我们使用np.testing.assert_allclose函数来比较两个模型的输出,确保它们在数值上是接近的。通过这些步骤,你可以确保你的静态图模型在转换为ONNX格式后仍然保持其功能和性能。4ONNX模型的动态图转换4.1动态图转换的准备工作在开始将动态图模型转换为ONNX格式之前,有几个关键的准备工作需要完成:安装必要的库:确保你的环境中安装了ONNX、ONNXRuntime以及你所使用的深度学习框架(如PyTorch、TensorFlow等)。模型选择:确定你想要转换的动态图模型。动态图模型通常在训练时定义,允许在运行时动态调整网络结构。数据准备:准备用于模型验证的数据集。这将用于在转换后的模型上进行测试,确保其性能与原始模型一致。模型评估:在转换前,对模型进行评估,记录其性能指标,以便与转换后的模型进行对比。4.1.1示例:PyTorch模型转换前的准备工作#导入必要的库

importtorch

importtorchvision

importonnx

#选择模型

model=torchvision.models.resnet18(pretrained=True)

#将模型设置为评估模式

model.eval()

#准备数据

dummy_input=torch.randn(1,3,224,224)

#模型评估

output=model(dummy_input)

print(output)4.2使用ONNX将动态图模型转换为ONNX格式ONNX提供了工具和API来将动态图模型转换为ONNX格式,这一步骤是模型部署和优化的关键。4.2.1示例:将PyTorch动态图模型转换为ONNX#导入必要的库

importtorch

importtorchvision

importonnx

fromonnximportshape_inference

#选择模型

model=torchvision.models.resnet18(pretrained=True)

#将模型设置为评估模式

model.eval()

#准备数据

dummy_input=torch.randn(1,3,224,224)

#转换模型

torch.onnx.export(model,dummy_input,"resnet18.onnx",verbose=True,opset_version=11)

#使用ONNX的shape_inference来检查模型

model_proto=onnx.load("resnet18.onnx")

inferred_model=shape_inference.infer_shapes(model_proto)

onnx.save(inferred_model,"resnet18_inferred.onnx")4.3动态图模型的优化与验证转换后的ONNX模型可以通过ONNXRuntime进行优化和加速,同时需要验证模型的准确性和性能。4.3.1示例:使用ONNXRuntime优化和验证模型#导入必要的库

importonnxruntime

importnumpyasnp

#加载ONNX模型

ort_session=onnxruntime.InferenceSession("resnet18_inferred.onnx")

#准备输入数据

ort_inputs={ort_session.get_inputs()[0].name:to_numpy(dummy_input)}

#运行模型

ort_outs=ort_session.run(None,ort_inputs)

#验证模型输出

np.testing.assert_allclose(to_numpy(output),ort_outs[0],rtol=1e-03,atol=1e-05)

print("ExportedmodelhasbeentestedwithONNXRuntime,andtheresultlooksgood!")4.3.2代码解释在上述代码中,我们首先加载了转换后的ONNX模型到ONNXRuntime中。然后,我们准备了输入数据,将其从PyTorch的Tensor格式转换为NumPy的ndarray格式,这是因为ONNXRuntime接受NumPy格式的数据作为输入。接下来,我们运行模型并获取输出。最后,我们使用np.testing.assert_allclose函数来验证ONNX模型的输出与原始PyTorch模型的输出是否一致,从而确保转换过程没有引入错误。4.3.3验证步骤性能测试:使用相同的数据集,比较ONNX模型与原始模型的运行时间。准确性测试:确保ONNX模型的预测结果与原始模型一致,可以使用相同的测试数据集和评估指标。通过这些步骤,我们可以确保动态图模型在转换为ONNX格式后,不仅保持了原有的功能,而且可能在某些平台上获得了更好的性能。5动态图与静态图之间的转换5.1ONNX支持的转换方法在深度学习领域,模型的图结构可以分为动态图和静态图。动态图允许在运行时定义和修改计算图,而静态图则在模型编译时确定计算图结构。ONNX(OpenNeuralNetworkExchange)作为模型交换格式,支持多种深度学习框架之间的模型转换,同时也提供了从动态图到静态图的转换方法。5.1.1动态图到静态图的转换ONNX通过其API和工具链,可以将动态图模型(如PyTorch中的模型)转换为静态图模型。这一过程通常涉及模型的导出和优化,以确保转换后的模型在不同的执行环境中能够高效运行。示例:PyTorch模型到ONNX的转换importtorch

fromtorch.autogradimportVariable

importonnx

#定义一个简单的动态图模型

classDynamicModel(torch.nn.Module):

defforward(self,x):

ifx.size(0)>10:

returntorch.nn.functional.relu(x)

else:

returntorch.nn.functional.tanh(x)

#创建模型实例

model=DynamicModel()

#随机生成输入数据

x=Variable(torch.randn(20,5))

#将动态图模型转换为ONNX模型

torch.onnx.export(model,x,"dynamic_model.onnx",verbose=True,input_names=['input'],output_names=['output'])

#加载ONNX模型并检查

onnx_model=onnx.load("dynamic_model.onnx")

onnx.checker.check_model(onnx_model)在上述代码中,我们首先定义了一个简单的动态图模型DynamicModel,该模型根据输入数据的大小动态选择ReLU或Tanh激活函数。然后,我们使用torch.onnx.export函数将模型转换为ONNX格式,其中input_names和output_names用于指定模型的输入和输出名称。5.1.2静态图到动态图的转换虽然ONNX主要被用于从动态图模型转换到静态图模型,但也可以通过一些框架的特性,如TensorFlow的tf.function,将静态图模型转换为动态图模型。示例:ONNX模型到TensorFlow的转换importonnx

importtf2onnx

importtensorflowastf

#加载ONNX模型

onnx_model=onnx.load("dynamic_model.onnx")

#将ONNX模型转换为TensorFlow模型

tf_rep=tf2onnx.tf_loader.tf_rep_from_onnx(onnx_model)

tf.import_graph_def(tf_rep.graph_def,name='')

#创建TensorFlow会话并运行模型

withtf.Session()assess:

#获取输入输出张量

input_tensor=sess.graph.get_tensor_by_name('input:0')

output_tensor=sess.graph.get_tensor_by_name('output:0')

#随机生成输入数据

x=np.random.randn(20,5).astype(np.float32)

#运行模型

output=sess.run(output_tensor,feed_dict={input_tensor:x})在这个例子中,我们首先加载了之前通过PyTorch导出的ONNX模型。然后,使用tf2onnx库将ONNX模型转换为TensorFlow的计算图。最后,我们创建了一个TensorFlow会话,并通过会话运行了模型,以验证转换是否成功。5.2转换过程中的常见问题与解决方案在将动态图模型转换为静态图模型,或反之亦然的过程中,可能会遇到一些常见问题。这些问题通常与模型的动态特性、框架的兼容性以及ONNX支持的操作有关。5.2.1动态特性问题动态图模型可能包含条件语句或循环结构,这些在静态图模型中需要被展开或转换为等效的静态操作。解决方案条件语句:ONNX支持If操作,可以用来替换动态图中的条件语句。但在转换时,需要确保所有可能的分支都被正确地表示。循环结构:ONNX的Loop操作可以用来表示循环。转换时,需要确定循环的次数或条件,以便在静态图中正确地展开循环。5.2.2兼容性问题不同的深度学习框架可能使用不同的数据类型或操作,这些在转换时需要被适配到ONNX支持的格式。解决方案数据类型适配:ONNX支持多种数据类型,包括浮点数、整数和布尔值。在转换时,需要确保模型中的数据类型与ONNX兼容。操作适配:ONNX定义了一套标准的操作集,但并非所有框架的操作都能直接映射到ONNX操作。对于不支持的操作,可以尝试使用ONNX的自定义操作,或者将操作分解为ONNX支持的多个操作。5.2.3ONNX支持的操作问题ONNX虽然支持广泛的操作,但并非所有深度学习框架的操作都能在ONNX中找到等效的替代。解决方案操作映射:查阅ONNX官方文档,了解框架操作与ONNX操作之间的映射关系。自定义操作:对于ONNX不支持的操作,可以定义自定义操作,并在转换时使用这些操作。5.3转换后的模型性能分析转换后的模型性能可能受到多种因素的影响,包括模型的复杂度、转换过程中的优化、以及目标执行环境的特性。5.3.1性能评估方法基准测试:在转换前后,使用相同的数据集和相同的硬件环境进行基准测试,比较模型的运行时间、内存使用和计算资源消耗。精度验证:确保转换后的模型在预测结果上与原模型保持一致,可以通过计算转换前后模型预测结果的差异来验证。5.3.2性能优化策略模型简化:在转换过程中,可以使用ONNX的简化工具,如onnx-simplifier,来减少模型的复杂度,从而提高性能。量化:将模型的权重和激活量化为较低的精度,如8位整数,可以减少模型的大小和提高运行速度。硬件优化:根据目标执行环境的硬件特性,如GPU或特定的加速器,对模型进行优化,以充分利用硬件资源。5.3.3示例:性能分析importonnxruntime

importnumpyasnp

#加载ONNX模型

ort_session=onnxruntime.InferenceSession("dynamic_model.onnx")

#随机生成输入数据

x=np.random.randn(20,5).astype(np.float32)

#运行模型并测量时间

start_time=time.time()

output=ort_session.run(None,{'input':x})

end_time=time.time()

#输出运行时间

print(f"ONNX模型运行时间:{end_time-start_time}秒")在这个例子中,我们使用onnxruntime来加载和运行ONNX模型,并通过测量模型运行时间来评估性能。通过与原框架的模型运行时间进行比较,可以分析转换对模型性能的影响。转换模型时,理解动态图与静态图之间的差异,以及如何处理转换过程中的常见问题,对于确保模型在不同框架和执行环境中的正确性和性能至关重要。通过上述方法和策略,可以有效地进行模型转换,并对转换后的模型性能进行分析和优化。6深度学习框架:ONNX模型的动态图与静态图转换实战案例分析6.1静态图模型转换为动态图模型的案例6.1.1原理与内容静态图(StaticGraph)和动态图(DynamicGraph)是深度学习模型中两种不同的计算图表示方式。静态图在模型构建时就确定了计算图的结构,而动态图则允许在运行时根据输入数据的形状和大小动态调整计算图。ONNX(OpenNeuralNetworkExchange)作为模型交换格式,支持从静态图模型转换为动态图模型,以适应不同的框架和运行环境。转换步骤加载静态图模型:使用ONNX加载静态图模型。分析模型结构:检查模型的输入输出,以及模型中的节点和操作。修改模型结构:根据动态图框架的要求,修改模型中的静态维度为动态维度。保存动态图模型:将修改后的模型保存为新的ONNX模型。示例代码importonnx

fromonnximporthelper

#加载静态图模型

model_path='static_model.onnx'

static_model=onnx.load(model_path)

#分析模型结构

forinputinstatic_model.graph.input:

print("Originalinputshape:",input.type.tensor_type.shape)

#修改模型结构,将静态维度转换为动态维度

forinputinstatic_model.graph.input:

dim=input.type.tensor_type.shape.dim

fordindim:

ifd.dim_value>0:

d.dim_param='batch_size'

d.dim_value=0

#保存动态图模型

onnx.save(static_model,'dynamic_model.onnx')6.1.2动态图模型转换为静态图模型的案例原理与内容从动态图模型转换为静态图模型的过程与上述相反。在动态图模型中,计算图的结构可以在运行时动态调整,但在某些情况下,如部署在特定硬件上,可能需要固定模型的计算图结构,以优化性能。转换步骤加载动态图模型:使用ONNX加载动态图模型。确定静态维度:根据模型的使用场景,确定输入输出的静态维度。修改模型结构:将模型中的动态维度替换为静态维度。保存静态图模型:将修改后的模型保存为新的ONNX模型。示例代码importonnx

#加载动态图模型

model_path='dynamic_model.onnx'

dynamic_model=onnx.load(model_path)

#分析模型结构

forinputindy

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论