模型转换[yolov3模型在keras与darknet之间转换]
首先借助qqwweee/keras-yolo3中的convert.py和tensorrt例子yolov3_onnx,并重新编写了代码,实现将darknet格式的yolov3的yolov3.cfg和yolov3.weights转换成keras(tensorflow)的h5格式
1 将darknet格式的yolov3.cfg和yolov3.weights转换成kears(tf)的h5格式
# -*- coding: utf-8 -*-
import os
import io
import argparse
import configparser
import numpy as np
from keras import backend as K
from keras.layers import (Conv2D, Input, ZeroPadding2D, Add,
UpSampling2D, MaxPooling2D, Concatenate)
from keras.layers.advanced_activations import LeakyReLU
from keras.layers.normalization import BatchNormalization
from keras.models import Model
from keras.regularizers import l2
from keras.utils.vis_utils import plot_model as plot
def parser():
parser = argparse.ArgumentParser(description="Darknet\'s yolov3.cfg and yolov3.weights \
converted into Keras\'s yolov3.h5!")
parser.add_argument('-cfg_path', help='yolov3.cfg')
parser.add_argument('-weights_path', help='yolov3.weights')
parser.add_argument('-output_path', help='yolov3.h5')
parser.add_argument('-weights_only', action='store_true',help='only save weights in yolov3.h5')
return parser.parse_args()
class WeightLoader(object):
def __init__(self,weight_path):
self.fhandle = open(weight_path,'rb')
self.read_bytes = 0
def parser_buffer(self,shape,dtype='int32',buffer_size=None):
self.read_bytes += buffer_size
return np.ndarray(shape=shape,
dtype=dtype,
buffer=self.fhandle.read(buffer_size) )
def head(self):
major, minor, revision = self.parser_buffer(
shape=(3,),
dtype='int32',
buffer_size=12)
if major*10+minor >= 2 and major < 1000 and minor < 1000:
seen = self.parser_buffer(
shape=(1,),
dtype='int64',
buffer_size=8)
else:
seen = self.parser_buffer(
shape=(1,),
dtype='int32',
buffer_size=4)
return major, minor, revision, seen
def close(self):
self.fhandle.close()
class DarkNetParser(object):
def __init__(self, cfg_path, weights_path):
self.block_gen = self._get_block(cfg_path)
self.weight_loader = WeightLoader(weights_path)
major, minor, revision, seen = self.weight_loader.head()
print('weights header: ',major, minor, revision, seen)
self.input_layer = Input(shape=(None, None, 3))
self.out_index = []
self.prev_layer = self.input_layer
self.all_layers = []
self.count = [0,0]
def _get_block(self,cfg_path):
block = {}
with open(cfg_path,'r', encoding='utf-8') as fr:
for line in fr:
line = line.strip()
if '[' in line and ']' in line:
if block:
yield block
block = {}
block['type'] = line.strip(' []')
elif not line or '#' in line:
continue
else:
key,val = line.strip().replace(' ','').split('=')
key,val = key.strip(), val.strip()
block[key] = val
yield block
def conv(self, block):
'''在读取darknet的yolov3.weights文件时,顺序是
1 - bias;
2 - 如果有bn,则接着读取三个scale,mean,var
3 - 读取权重
'''
# Darknet serializes convolutional weights as:
# [bias/beta, [gamma, mean, variance], conv_weights]
self.count[0] += 1
# read conv block
filters = int(block['filters'])
size = int(block['size'])
stride = int(block['stride'])
pad = int(block['pad'])
activation = block['activation']
padding = 'same' if pad == 1 and stride == 1 else 'valid'
batch_normalize = 'batch_normalize' in block
prev_layer_shape = K.int_shape(self.prev_layer)
weights_shape = (size, size, prev_layer_shape[-1], filters)
darknet_w_shape = (filters, weights_shape[2], size, size)
weights_size = np.product(weights_shape)
print('+',self.count[0],'conv2d',
'bn' if batch_normalize else ' ',
activation,
weights_shape)
# 读取滤波器个偏置
conv_bias = self.weight_loader.parser_buffer(
shape=(filters,),
dtype='float32',
buffer_size=filters*4)
# 如果有bn,则接着读取滤波器个scale,mean,var
if batch_normalize:
bn_weight_list = self.bn(filters, conv_bias)
# 读取权重
conv_weights = self.weight_loader.parser_buffer(
shape=darknet_w_shape,
dtype='float32',
buffer_size=weights_size*4)
# DarkNet conv_weights are serialized Caffe-style:
# (out_dim, in_dim, height, width)
# We would like to set these to Tensorflow order:
# (height, width, in_dim, out_dim)
conv_weights = np.transpose(conv_weights, [2, 3, 1, 0])
conv_weights = [conv_weights] if batch_normalize else \
[conv_weights, conv_bias]
act_fn = None
if activation == 'leaky':
pass
elif activation != 'linear':
raise
if stride > 1:
self.prev_layer = ZeroPadding2D(((1,0),(1,0)))(self.prev_layer)
conv_layer = (Conv2D(
filters, (size, size),
strides=(stride, stride),
kernel_regularizer=l2(self.weight_decay),
use_bias=not batch_normalize,
weights=conv_weights,
activation=act_fn,
padding=padding))(self.prev_layer)
if batch_normalize:
conv_layer = BatchNormalization(weights=bn_weight_list)(conv_layer)
self.prev_layer = conv_layer
if activation == 'linear':
self.all_layers.append(self.prev_layer)
elif activation == 'leaky':
act_layer = LeakyReLU(alpha=0.1)(self.prev_layer)
self.prev_layer = act_layer
self.all_layers.append(act_layer)
def bn(self,filters,conv_bias):
'''bn有4个参数,分别是bias,scale,mean,var,
其中bias已经读取完毕,这里读取剩下三个,scale,mean,var '''
bn_weights = self.weight_loader.parser_buffer(
shape=(3,filters),
dtype='float32',
buffer_size=(filters*3)*4)
# scale, bias, mean,var
bn_weight_list = [bn_weights[0],
conv_bias,
bn_weights[1],
bn_weights[2] ]
return bn_weight_list
def maxpool(self,block):
size = int(block['size'])
stride = int(block['stride'])
maxpool_layer = MaxPooling2D(pool_size=(size,size),
strides=(stride,stride),
padding='same')(self.prev_layer)
self.all_layers.append(maxpool_layer)
self.prev_layer = maxpool_layer
def shortcut(self,block):
index = int(block['from'])
activation = block['activation']
assert activation == 'linear', 'Only linear activation supported.'
shortcut_layer = Add()([self.all_layers[index],self.prev_layer])
self.all_layers.append(shortcut_layer)
self.prev_layer = shortcut_layer
def route(self,block):
layers_ids = block['layers']
ids = [int(i) for i in layers_ids.split(',')]
layers = [self.all_layers[i] for i in ids]
if len(layers) > 1:
print('Concatenating route layers:', layers)
concatenate_layer = Concatenate()(layers)
self.all_layers.append(concatenate_layer)
self.prev_layer = concatenate_layer
else:
skip_layer = layers[0]
self.all_layers.append(skip_layer)
self.prev_layer = skip_layer
def upsample(self,block):
stride = int(block['stride'])
assert stride == 2, 'Only stride=2 supported.'
upsample_layer = UpSampling2D(stride)(self.prev_layer)
self.all_layers.append(upsample_layer)
self.prev_layer = self.all_layers[-1]
def yolo(self,block):
self.out_index.append(len(self.all_layers)-1)
self.all_layers.append(None)
self.prev_layer = self.all_layers[-1]
def net(self, block):
self.weight_decay = block['decay']
def create_and_save(self,weights_only,output_path):
if len(self.out_index) == 0:
self.out_index.append( len(self.all_layers)-1 )
output_layers = [self.all_layers[i] for i in self.out_index]
model = Model(inputs=self.input_layer,
outputs=output_layers)
print(model.summary())
if weights_only:
model.save_weights(output_path)
print('Saved Keras weights to {}'.format(output_path))
else:
model.save(output_path)
print('Saved Keras model to {}'.format(output_path))
def close(self):
self.weight_loader.close()
def main():
args = parser()
print('loading weights...')
cfg_parser = DarkNetParser(args.cfg_path,args.weights_path)
print('creating keras model...')
layers_fun = {'convolutional':cfg_parser.conv,
'net':cfg_parser.net,
'yolo':cfg_parser.yolo,
'route':cfg_parser.route,
'upsample':cfg_parser.upsample,
'maxpool':cfg_parser.maxpool,
'shortcut':cfg_parser.shortcut
}
print('Parsing Darknet config.')
for ind,block in enumerate(cfg_parser.block_gen):
type = block['type']
layers_fun[type](block)
cfg_parser.create_and_save(args.weights_only, args.output_path)
cfg_parser.close()
if __name__ == '__main__':
main()
运行结果
python yolov3_darknet_to_keras.py -cfg_path text.cfg -weights_path yolov3.weights -output_path yolov3c_d2k.h5


2 将kears(tf)的h5格式转换成darknet格式的yolov3.weights
其中上面的与下面的名称转换
bias -> beta
scale -> gamma
mean -> moving_mean
var -> moving_variance
基于此写的脚本为:
# -*- coding: utf-8 -*-
''' yolov3_keras_to_darknet.py'''
import argparse
import numpy
import numpy as np
import keras
from keras.models import load_model
from keras import backend as K
def parser():
parser = argparse.ArgumentParser(description="Darknet\'s yolov3.cfg and yolov3.weights \
converted into Keras\'s yolov3.h5!")
parser.add_argument('-cfg_path', help='yolov3.cfg')
parser.add_argument('-h5_path', help='yolov3.h5')
parser.add_argument('-output_path', help='yolov3.weights')
return parser.parse_args()
class WeightSaver(object):
def __init__(self,h5_path,output_path):
self.model = load_model(h5_path)
# 如果要读取keras调用save_weights的h5文件,可以先读取一次save的h5,
# 然后取消下面的注释,读取save_weights的h5
# self.model.load_weights('text.h5')
self.layers = {weight.name:weight for weight in self.model.weights}
self.sess = K.get_session()
self.fhandle = open(output_path,'wb')
self._write_head()
def _write_head(self):
numpy_data = numpy.ndarray(shape=(3,),
dtype='int32',
buffer=np.array([0,2,0],dtype='int32') )
self.save(numpy_data)
numpy_data = numpy.ndarray(shape=(1,),
dtype='int64',
buffer=np.array([320000],dtype='int64'))
self.save(numpy_data)
def get_bn_layername(self,num):
layer_name = 'batch_normalization_{num}'.format(num=num)
bias = self.layers['{0}/beta:0'.format(layer_name)]
scale = self.layers['{0}/gamma:0'.format(layer_name)]
mean = self.layers['{0}/moving_mean:0'.format(layer_name)]
var = self.layers['{0}/moving_variance:0'.format(layer_name)]
bias_np = self.get_numpy(bias)
scale_np = self.get_numpy(scale)
mean_np = self.get_numpy(mean)
var_np = self.get_numpy(var)
return bias_np,scale_np,mean_np,var_np
def get_convbias_layername(self,num):
layer_name = 'conv2d_{num}'.format(num=num)
bias = self.layers['{0}/bias:0'.format(layer_name)]
bias_np = self.get_numpy(bias)
return bias_np
def get_conv_layername(self,num):
layer_name = 'conv2d_{num}'.format(num=num)
conv = self.layers['{0}/kernel:0'.format(layer_name)]
conv_np = self.get_numpy(conv)
return conv_np
def get_numpy(self,layer_name):
numpy_data = self.sess.run(layer_name)
return numpy_data
def save(self,numpy_data):
bytes_data = numpy_data.tobytes()
self.fhandle.write(bytes_data)
self.fhandle.flush()
def close(self):
self.fhandle.close()
class KerasParser(object):
def __init__(self, cfg_path, h5_path, output_path):
self.block_gen = self._get_block(cfg_path)
self.weights_saver = WeightSaver(h5_path, output_path)
self.count_conv = 0
self.count_bn = 0
def _get_block(self,cfg_path):
block = {}
with open(cfg_path,'r', encoding='utf-8') as fr:
for line in fr:
line = line.strip()
if '[' in line and ']' in line:
if block:
yield block
block = {}
block['type'] = line.strip(' []')
elif not line or '#' in line:
continue
else:
key,val = line.strip().replace(' ','').split('=')
key,val = key.strip(), val.strip()
block[key] = val
yield block
def close(self):
self.weights_saver.close()
def conv(self, block):
self.count_conv += 1
batch_normalize = 'batch_normalize' in block
print('handing.. ',self.count_conv)
# 如果bn存在,则先处理bn,顺序为bias,scale,mean,var
if batch_normalize:
bias,scale,mean,var = self.bn()
self.weights_saver.save(bias)
scale = scale.reshape(1,-1)
mean = mean.reshape(1,-1)
var = var.reshape(1,-1)
remain = np.concatenate([scale,mean,var],axis=0)
self.weights_saver.save(remain)
# 否则,先处理biase
else:
conv_bias = self.weights_saver.get_convbias_layername(self.count_conv)
self.weights_saver.save(conv_bias)
# 接着处理weights
conv_weights = self.weights_saver.get_conv_layername(self.count_conv)
# 需要将(height, width, in_dim, out_dim)转换成(out_dim, in_dim, height, width)
conv_weights = np.transpose(conv_weights,[3,2,0,1])
self.weights_saver.save(conv_weights)
def bn(self):
self.count_bn += 1
bias,scale,mean,var = self.weights_saver.get_bn_layername(self.count_bn)
return bias,scale,mean,var
def main():
args = parser()
keras_loader = KerasParser(args.cfg_path, args.h5_path, args.output_path)
for block in keras_loader.block_gen:
if 'convolutional' in block['type']:
keras_loader.conv(block)
keras_loader.close()
if __name__ == "__main__":
main()
通过读取keras保存的h5文件,并读取其权重,其如下所示,
[<tf.Variable 'conv2d_1/kernel:0' shape=(3, 3, 3, 32) dtype=float32_ref>,
<tf.Variable 'batch_normalization_1/gamma:0' shape=(32,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_1/beta:0' shape=(32,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_1/moving_mean:0' shape=(32,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_1/moving_variance:0' shape=(32,) dtype=float32_ref>,
<tf.Variable 'conv2d_2/kernel:0' shape=(3, 3, 32, 64) dtype=float32_ref>,
<tf.Variable 'batch_normalization_2/gamma:0' shape=(64,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_2/beta:0' shape=(64,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_2/moving_mean:0' shape=(64,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_2/moving_variance:0' shape=(64,) dtype=float32_ref>,
<tf.Variable 'conv2d_3/kernel:0' shape=(1, 1, 64, 32) dtype=float32_ref>,
<tf.Variable 'batch_normalization_3/gamma:0' shape=(32,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_3/beta:0' shape=(32,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_3/moving_mean:0' shape=(32,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_3/moving_variance:0' shape=(32,) dtype=float32_ref>,
<tf.Variable 'conv2d_4/kernel:0' shape=(3, 3, 32, 64) dtype=float32_ref>,
<tf.Variable 'batch_normalization_4/gamma:0' shape=(64,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_4/beta:0' shape=(64,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_4/moving_mean:0' shape=(64,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_4/moving_variance:0' shape=(64,) dtype=float32_ref>,
<tf.Variable 'conv2d_5/kernel:0' shape=(3, 3, 64, 128) dtype=float32_ref>,
<tf.Variable 'batch_normalization_5/gamma:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_5/beta:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_5/moving_mean:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_5/moving_variance:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'conv2d_6/kernel:0' shape=(1, 1, 128, 64) dtype=float32_ref>,
<tf.Variable 'batch_normalization_6/gamma:0' shape=(64,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_6/beta:0' shape=(64,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_6/moving_mean:0' shape=(64,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_6/moving_variance:0' shape=(64,) dtype=float32_ref>,
<tf.Variable 'conv2d_7/kernel:0' shape=(3, 3, 64, 128) dtype=float32_ref>,
<tf.Variable 'batch_normalization_7/gamma:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_7/beta:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_7/moving_mean:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_7/moving_variance:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'conv2d_8/kernel:0' shape=(1, 1, 128, 64) dtype=float32_ref>,
<tf.Variable 'batch_normalization_8/gamma:0' shape=(64,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_8/beta:0' shape=(64,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_8/moving_mean:0' shape=(64,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_8/moving_variance:0' shape=(64,) dtype=float32_ref>,
<tf.Variable 'conv2d_9/kernel:0' shape=(3, 3, 64, 128) dtype=float32_ref>,
<tf.Variable 'batch_normalization_9/gamma:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_9/beta:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_9/moving_mean:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_9/moving_variance:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'conv2d_10/kernel:0' shape=(3, 3, 128, 256) dtype=float32_ref>,
<tf.Variable 'batch_normalization_10/gamma:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_10/beta:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_10/moving_mean:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_10/moving_variance:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'conv2d_11/kernel:0' shape=(1, 1, 256, 128) dtype=float32_ref>,
<tf.Variable 'batch_normalization_11/gamma:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_11/beta:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_11/moving_mean:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_11/moving_variance:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'conv2d_12/kernel:0' shape=(3, 3, 128, 256) dtype=float32_ref>,
<tf.Variable 'batch_normalization_12/gamma:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_12/beta:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_12/moving_mean:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_12/moving_variance:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'conv2d_13/kernel:0' shape=(1, 1, 256, 128) dtype=float32_ref>,
<tf.Variable 'batch_normalization_13/gamma:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_13/beta:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_13/moving_mean:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_13/moving_variance:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'conv2d_14/kernel:0' shape=(3, 3, 128, 256) dtype=float32_ref>,
<tf.Variable 'batch_normalization_14/gamma:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_14/beta:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_14/moving_mean:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_14/moving_variance:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'conv2d_15/kernel:0' shape=(1, 1, 256, 128) dtype=float32_ref>,
<tf.Variable 'batch_normalization_15/gamma:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_15/beta:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_15/moving_mean:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_15/moving_variance:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'conv2d_16/kernel:0' shape=(3, 3, 128, 256) dtype=float32_ref>,
<tf.Variable 'batch_normalization_16/gamma:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_16/beta:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_16/moving_mean:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_16/moving_variance:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'conv2d_17/kernel:0' shape=(1, 1, 256, 128) dtype=float32_ref>,
<tf.Variable 'batch_normalization_17/gamma:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_17/beta:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_17/moving_mean:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_17/moving_variance:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'conv2d_18/kernel:0' shape=(3, 3, 128, 256) dtype=float32_ref>,
<tf.Variable 'batch_normalization_18/gamma:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_18/beta:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_18/moving_mean:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_18/moving_variance:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'conv2d_19/kernel:0' shape=(1, 1, 256, 128) dtype=float32_ref>,
<tf.Variable 'batch_normalization_19/gamma:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_19/beta:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_19/moving_mean:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_19/moving_variance:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'conv2d_20/kernel:0' shape=(3, 3, 128, 256) dtype=float32_ref>,
<tf.Variable 'batch_normalization_20/gamma:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_20/beta:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_20/moving_mean:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_20/moving_variance:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'conv2d_21/kernel:0' shape=(1, 1, 256, 128) dtype=float32_ref>,
<tf.Variable 'batch_normalization_21/gamma:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_21/beta:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_21/moving_mean:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_21/moving_variance:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'conv2d_22/kernel:0' shape=(3, 3, 128, 256) dtype=float32_ref>,
<tf.Variable 'batch_normalization_22/gamma:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_22/beta:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_22/moving_mean:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_22/moving_variance:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'conv2d_23/kernel:0' shape=(1, 1, 256, 128) dtype=float32_ref>,
<tf.Variable 'batch_normalization_23/gamma:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_23/beta:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_23/moving_mean:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_23/moving_variance:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'conv2d_24/kernel:0' shape=(3, 3, 128, 256) dtype=float32_ref>,
<tf.Variable 'batch_normalization_24/gamma:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_24/beta:0' shape=(256,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_25/kernel:0' shape=(1, 1, 256, 128) dtype=float32_ref>,
<tf.Variable 'batch_normalization_25/gamma:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_25/beta:0' shape=(128,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_26/kernel:0' shape=(3, 3, 128, 256) dtype=float32_ref>,
<tf.Variable 'batch_normalization_26/gamma:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_26/beta:0' shape=(256,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_27/kernel:0' shape=(3, 3, 256, 512) dtype=float32_ref>,
<tf.Variable 'batch_normalization_27/gamma:0' shape=(512,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_27/beta:0' shape=(512,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_28/kernel:0' shape=(1, 1, 512, 256) dtype=float32_ref>,
<tf.Variable 'batch_normalization_28/gamma:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_28/beta:0' shape=(256,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_29/kernel:0' shape=(3, 3, 256, 512) dtype=float32_ref>,
<tf.Variable 'batch_normalization_29/gamma:0' shape=(512,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_29/beta:0' shape=(512,) dtype=float32_ref>
......
<tf.Variable 'conv2d_30/kernel:0' shape=(1, 1, 512, 256) dtype=float32_ref>,
<tf.Variable 'batch_normalization_30/gamma:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_30/beta:0' shape=(256,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_31/kernel:0' shape=(3, 3, 256, 512) dtype=float32_ref>,
<tf.Variable 'batch_normalization_31/gamma:0' shape=(512,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_31/beta:0' shape=(512,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_32/kernel:0' shape=(1, 1, 512, 256) dtype=float32_ref>,
<tf.Variable 'batch_normalization_32/gamma:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_32/beta:0' shape=(256,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_33/kernel:0' shape=(3, 3, 256, 512) dtype=float32_ref>,
<tf.Variable 'batch_normalization_33/gamma:0' shape=(512,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_33/beta:0' shape=(512,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_34/kernel:0' shape=(1, 1, 512, 256) dtype=float32_ref>,
<tf.Variable 'batch_normalization_34/gamma:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_34/beta:0' shape=(256,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_35/kernel:0' shape=(3, 3, 256, 512) dtype=float32_ref>,
<tf.Variable 'batch_normalization_35/gamma:0' shape=(512,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_35/beta:0' shape=(512,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_36/kernel:0' shape=(1, 1, 512, 256) dtype=float32_ref>,
<tf.Variable 'batch_normalization_36/gamma:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_36/beta:0' shape=(256,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_37/kernel:0' shape=(3, 3, 256, 512) dtype=float32_ref>,
<tf.Variable 'batch_normalization_37/gamma:0' shape=(512,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_37/beta:0' shape=(512,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_38/kernel:0' shape=(1, 1, 512, 256) dtype=float32_ref>,
<tf.Variable 'batch_normalization_38/gamma:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_38/beta:0' shape=(256,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_39/kernel:0' shape=(3, 3, 256, 512) dtype=float32_ref>,
<tf.Variable 'batch_normalization_39/gamma:0' shape=(512,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_39/beta:0' shape=(512,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_40/kernel:0' shape=(1, 1, 512, 256) dtype=float32_ref>,
<tf.Variable 'batch_normalization_40/gamma:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_40/beta:0' shape=(256,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_41/kernel:0' shape=(3, 3, 256, 512) dtype=float32_ref>,
<tf.Variable 'batch_normalization_41/gamma:0' shape=(512,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_41/beta:0' shape=(512,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_42/kernel:0' shape=(1, 1, 512, 256) dtype=float32_ref>,
<tf.Variable 'batch_normalization_42/gamma:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_42/beta:0' shape=(256,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_43/kernel:0' shape=(3, 3, 256, 512) dtype=float32_ref>,
<tf.Variable 'batch_normalization_43/gamma:0' shape=(512,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_43/beta:0' shape=(512,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_44/kernel:0' shape=(3, 3, 512, 1024) dtype=float32_ref>,
<tf.Variable 'batch_normalization_44/gamma:0' shape=(1024,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_44/beta:0' shape=(1024,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_45/kernel:0' shape=(1, 1, 1024, 512) dtype=float32_ref>,
<tf.Variable 'batch_normalization_45/gamma:0' shape=(512,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_45/beta:0' shape=(512,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_46/kernel:0' shape=(3, 3, 512, 1024) dtype=float32_ref>,
<tf.Variable 'batch_normalization_46/gamma:0' shape=(1024,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_46/beta:0' shape=(1024,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_47/kernel:0' shape=(1, 1, 1024, 512) dtype=float32_ref>,
<tf.Variable 'batch_normalization_47/gamma:0' shape=(512,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_47/beta:0' shape=(512,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_48/kernel:0' shape=(3, 3, 512, 1024) dtype=float32_ref>,
<tf.Variable 'batch_normalization_48/gamma:0' shape=(1024,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_48/beta:0' shape=(1024,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_49/kernel:0' shape=(1, 1, 1024, 512) dtype=float32_ref>,
<tf.Variable 'batch_normalization_49/gamma:0' shape=(512,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_49/beta:0' shape=(512,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_50/kernel:0' shape=(3, 3, 512, 1024) dtype=float32_ref>,
<tf.Variable 'batch_normalization_50/gamma:0' shape=(1024,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_50/beta:0' shape=(1024,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_51/kernel:0' shape=(1, 1, 1024, 512) dtype=float32_ref>,
<tf.Variable 'batch_normalization_51/gamma:0' shape=(512,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_51/beta:0' shape=(512,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_52/kernel:0' shape=(3, 3, 512, 1024) dtype=float32_ref>,
<tf.Variable 'batch_normalization_52/gamma:0' shape=(1024,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_52/beta:0' shape=(1024,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_53/kernel:0' shape=(1, 1, 1024, 512) dtype=float32_ref>,
<tf.Variable 'batch_normalization_53/gamma:0' shape=(512,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_53/beta:0' shape=(512,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_54/kernel:0' shape=(3, 3, 512, 1024) dtype=float32_ref>,
<tf.Variable 'batch_normalization_54/gamma:0' shape=(1024,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_54/beta:0' shape=(1024,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_55/kernel:0' shape=(1, 1, 1024, 512) dtype=float32_ref>,
<tf.Variable 'batch_normalization_55/gamma:0' shape=(512,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_55/beta:0' shape=(512,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_56/kernel:0' shape=(3, 3, 512, 1024) dtype=float32_ref>,
<tf.Variable 'batch_normalization_56/gamma:0' shape=(1024,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_56/beta:0' shape=(1024,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_57/kernel:0' shape=(1, 1, 1024, 512) dtype=float32_ref>,
<tf.Variable 'batch_normalization_57/gamma:0' shape=(512,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_57/beta:0' shape=(512,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_58/kernel:0' shape=(3, 3, 512, 1024) dtype=float32_ref>,
<tf.Variable 'batch_normalization_58/gamma:0' shape=(1024,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_58/beta:0' shape=(1024,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_59/kernel:0' shape=(1, 1, 1024, 21) dtype=float32_ref>,
<tf.Variable 'conv2d_59/bias:0' shape=(21,) dtype=float32_ref>,
<tf.Variable 'conv2d_60/kernel:0' shape=(1, 1, 512, 256) dtype=float32_ref>,
<tf.Variable 'batch_normalization_59/gamma:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_59/beta:0' shape=(256,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_61/kernel:0' shape=(1, 1, 768, 256) dtype=float32_ref>,
<tf.Variable 'batch_normalization_60/gamma:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_60/beta:0' shape=(256,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_62/kernel:0' shape=(3, 3, 256, 512) dtype=float32_ref>,
<tf.Variable 'batch_normalization_61/gamma:0' shape=(512,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_61/beta:0' shape=(512,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_63/kernel:0' shape=(1, 1, 512, 256) dtype=float32_ref>,
<tf.Variable 'batch_normalization_62/gamma:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_62/beta:0' shape=(256,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_64/kernel:0' shape=(3, 3, 256, 512) dtype=float32_ref>,
<tf.Variable 'batch_normalization_63/gamma:0' shape=(512,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_63/beta:0' shape=(512,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_65/kernel:0' shape=(1, 1, 512, 256) dtype=float32_ref>,
<tf.Variable 'batch_normalization_64/gamma:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_64/beta:0' shape=(256,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_66/kernel:0' shape=(3, 3, 256, 512) dtype=float32_ref>,
<tf.Variable 'batch_normalization_65/gamma:0' shape=(512,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_65/beta:0' shape=(512,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_67/kernel:0' shape=(1, 1, 512, 21) dtype=float32_ref>,
<tf.Variable 'conv2d_67/bias:0' shape=(21,) dtype=float32_ref>,
<tf.Variable 'conv2d_68/kernel:0' shape=(1, 1, 256, 128) dtype=float32_ref>,
<tf.Variable 'batch_normalization_66/gamma:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_66/beta:0' shape=(128,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_69/kernel:0' shape=(1, 1, 384, 128) dtype=float32_ref>,
<tf.Variable 'batch_normalization_67/gamma:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_67/beta:0' shape=(128,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_70/kernel:0' shape=(3, 3, 128, 256) dtype=float32_ref>,
<tf.Variable 'batch_normalization_68/gamma:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_68/beta:0' shape=(256,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_71/kernel:0' shape=(1, 1, 256, 128) dtype=float32_ref>,
<tf.Variable 'batch_normalization_69/gamma:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_69/beta:0' shape=(128,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_72/kernel:0' shape=(3, 3, 128, 256) dtype=float32_ref>,
<tf.Variable 'batch_normalization_70/gamma:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_70/beta:0' shape=(256,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_73/kernel:0' shape=(1, 1, 256, 128) dtype=float32_ref>,
<tf.Variable 'batch_normalization_71/gamma:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_71/beta:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_71/moving_mean:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_71/moving_variance:0' shape=(128,) dtype=float32_ref>,
<tf.Variable 'conv2d_74/kernel:0' shape=(3, 3, 128, 256) dtype=float32_ref>,
<tf.Variable 'batch_normalization_72/gamma:0' shape=(256,) dtype=float32_ref>,
<tf.Variable 'batch_normalization_72/beta:0' shape=(256,) dtype=float32_ref>,
......
<tf.Variable 'conv2d_75/kernel:0' shape=(1, 1, 256, 21) dtype=float32_ref>,
<tf.Variable 'conv2d_75/bias:0' shape=(21,) dtype=float32_ref>,
运行结果
python yolov3_keras_to_darknet.py -cfg_path text.cfg -h5_path yolov3c_d2k.h5 -output_path yolov3c_d2k_k2d.weights

可以看出原始文件yolov3.weights转成yolov3c_d2k.h5,然后再转回来yolov3c_d2k_k2d.weights,而md5值未变,说明逆向转换成功。
3 实际案例
这里我们给出完整的操作过程:
首先,机器环境(个人觉得这里应该无所谓):
1 - python3.5.6;
2 - keras 2.2.4;
3 - tensorflow-gpu 1.12.0.
然后,去github的chineseocr给出的百度网盘下下载:
- text.h5: 通过keras的save_weights方式保存的
- text.weights:darknet生成的文件
- text.cfg: darknet中yolov3的网络结构
如果直接执行
python yolov3_keras_to_darknet.py -cfg_path text.cfg -h5_path text.h5 -output_path test.weights
会报:

是因为当前h5是通过save_weights方式保存的,而非save方式。
所以我们先执行
python yolov3_darknet_to_keras.py -cfg_path text.cfg -weights_path text.weights -output_path test.h5
此时是将darknet的结构通过keras的save方式转换成h5.然后此时执行,就没问题了:
python h5_to_weights.py -cfg_path text.cfg -h5_path test.h5 -output_path test.weights
模型转换[yolov3模型在keras与darknet之间转换]的更多相关文章
- (转)Darknet模型与Tensorflow模型相互转换
目前darknet框架下的模型训练都是在C环境下训练的,难免较为晦涩,如果能将模型转换到Tensorflow环境下完成模型的训练,在将训练好的权重转为Darknet可以识别的权重部署到实际应用中.这样 ...
- darknet-训练自己的yolov3模型
目录 Yolo v3的使用方法 安装darknet 训练Pascal VOC格式的数据 修改cfg文件中的voc.data 修改VOC.names 下载预训练卷积层权重 修改cfg/yolov3-vo ...
- 基于树莓派与YOLOv3模型的人体目标检测小车(一)
项目介绍: 本科毕业选的深度学习的毕设,一开始只是学习了一下YOLOv3模型, 按照作者的指示在官网上下载下来权重,配好环境跑出来Demo,后来想着只是跑模型会不会太单薄,于是想了能不能做出来个比较实 ...
- Keras框架下的保存模型和加载模型
在Keras框架下训练深度学习模型时,一般思路是在训练环境下训练出模型,然后拿训练好的模型(即保存模型相应信息的文件)到生产环境下去部署.在训练过程中我们可能会遇到以下情况: 需要运行很长时间的程序在 ...
- 一款超级好用的3Dmax模型插件 支持模型多格式批量转换
对于模型设计师来说模型格式转换是最常见的事,但是每一款建模软件所支持的格式各有不同,模型互导操作太麻烦 为了解决这个难题,老子云平台研发了一款基于3dmax软件的模型格式转换插件,支持多种模型格式想换 ...
- ThinkPHP 学习笔记 ( 三 ) 数据库操作之数据表模型和基础模型 ( Model )
//TP 恶补ing... 一.定义数据表模型 1.模型映射 要测试数据库是否正常连接,最直接的办法就是在当前控制器中实例化数据表,然后使用 dump 函数输出,查看数据库的链接状态.代码: publ ...
- ER模型到关系模型的转换规则
E-R模型向关系模型的转换规则: 一.两元联系的转换规则 (1)实体类型的转换 将每个实体类型转换成一个关系模式,实体的属性即为关系的属性,实体标识符即为关系的键. (2)联系类型的转换 a实体间的联 ...
- Fixflow引擎解析(三)(模型) - 创建EMF模型来读写XML文件
Fixflow引擎解析(四)(模型) - 通过EMF扩展BPMN2.0元素 Fixflow引擎解析(三)(模型) - 创建EMF模型来读写XML文件 Fixflow引擎解析(二)(模型) - BPMN ...
- 数据库设计和ER模型-------之关系模型的基本概念(第二章)
关系模型的基本术语 定义:用二维表格来表示实体集,用关键码表示实体之间联系的数据模型称为关系模型 有时也习惯称呼关系为表或表格,元组为行(Row),属性为列.关系中属性个数称为“元数”,元组个数称为“ ...
随机推荐
- CS224n笔记0
我准备跟随码农场hankcs大神的脚步,学习一下斯坦福的CS224n课程. 关于该课程的简介,hankcs大神已经写得很清楚了.
- jQuery学习之旅 Item10 ajax快餐
1. 摘要 本系列文章将带您进入jQuery的精彩世界, 其中有很多作者具体的使用经验和解决方案, 即使你会使用jQuery也能在阅读中发现些许秘籍. 本篇文章讲解如何使用jQuery方便快捷的实现A ...
- 16.app后端如何保证通讯安全--url签名
app和后端的通讯过程中,api请求有可能被别人截取或不小心泄露.那么,怎么保证api请求的安全呢?在这篇文章中,介绍一种常见的保证api请求安全的做法--url签名. 1. url签名详解 在前一篇 ...
- python3.5中,import sqlite3 出现 no module named _sqlite3的解决方法
我用的centos7.2,系统自带python2.7. 我自己装了python3.5,但在导入sqlite3这个包的时候出现找不到包的错误. 下面给出解决方法. 第一种: 检查自己有没有安装sqlit ...
- PHP引用符&的用法举例
php的引用就是在变量或者函数.对象等前面加上&符号.在PHP 中引用的意思是:不同的名字访问同一个变量内容.与C语言中的指针是有差别的,C语言中的指针里面存储的是变量的内容在内存中存放的地址 ...
- go语言nsq源码解读七 lookup_protocol_v1.go
本篇将解读nsqlookup处理tcp请求的核心代码文件lookup_protocol_v1.go. 1234567891011121314151617181920212223242526272829 ...
- 【构造】UVa 11387 The 3-Regular Graph
Description 输入n,构造一个n个点的无向图,使得每个点的度数都为3.不能有重边和自环,输出图或确定无解. Solution 如果n为奇数,奇数*3=奇数,度数为奇,必无解. 考虑我们怎么构 ...
- java中的单例模式与静态类
单例模式与静态类(一个类,所有方法为静态方法)是另一个非常有趣的问题,在<Java中有关单例模式的面试问题>博文中露掉了,由于单例模式和静态类都具有良好的访问性,它们之间有许多相似之处,例 ...
- C++实现离散数学的关系类,支持传递闭包运算
#include <vector> #include <cassert> #include <iostream> using namespace std; clas ...
- Mybatis配置详解
一.SqlSession的使用范围说明 1.SQLSessionFactoryBuilder 通过SqlSessionFactoryBuilder创建会话工厂SqlSessionFactory, ...