扒扒Tiny YoloV3的.weights文件经过TensorFlow处理后得到的Frozen Graph里面有什么

最近要把tiny yolov3的模型移植到NCS2,从.weights文件到IE model的转化相当繁琐(见另外一篇博文《在树莓派+Intel NCS2上跑YoloV3 Tiny》),并且TensorFlow的版本不对还报错,实在是讨厌。
一直没怎么用tensorflow,将来打算在darknet里面直接输出.pb文件(而不是.weights文件),今天先扒了扒tensorflow 1.9环境下生成的tiny_yolov3.pb文件。
附生成命令(Window10 + Python 3.6.7+ TensorFlow 1.9.0):

python ../tensorflow-yolo-v3/convert_weights_pb.py --weights_file yolov3-tiny.weights \
       --class_names coco.names  --tiny True --size 416 --data_format NHWC \
       --output_graph yolov3-tiny.pb

使用ProtoBuf 3.0.0生成*.pb.h和*.pb.cc,如图
在这里插入图片描述
解析程序代码main.cpp(Compiled under Visual Studio 2015):


/*****************************************************************
main.cpp
******************************************************************/
#include <iostream>
#include <fstream>
#include <google/protobuf/util/time_util.h>
#include "tensorflow/core/framework/graph.pb.h"

using namespace std;

using google::protobuf::util::TimeUtil;

using namespace tensorflow;

constexpr char* pb_path = "E:\\AI\\OpenVINO\\COCO\\tiny_yolov3.pb";

static const char* type_to_str(tensorflow::DataType t) {
   
   

	switch (t)
	{
   
   
	case tensorflow::DT_INVALID:
		return "Invalid";
	case tensorflow::DT_FLOAT:
		return "Float";
	case tensorflow::DT_DOUBLE:
		return "Double";
	case tensorflow::DT_INT32:
		return "Int32";
	case tensorflow::DT_UINT8:
		return "Uint8";
	case tensorflow::DT_INT16:
		return "Uint16";
	case tensorflow::DT_INT8:
		return "Int8";
	case tensorflow::DT_STRING:
		return "String";
	case tensorflow::DT_COMPLEX64:
		return "Complex64";
	case tensorflow::DT_INT64:
		return "Int64";
	case tensorflow::DT_BOOL:
		return "Bool";
	case tensorflow::DT_QINT8:
		return "Qint8";
	case tensorflow::DT_QUINT8:
		return "QUint8";
	case tensorflow::DT_QINT32:
		return "Qint32";
	case tensorflow::DT_BFLOAT16:
		return "BFloat16";
	case tensorflow::DT_QINT16:
		return "Qint16";
	case tensorflow::DT_QUINT16:
		return "Quint16";
	case tensorflow::DT_UINT16:
		return "Uint16";
	case tensorflow::DT_COMPLEX128:
		return "Complex128";
	case tensorflow::DT_HALF:
		return "Half";
	case tensorflow::DT_RESOURCE:
		return "Resource";
	case tensorflow::DT_VARIANT:
		return "Variant";
	case tensorflow::DT_UINT32:
		return "Uint32";
	case tensorflow::DT_UINT64:
		return "Uint64";
	case tensorflow::DT_FLOAT_REF:
		return "FloatRef";
	case tensorflow::DT_DOUBLE_REF:
		return "DoubleRef";
	case tensorflow::DT_INT32_REF:
		return "Int32Ref";
	case tensorflow::DT_UINT8_REF:
		return "Uint8Ref";
	case tensorflow::DT_INT16_REF:
		return "Int16Ref";
	case tensorflow::DT_INT8_REF:
		return "Int8Ref";
	case tensorflow::DT_STRING_REF:
		return "StringRef";
	case tensorflow::DT_COMPLEX64_REF:
		return "Complex64Ref";
	case tensorflow::DT_INT64_REF:
		return "Int64Ref";
	case tensorflow::DT_BOOL_REF:
		return "BoolRef";
	case tensorflow::DT_QINT8_REF:
		return "Qint8Ref";
	case tensorflow::DT_QUINT8_REF:
		return "QUint8Ref";
	case tensorflow::DT_QINT32_REF:
		return "QUint32Ref";
	case tensorflow::DT_BFLOAT16_REF:
		return "DT_BFLOAT16_REF";
	case tensorflow::DT_QINT16_REF:
		return "DT_QINT16_REF";
	case tensorflow::DT_QUINT16_REF:
		return "DT_QUINT16_REF";
	case tensorflow::DT_UINT16_REF:
		return "DT_UINT16_REF";
	case tensorflow::DT_COMPLEX128_REF:
		return "DT_COMPLEX128_REF";
	case tensorflow::DT_HALF_REF:
		return "DT_HALF_REF";
	case tensorflow::DT_RESOURCE_REF:
		return "DT_RESOURCE_REF";
	case tensorflow::DT_VARIANT_REF:
		return "DT_VARIANT_REF";
	case tensorflow::DT_UINT32_REF:
		return "DT_UINT32_REF";
	case tensorflow::DT_UINT64_REF:
		return "DT_UINT64_REF"; 
	default:
		return "Illegal";
	}
	return "";
}
void dump_attr(ostream& of, const AttrValue& v) {
   
   
	switch (v.value_case())
	{
   
   
	case tensorflow::AttrValue::kS:
		of << " type=\"String\" value=\"" << v.s() << "\" />" <<endl;
		break;
	case tensorflow::AttrValue::kI:
		of << " type=\"Integer\" value=\"" << v.i() << "\" />" << endl;
		break;
	case tensorflow::AttrValue::kF:
		of << " type=\"Float\" value=\"" << v.f() << "\" />" << endl;
		break;
	case tensorflow::AttrValue::kB:
		of << " type=\"Bool\" value=\"" << (v.b() ? "True": "False" ) << "\" />" << endl;
		break;
	case tensorflow::AttrValue::kType:
		of << " type=\"Type\" value=\"" << type_to_str(v.type()) << "\" />" << endl;
		break;
	case tensorflow::AttrValue::kShape:
	{
   
   
		const tensorflow::TensorShapeProto& sh = v.shape();
		of << " type=\"Shape\" dim-size=\"" << sh.dim_size() << "\" dims=\"[";
		for (int i = 0; i < sh.dim_size(); i++) {
   
   
			const tensorflow::TensorShapeProto_Dim& d = sh.dim(i);
			if ((i + 1) < sh.dim_size())
				of << d.size()<< ",";
			else
				of << d.size() << "]\" />" << endl;
		}
			 
		break;
	}
	case tensorflow::AttrValue::kTensor:
	{
   
   
		const tensorflow::TensorProto& t = v.tensor(); 
		const tensorflow::TensorShapeProto& sh = t.tensor_shape();
		size_t content_size = t.tensor_content().size();
		int dim_size = sh.dim_size();
		of << " type=\"Tensor\" type=\"" << type_to_str(t.dtype()) << "\"  dims=\"[";
		if(0 == dim_size)
			of << "]\"  size = \"" << content_size << "\" />" << endl;
		for (int i = 0; i < dim_size; i++) {
   
   
			const tensorflow::TensorShapeProto_Dim& d = sh.dim(i);
			if ((i + 1) < sh.dim_size())
				of << d.size() << ",";
			else
				of << d.size() << "]\"  bytes=\"" << content_size << "\" />" << endl;
		}
		 
		
		break;
	}
	case tensorflow::AttrValue::kList:
	{
   
   
		const tensorflow::AttrValue_ListValue& lv = v.list();
		of << " type=\"List\" ";
		if (lv.i_size() > 0) {
   
   
			of << "int-size=\"" << lv.i_size() << "\" int-vals=\"";
			for (int i = 0; i < lv.i_size(); i++) {
   
   
				if ((i + 1) < lv.i_size())
					of << lv.i(i) << ",";
				else
					of << lv.i(i) << "\" ";
			}
		}
		if (lv.s_size() > 0) {
   
   
			of << "string-size=\"" << lv.s_size() << "\" strings=\"";
			for (int i = 0; i < lv.s_size(); i++) {
   
   
				if ((i + 1) < lv.s_size())
					of << lv.s(i) << ",";
				else
					of << lv.s(i) << "\" "; 
			}
		} 
		if (lv.f_size() > 0) {
   
   
			of << "float-size=\"" << lv.s_size() << "\" float-vals=\"";
			for (int i = 0; i < lv.f_size(); i++) {
   
   
				if ((i + 1) < lv.f_size())
					of << lv.f(i) << ",";
				else
					of << lv.f(i) << "\" ";
			}
		}
		of << "/>" << endl; 
		break;
	}
	case tensorflow::AttrValue::kFunc:
		of << " type=\"Function\" name=\"" << v.func().name() << "\" />" << endl;
		break;
	case tensorflow::AttrValue::kPlaceholder:
		of << " type=\"PlaceHolder\" name=\"" << v.placeholder() << "\" />" << endl;
		break; 		 
	default:
		of << " type-value=\"" << (int)v.value_case() << "\" />" << endl;
		break;
	}
}

int main(int argc, char* argv[]) {
   
   

	// Verify that the version of the library that we linked against is
	// compatible with the version of the headers we compiled against.
	GOOGLE_PROTOBUF_VERIFY_VERSION;

	GraphDef graph;
	
	fstream input(pb_path, ios::in | ios::binary);
	if (!graph.ParseFromIstream(&input)) {
   
   
		cerr << "Failed to parse graph." << endl;
		return -1;
	}
	
	cout << "parse graph OK. node size:" << graph.node_size() << endl;
	fstream of("output.xml", ios::out | ios::trunc);
	if (!of.is_open()) {
   
   
		cerr << "open output.xml failed! " << endl;
		return -1;
	} 
	of << "<graphdef from=\"" << pb_path << "\" >" << endl ; 

	for (int i = 0; i < graph.node_size(); i++) {
   
   
		const NodeDef& d = graph.node(i);
		
		of << "\t<nodedef index=\"" << i << "\" name=\"" << d.name() << "\" op=\"" << d.op() <<  "\">" << endl;
		if (d.input_size() == 0)
			of << "\t\t<inputs />" << endl;
		else {
   
   
			of << "\t\t<inputs>" << endl;
			for (int j = 0; j < d.input_size(); j++) {
   
   
				of << "\t\t\t<input node=\"" << d.input(j) << "\" />" << endl;
			}
			of << "\t\t</inputs>" << endl;
		}
		const google::protobuf::Map<string, AttrValue>& m = d.attr();
		of << "\t\t<attributes>" << endl;
		for (google::protobuf::Map<string, AttrValue>::const_iterator it = m.begin(); it != m.end(); it++) {
   
   
			const AttrValue& v = it->second;
			of << "\t\t\t<attr name=\"" << it->first << "\" ";
			dump_attr(of,v); 
			
		}
		
		of << "\t\t</attributes>" << endl;
		of << "\t</nodedef>" << endl;
		
			
	}
	of << "</graphdef>" << endl;
	of.close();

	cout << "translated into .xml.\n";
	// Optional:  Delete all global objects allocated by libprotobuf.
	google::protobuf::ShutdownProtobufLibrary();

	return 0;
}

output.xml:

<graphdef from="E:\AI\OpenVINO\COCO\yolov3-tiny.pb" >
	<nodedef index="0" name="inputs" op="Placeholder">
		<inputs />
		<attributes>
			<attr name="dtype"  type="Type" value="Float" />
			<attr name="shape"  type="Shape" dim-size="4" dims="[-1,416,416,3]" />
		</attributes>
	</nodedef>
	<nodedef index="1" name="detector/truediv/y" op="Const">
		<inputs />
		<attributes>
			<attr name="value"  type="Tensor" type="Float"  dims="[]"  size = "0" />
			<attr name="dtype"  type="Type" value="Float" />
		</attributes>
	</nodedef>
	<nodedef index="2" name="detector/truediv" op="RealDiv">
		<inputs>
			<input node="inputs" />
			<input node="detector/truediv/y" />
		</inputs>
		<attributes>
			<attr name="T"  type="Type" value="Float" />
		</attributes>
	</nodedef>
	<nodedef index="3" name="detector/yolo-v3-tiny/Conv/weights" op="Const">
		<inputs />
		<attributes>
			<attr name="dtype"  type="Type" value="Float" />
			<attr name="value"  type="Tensor" type="Float"  dims="[3,3,3,16]"  bytes="1728" />
		</attributes>
	</nodedef>
	<nodedef index="4" name="detector/yolo-v3-tiny/Conv/weights/read" op="Identity">
		<inputs>
			<input node="detector/yolo-v3-tiny/Conv/weights" />
		</inputs>
		<attributes>
			<attr name="T"  type="Type" value="Float" />
			<attr name="_class"  type="List" string-size="1" strings="loc:@detector/yolo-v3-tiny/Conv/weights" />
		</attributes>
	</nodedef>
	<nodedef index="5" name="detector/yolo-v3-tiny/Conv/Conv2D" op="Conv2D">
		<inputs>
			<input node="detector/truediv" />
			<input node="detector/yolo-v3-tiny/Conv/weights/read" />
		</inputs>
		<attributes>
			<attr name="T"  type="Type" value="Float" />
			<attr name="strides"  type="List" int-size="4" int-vals="1,1,1,1" />
			<attr name="padding"  type="String" value="SAME" />
			<attr name="dilations"  type="List" int-size="4" int-vals="1,1,1,1" />
			<attr name="data_format"  type="String" value="NHWC" />
			<attr name="use_cudnn_on_gpu"  type="Bool" value="True" />
		</attributes>
	</nodedef>
	<nodedef index="6" name="detector/yolo-v3-tiny/Conv/BatchNorm/gamma" op="Const">
		<inputs />
		<attributes>
			<attr name="dtype"  type="Type" value="Float" />
			<attr name="value"  type="Tensor" type="Float"  dims="[16]"  bytes="64" />
		</attributes>
	</nodedef>
	<nodedef index="7" name="detector/yolo-v3-tiny/Conv/BatchNorm/gamma/read" op="Identity">
		<inputs>
			<input node="detector/yolo-v3-tiny/Conv/BatchNorm/gamma" />
		</inputs>
		<attributes>
			<attr name="T"  type="Type" value="Float" />
			<attr name="_class"  type="List" string-size="1" strings="loc:@detector/yolo-v3-tiny/Conv/BatchNorm/gamma" />
		</attributes>
	</nodedef>
	<nodedef index="8" name="detector/yolo-v3-tiny/Conv/BatchNorm/beta" op="Const">
		<inputs />
		<attributes>
			<attr name="dtype"  type="Type" value="Float" />
			<attr name="value"  type="Tensor" type="Float"  dims="[16]"  bytes="64" />
		</attributes>
	</nodedef>
	<nodedef index="9" name="detector/yolo-v3-tiny/Conv/BatchNorm/beta/read" op="Identity">
		<inputs>
			<input node="detector/yolo-v3-tiny/Conv/BatchNorm/beta" />
		</inputs>
		<attributes>
			<attr name="T"  type="Type" value="Float" />
			<attr name="_class"  type="List" string-size="1" strings="loc:@detector/yolo-v3-tiny/Conv/BatchNorm/beta" />
		</attributes>
	</nodedef>
	<nodedef index="10" name="detector/yolo-v3-tiny/Conv/BatchNorm/moving_mean" op="Const">
		<inputs />
		<attributes>
			<attr name="dtype"  type="Type" value="Float" />
			<attr name="value"  type="Tensor" type="Float"  dims="[16]"  bytes="64" />
		</attributes>
	</nodedef>
	<nodedef index="11" name="detector/yolo-v3-tiny/Conv/BatchNorm/moving_mean/read" op="Identity">
		<inputs>
			<input node="detector/yolo-v3-tiny/Conv/BatchNorm/moving_mean" />
		</inputs>
		<attributes>
			<attr name="T"  type="Type" value="Float" />
			<attr name="_class"  type="List" string-size="1" strings="loc:@detector/yolo-v3-tiny/Conv/BatchNorm/moving_mean" />
		</attributes>
	</nodedef>
	<nodedef index="12" name="detector/yolo-v3-tiny/Conv/BatchNorm/moving_variance" op="Const">
		<inputs />
		<attributes>
			<attr name="dtype"  type="Type" value="Float" />
			<attr name="value"  type="Tensor" type="Float"  dims="[16]"  bytes="64" />
		</attributes>
	</nodedef>
	<nodedef index="13" name="detector/yolo-v3-tiny/Conv/BatchNorm/moving_variance/read" op="Identity">
		<inputs>
			<input node="detector/yolo-v3-tiny/Conv/BatchNorm/moving_variance" />
		</inputs>
		<attributes>
			<attr name="T"  type="Type" value="Float" />
			<attr name="_class"  type="List" string-size="1" strings="loc:@detector/yolo-v3-tiny/Conv/BatchNorm/moving_variance" />
		</attributes>
	</nodedef>
	<nodedef index="14" name="detector/yolo-v3-tiny/Conv/BatchNorm/FusedBatchNorm" op="FusedBatchNorm">
		<inputs>
			<input node="detector/yolo-v3-tiny/Conv/Conv2D" />
			<input node="detector/yolo-v3-tiny/Conv/BatchNorm/gamma/read" />
			<input node="detector/yolo-v3-tiny/Conv/BatchNorm/beta/read" />
			<input node="detector/yolo-v3-tiny/Conv/BatchNorm/moving_mean/read" />
			<input node="detector/yolo-v3-tiny/Conv/BatchNorm/moving_variance/read" />
		</inputs>
		<attributes>
			<attr name="is_training"  type="Bool" value="False" />
			<attr name="T"  type="Type" value="Float" />
			<attr name="data_format"  type="String" value="NHWC" />
			<attr name="epsilon"  type="Float" value="1.001e-05" />
		</attributes>
	</nodedef>
	<nodedef index="15" name="detector/yolo-v3-tiny/Conv/LeakyRelu/alpha" op="Const">
		<inputs />
		<attributes>
			<attr name="value"  type="Tensor" type="Float"  dims="[]"  size = "0" />
			<attr name="dtype"  type="Type" value="Float" />
		</attributes>
	</nodedef>
	<nodedef index="16" name="detector/yolo-v3-tiny/Conv/LeakyRelu/mul" op="Mul">
		<inputs>
			<input node="detector/yolo-v3-tiny/Conv/LeakyRelu/alpha" />
			<input node="detector/yolo-v3-tiny/Conv/BatchNorm/FusedBatchNorm" />
		</inputs>
		<attributes>
			<attr name="T"  type="Type" value="Float" />
		</attributes>
	</nodedef>
	<nodedef index="17" name="detector/yolo-v3-tiny/Conv/LeakyRelu" op="Maximum">
		<inputs>
			<input node="detector/yolo-v3-tiny/Conv/LeakyRelu/mul" />
			<input node="detector/yolo-v3-tiny/Conv/BatchNorm/FusedBatchNorm" />
		</inputs>
		<attributes>
			<attr name="T"  type="Type" value="Float" />
		</attributes>
	</nodedef>
	<nodedef index="18" name="detector/yolo-v3-tiny/pool2/MaxPool" op="MaxPool">
		<inputs>
			<input node="detector/yolo-v3-tiny/Conv/LeakyRelu" />
		</inputs>
		<attributes>
			<attr name="strides"  type="List" int-size="4" int-vals="1,2,2,1" />
			<attr name="T"  type="Type" value="Float" />
			<attr name="data_format"  type="String" value="NHWC" />
			<attr name="padding"  type="String" value="VALID" />
			<attr name="ksize"  type="List" int-size="4" int-vals="1,2,2,1" />
		</attributes>
	</nodedef>
	<nodedef index="19" name="detector/yolo-v3-tiny/Conv_1/weights" op="Const">
		<inputs />
		<attributes>
			<attr name="dtype"  type="Type" value="Float" />
			<attr name="value"  type="Tensor" type="Float"  dims="[3,3,16,32]"  bytes="18432" />
		</attributes>
	</nodedef>
	<nodedef index="20" name="detector/yolo-v3-tiny/Conv_1/weights/read" op="Identity">
		<inputs>
			<input node="detector/yolo-v3-tiny/Conv_1/weights" />
		</inputs>
		<attributes>
			<attr name="T"  type="Type" value="Float" />
			<attr name="_class"  type="List" string-size="1" strings="loc:@detector/yolo-v3-tiny/Conv_1/weights" />
		</attributes>
	</nodedef>
	<nodedef index="21" name="detector/yolo-v3-tiny/Conv_1/Conv2D" op="Conv2D">
		<inputs>
			<input node="detector/yolo-v3-tiny/pool2/MaxPool" />
			<input node="detector/yolo-v3-tiny/Conv_1/weights/read" />
		</inputs>
		<attributes>
			<attr name="T"  type="Type" value="Float" />
			<attr name="strides"  type="List" int-size="4" int-vals="1,1,1,1" />
			<attr name="padding"  type="String" value="SAME" />
			<attr name="dilations"  type="List" int-size="4" int-vals="1,1,1,1" />
			<attr name="data_format"  type="String" value="NHWC" />
			<attr name="use_cudnn_on_gpu"  type="Bool" value="True" />
		</attributes>
	</nodedef>
	<nodedef index="22" name="detector/yolo-v3-tiny/Conv_1/BatchNorm/gamma" op="Const">
		<inputs />
		<attributes>
			<attr name="dtype"  type="Type" value="Float" />
			<attr name="value"  type="Tensor" type="Float"  dims="[32]"  bytes="128" />
		</attributes>
	</nodedef>
	<nodedef index="23" name="detector/yolo-v3-tiny/Conv_1/BatchNorm/gamma/read" op="Identity">
		<inputs>
			<input node="detector/yolo-v3-tiny/Conv_1/BatchNorm/gamma" />
		</inputs>
		<attributes>
			<attr name="T"  type="Type" value="Float" />
			<attr name="_class"  type="List" string-size="1" strings="loc:@detector/yolo-v3-tiny/Conv_1/BatchNorm/gamma" />
		</attributes>
	</nodedef>
	<nodedef index="24" name="detector/yolo-v3-tiny/Conv_1/BatchNorm/beta" op="Const">
		<inputs />
		<attributes>
			<attr name="dtype"  type="Type" value="Float" />
			<attr name="value"  type="Tensor" type="Float"  dims="[32]"  bytes="128" />
		</attributes>
	</nodedef>
	<nodedef index="25" name="detector/yolo-v3-tiny/Conv_1/BatchNorm/beta/read" op="Identity">
		<inputs>
			<input node="detector/yolo-v3-tiny/Conv_1/BatchNorm/beta" />
		</inputs>
		<attributes>
			<attr name="T"  type="Type" value="Float" />
			<attr name="_class"  type="List" string-size="1" strings="loc:@detector/yolo-v3-tiny/Conv_1/BatchNorm/beta" />
		</attributes>
	</nodedef>
	<nodedef index="26" name="detector/yolo-v3-tiny/Conv_1/BatchNorm/moving_mean" op="Const">
		<inputs />
		<attributes>
			<attr name="dtype"  type="Type" value="Float" />
			<attr name="value"  type="Tensor" type="Float"  dims="[32]"  bytes="128" />
		</attributes>
	</nodedef>
	<nodedef index="27" name="detector/yolo-v3-tiny/Conv_1/BatchNorm/moving_mean/read" op="Identity">
		<inputs>
			<input node="detector/yolo-v3-tiny/Conv_1/BatchNorm/moving_mean" />
		</inputs>
		<attributes>
			<attr name="T"  type="Type" value="Float" />
			<attr name="_class"  type="List" string-size="1" strings="loc:@detector/yolo-v3-tiny/Conv_1/BatchNorm/moving_mean" />
		</attributes>
	</nodedef>
	<nodedef index="28" name="detector/yolo-v3-tiny/Conv_1/BatchNorm/moving_variance" op="Const">
		<inputs />
		<attributes>
			<attr name="dtype"  type="Type" value="Float" />
			<attr name="value"  type="Tensor" type="Float"  dims="[32]"  bytes="128" />
		</attributes>
	</nodedef>
	<nodedef index="29" name="detector/yolo-v3-tiny/Conv_1/BatchNorm/moving_variance/read" op="Identity">
		<inputs>
			<input node="detector/yolo-v3-tiny/Conv_1/BatchNorm/moving_variance" />
		</inputs>
		<attributes>
			<attr name="T"  type="Type" value="Float" />
			<attr name="_class"  type="List" string-size="1" strings="loc:@detector/yolo-v3-tiny/Conv_1/BatchNorm/moving_variance" />
		</attributes>
	</nodedef>
	<nodedef index="30" name="detector/yolo-v3-tiny/Conv_1/BatchNorm/FusedBatchNorm" op="FusedBatchNorm">
		<inputs>
			<input node="detector/yolo-v3-tiny/Conv_1/Conv2D" />
			<input node="detector/yolo-v3-tiny/Conv_1/BatchNorm/gamma/read" />
			<input node="detector/yolo-v3-tiny/Conv_1/BatchNorm/beta/read" />
			<input node="detector/yolo-v3-tiny/Conv_1/BatchNorm/moving_mean/read" />
			<input node="detector/yolo-v3-tiny/Conv_1/BatchNorm/moving_variance/read" />
		</inputs>
		<attributes>
			<attr name="is_training"  type="Bool" value="False" />
			<attr name="T"  type="Type" value="Float" />
			<attr name="data_format"  type="String" value="NHWC" />
			<attr name="epsilon"  type="Float" value="1.001e-05" />
		</attributes>
	</nodedef>
	<nodedef index="31" name="detector/yolo-v3-tiny/Conv_1/LeakyRelu/alpha" op="Const">
		<inputs />
		<attributes>
			<attr name="value"  type="Tensor" type="Float"  dims="[]"  size = "0" />
			<attr name="dtype"  type="Type" value="Float" />
		</attributes>
	</nodedef>
	<nodedef index="32" name="detector/yolo-v3-tiny/Conv_1/LeakyRelu/mul" op="Mul">
		<inputs>
			<input node="detector/yolo-v3-tiny/Conv_1/LeakyRelu/alpha" />
			<input node="detector/yolo-v3-tiny/Conv_1/BatchNorm/FusedBatchNorm" />
		</inputs>
		<attributes>
			<attr name="T"  type="Type" value="Float" />
		</attributes>
	</nodedef>
	<nodedef index="33" name="detector/yolo-v3-tiny/Conv_1/LeakyRelu" op="Maximum">
		<inputs>
			<input node="detector/yolo-v3-tiny/Conv_1/LeakyRelu/mul" />
			<input node="detector/yolo-v3-tiny/Conv_1/BatchNorm/FusedBatchNorm" />
		</inputs>
		<attributes>
			<attr name="T"  type="Type" value="Float" />
		</attributes>
	</nodedef>
	<nodedef index="34" name="detector/yolo-v3-tiny/pool2_1/MaxPool" op="MaxPool">
		<inputs>
			<input node="detector/yolo-v3-tiny/Conv_1/LeakyRelu" />
		</inputs>
		<attributes>
			<attr name="strides"  type="List" int-size="4" int-vals="1,2,2,1" />
			<attr name="T"  type="Type" value="Float" />
			<attr name="data_format"  type="String" value="NHWC" />
			<attr name="padding"  type="String" value="VALID" />
			<attr name="ksize"  type="List" int-size="4" int-vals="1,2,2,1" />
		</attributes>
	</nodedef>
	<nodedef index="35" name="detector/yolo-v3-tiny/Conv_2/weights" op="Const">
		<inputs />
		<attributes>
			<attr name="dtype"  type="Type" value="Float" />
			<attr name="value"  type="Tensor" type="Float"  dims="[3,3,32,64]"  bytes="73728" />
		</attributes>
	</nodedef>
	<nodedef index="36" name="detector/yolo-v3-tiny/Conv_2/weights/read" op="Identity">
		<inputs>
			<input node="detector/yolo-v3-tiny/Conv_2/weights" />
		</inputs>
		<attributes>
			<attr name="T"  type="Type" value="Float" />
			<attr name="_class"  type="List" string-size="1" strings="loc:@detector/yolo-v3-tiny/Conv_2/weights" />
		</attributes>
	</nodedef>
	<nodedef index="37" name="detector/yolo-v3-tiny/Conv_2/Conv2D" op="Conv2D">
		<inputs>
			<input node="detector/yolo-v3-tiny/pool2_1/MaxPool" />
			<input node="detector/yolo-v3-tiny/Conv_2/weights/read" />
		</inputs>
		<attributes>
			<attr name="T"  type="Type" value="Float" />
			<attr name="strides"  type="List" int-size="4" int-vals="1,1,1,1" />
			<attr name="padding"  type="String" value="SAME" />
			<attr name="dilations"  type="List" int-size="4" int-vals="1,1,1,1" />
			<attr name="data_format"  type="String" value="NHWC" />
			<attr name="use_cudnn_on_gpu"  type="Bool" value="True" />
		</attributes>
	</nodedef>
	<nodedef index="38" name="detector/yolo-v3-tiny/Conv_2/BatchNorm/gamma" op="Const">
		<inputs />
		<attributes>
			<attr name="dtype"  type="Type" value="Float" />
			<attr name="value"  type="Tensor" type="Float"  dims="[64]"  bytes="256" />
		</attributes>
	</nodedef>
	<nodedef index="39" name="detector/yolo-v3-tiny/Conv_2/BatchNorm/gamma/read" op="Identity">
		<inputs>
			<input node="detector/yolo-v3-tiny/Conv_2/BatchNorm/gamma" />
		</inputs>
		<attributes>
			<attr name="T"  type="Type" value="Float" />
			<attr name="_class"  type="List" string-size="1" strings="loc:@detector/yolo-v3-tiny/Conv_2/BatchNorm/gamma" />
		</attributes>
	</nodedef>
	<nodedef index="40" name="detector/yolo-v3-tiny/Conv_2/BatchNorm/beta" op="Const">
		<inputs />
		<attributes>
			<attr name="dtype"  type="Type" value="Float" />
			<attr name="value"  type="Tensor" type="Float"  dims="[64]"  bytes="256" />
		</attributes>
	</nodedef>
	<nodedef index="41" name="detector/yolo-v3-tiny/Conv_2/BatchNorm/beta/read" op="Identity">
		<inputs>
			<input node="detector/yolo-v3-tiny/Conv_2/BatchNorm/beta" />
		</inputs>
		<attributes>
			<attr name="T"  type="Type" value="Float" />
			<attr name="_class"  type="List" string-size="1" strings="loc:@detector/yolo-v3-tiny/Conv_2/BatchNorm/beta" />
		</attributes>
	</nodedef>
	<nodedef index="42" name="detector/yolo-v3-tiny/Conv_2/BatchNorm/moving_mean" op="Const">
		<inputs />
		<attributes>
			<attr name="dtype"  type="Type" value="Float" />
			<attr name="value"  type="Tensor" type="Float"  dims="[64]"  bytes="256" />
		</attributes>
	</nodedef>
	<nodedef index="43" name="detector/yolo-v3-tiny/Conv_2/BatchNorm/moving_mean/read" op="Identity">
		<inputs>
			<input node="detector/yolo-v3-tiny/Conv_2/BatchNorm/moving_mean" />
		</inputs>
		<attributes>
			<attr name="T"  type="Type" value="Float" />
			<attr name="_class"  type="List" string-size="1" strings="loc:@detector/yolo-v3-tiny/Conv_2/BatchNorm/moving_mean" />
		</attributes>
	</nodedef>
	<nodedef index="44" name="detector/yolo-v3-tiny/Conv_2/BatchNorm/moving_variance" op="Const">
		<inputs />
		<attributes>
			<attr name="dtype"  type="Type" value="Float" />
			<attr name="value"  type="Tensor" type="Float"  dims="[64]"  bytes="256" />
		</attributes>
	</nodedef>
	<nodedef index="45" name="detector/yolo-v3-tiny/Conv_2/BatchNorm/moving_variance/read" op="Identity">
		<inputs>
			<input node="detector/yolo-v3-tiny/Conv_2/BatchNorm/moving_variance" />
		</inputs>
		<attributes>
			<attr name="T"  type="Type" value="Float" />
			<attr name="_class"  type="List" string-size="1" strings="loc:@detector/yolo-v3-tiny/Conv_2/BatchNorm/moving_variance" />
		</attributes>
	</nodedef>
	<nodedef index="46" name="detector/yolo-v3-tiny/Conv_2/BatchNorm/FusedBatchNorm" op="FusedBatchNorm">
		<inputs>
			<input node="detector/yolo-v3-tiny/Conv_2/Conv2D" />
			<input node="detector/yolo-v3-tiny/Conv_2/BatchNorm/gamma/read" />
			<input node="detector/yolo-v3-tiny/Conv_2/BatchNorm/beta/read" />
			<input node="detector/yolo-v3-tiny/Conv_2/BatchNorm/moving_mean/read" />
			<input node="detector/yolo-v3-tiny/Conv_2/BatchNorm/moving_variance/read" />
		</inputs>
		<attributes>
			<attr name="is_training"  type="Bool" value="False" />
			<attr name="T"  type="Type" value="Float" />
			<attr name="data_format"  type="String" value="NHWC" />
			<attr name="epsilon"  type="Float" value="1.001e-05" />
		</attributes>
	</nodedef>
	<nodedef index="47" name="detector/yolo-v3-tiny/Conv_2/LeakyRelu/alpha" op="Const">
		<inputs />
		<attributes>
			<attr name="value"  type="Tensor" type="Float"  dims="[]"  size = "0" />
			<attr name="dtype"  type="Type" value="Float" />
		</attributes>
	</nodedef>
	<nodedef index="48" name="detector/yolo-v3-tiny/Conv_2/LeakyRelu/mul" op="Mul">
		<inputs>
			<input node="detector/yolo-v3-tiny/Conv_2/LeakyRelu/alpha" />
			<input node="detector/yolo-v3-tiny/Conv_2/BatchNorm/FusedBatchNorm" />
		</inputs>
		<attributes>
			<attr name="T"  type="Type" value="Float" />
		</attributes>
	</nodedef>
	<nodedef index="49" name="detector/yolo-v3-tiny/Conv_2/LeakyRelu" op=
<think>嗯,用户问的是“yolov3.cfg和yolov3.weights必须都安装吗”。首先,我需要确认用户对YOLO模型的理解程度。可能用户在使用OpenCV加载YOLOv3时遇到了问题,之前的对话已经涉及到了文件路径的问题,现在他们可能对这两个文件的作用不太清楚。 我应该先解释这两个文件的用途。.cfg文件是配置文件,定义了模型的结构,比如层数、卷积核大小等等。而.weights文件则是训练好的权重,包含了模型学习到的参数。这两个文件确实是必须的,因为模型的结构和参数缺一不可。 接下来,用户可能想知道是否必须同时安装这两个文件。需要明确回答是的,必须同时存在,否则无法正确加载模型。比如,如果只有.cfg没有.weights,OpenCV知道模型结构但不知道参数,反之亦然,都不行。 然后,可能需要进一步说明这两个文件的关系,比如在训练时,.cfg用来构建网络,训练完成后生成.weights。用户可能误以为安装YOLO只需要其中一个,或者不知道从哪里获取这两个文件。 还要考虑用户可能遇到的问题,比如路径错误、文件损坏或者版本不匹配。之前用户已经遇到了路径问题,所以这里需要再次强调路径正确的重要性,或者建议用户检查文件完整性。 另外,用户可能对如何获取这两个文件有疑问,所以给出官方下载链接或者方法会很有帮助。比如从Darknet官网下载.weights,从GitHub获取.cfg文件。 最后,可能需要提醒用户注意版本兼容性,确保.cfg和.weights是同一版本的,避免因为版本不一致导致加载失败。同时,检查OpenCV的版本是否支持YOLOv3,是否需要升级。 总结一下,回答的结构应该是先解释两个文件的作用,强调必须同时存在,然后说明它们的关系,接着提供获取方式,最后给出常见问题的解决建议。这样用户能全面了解为什么需要这两个文件,以及如何处理相关问题。</think>以下是关于YOLOv3模型文件的详细说明: --- ### **核心结论** **必须同时拥有`yolov3.cfg`和`yolov3.weights`两个文件**,缺一不可。它们分别承担不同的关键功能,共同构成完整的YOLOv3模型。 --- ### **文件作用解析** | 文件类型 | 功能说明 | 重要性级别 | |-------------------|--------------------------------------------------------------------------|------------| | **.cfg文件** | 定义神经网络结构(层数、卷积核参数、激活函数等) | ★★★★★ | | **.weights文件** | 存储训练好的模型权重(模型从数据中学习到的参数) | ★★★★★ | --- ### **技术依赖关系** 1. **协同工作机制** - **.cfg** 文件告诉程序 *如何构建网络*(框架设计) - **.weights** 文件告诉程序 *网络的具体参数值*(知识核心) - **类比**:`.cfg` 是建筑设计图,`.weights` 是建筑所需的钢筋水泥 2. **独立验证测试** - 仅有`.cfg`时: ```python # 尝试加载会直接报错 net = cv2.dnn.readNetFromDarknet("yolov3.cfg") # 缺少weights文件 ``` 输出: ``` error: (-5:Bad argument) Cannot parse weights blob in function &#39;cv::dnn::dnn4_v20220524::readNetFromDarknet&#39; ``` - 仅有`.weights`时: ```python # 无法识别模型结构 net = cv2.dnn.readNetFromDarknet(weights="yolov3.weights") # 缺少cfg文件 ``` 输出: ``` error: (-212:Parsing error) Failed to parse NetParameter file in function &#39;cv::dnn::dnn4_v20220524::readNetFromDarknet&#39; ``` --- ### **文件获取方式** #### 官方推荐渠道 1. **配置文件.cfg)** ```bash # 从Darknet官方仓库下载(注意处理GitHub的raw文件) wget "https://github.com/pjreddie/darknet/blob/master/cfg/yolov3.cfg?raw=true" -O yolov3.cfg ``` 2. **权重文件.weights)** ```bash # 从YOLO作者官网下载(约236MB) wget https://pjreddie.com/media/files/yolov3.weights ``` --- ### **常见问题解决方案** 1. **文件不匹配错误** - 确保`.cfg`和`.weights`是**同一版本**(例如同时使用YOLOv3原版,而非YOLOv3-tiny- 验证文件哈希值(示例): ```bash # 校验weights文件 md5sum yolov3.weights # 正确输出:c84e5b99d0e52cd466ae710cadf6d84c ``` 2. **路径优化建议** - 使用绝对路径并添加断言验证: ```python import os cfg_path = r"/path/to/yolov3.cfg" weights_path = r"/path/to/yolov3.weights" assert os.path.exists(cfg_path), "配置文件路径错误!" assert os.path.exists(weights_path), "权重文件路径错误!" ``` 3. **版本兼容性验证** - OpenCV 4.5.5+ 对YOLOv3支持最稳定 - 升级命令: ```bash pip install opencv-python --upgrade ``` --- ### **扩展知识** - **训练自定义模型**:若需使用自己的数据集,需基于`.cfg`修改网络结构,重新训练生成新`.weights` - **模型转换工具**:可通过工具将Darknet格式转为TensorFlow/PyTorch格式(如`darkflow`或`onnx`转换器) 如果仍有问题,可以提供文件路径和OpenCV版本信息,我会进一步分析具体原因。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值