Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
yinnxinn
chineseocr
提交
0938b1c0
C
chineseocr
项目概览
yinnxinn
/
chineseocr
与 Fork 源项目一致
从无法访问的项目Fork
通知
5
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
chineseocr
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
0938b1c0
编写于
5月 15, 2019
作者:
W
wenlihaoyu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
新增darknet keras pytorch之间模型转换代码
上级
d63a5873
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
229 addition
and
19 deletion
+229
-19
README.md
README.md
+2
-2
tools/keras_to_darknet.py
tools/keras_to_darknet.py
+227
-17
未找到文件。
README.md
浏览文件 @
0938b1c0
...
...
@@ -87,5 +87,5 @@ http://127.0.0.1:8080/ocr
2.
crnn https://github.com/meijieru/crnn.pytorch.git
3.
ctpn https://github.com/eragonruan/text-detection-ctpn
4.
CTPN https://github.com/tianzhi0549/CTPN
5.
keras yolo3 https://github.com/qqwweee/keras-yolo3.git
5.
keras yolo3 https://github.com/qqwweee/keras-yolo3.git
6.
darknet keras 模型转换参考 参考:https://www.cnblogs.com/shouhuxianjian/p/10567201.html
tools/keras_to_darknet.py
浏览文件 @
0938b1c0
# -*- coding: utf-8 -*-
''' yolov3_keras_to_darknet.py'''
"""
参考:https://www.cnblogs.com/shouhuxianjian/p/10567201.html
"""
import
os
import
io
import
argparse
import
configparser
import
numpy
import
numpy
as
np
import
keras
import
sys
import
os
os
.
environ
[
"CUDA_VISIBLE_DEVICES"
]
=
''
##不调用GPU
sys
.
path
.
append
(
''
)
sys
.
path
.
append
(
'..'
)
from
keras.models
import
load_model
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
=
'models/text.cfg'
)
parser
.
add_argument
(
'-h5_path'
,
help
=
'models/text.h5'
)
parser
=
argparse
.
ArgumentParser
(
description
=
"keras yolo3 to darknet"
)
parser
.
add_argument
(
'-cfg_path'
,
help
=
'models/text.cfg'
)
parser
.
add_argument
(
'-weights_path'
,
help
=
'models/text.h5'
)
parser
.
add_argument
(
'-output_path'
,
help
=
'models/text.weights'
)
return
parser
.
parse_args
()
class
DarkNetParser
(
object
):
def
__init__
(
self
,
cfg_path
,
weights_path
):
self
.
block_gen
=
self
.
_get_block
(
cfg_path
)
self
.
input_layer
=
Input
(
shape
=
(
None
,
None
,
3
))
self
.
out_index
=
[]
self
.
prev_layer
=
self
.
input_layer
self
.
all_layers
=
[]
self
.
count
=
[
0
,
0
]
self
.
weights_path
=
weights_path
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
)
# 如果有bn,则接着读取滤波器个scale,mean,var
# 读取权重
# 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)
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)
conv_layer
=
BatchNormalization
()(
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
):
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
)
self
.
model
=
model
self
.
model
.
load_weights
(
self
.
weights_path
)
class
WeightSaver
(
object
):
def
__init__
(
self
,
h5_path
,
output_path
):
textModel
=
load_model
(
h5_path
)
def
__init__
(
self
,
textModel
,
output_path
):
self
.
model
=
textModel
self
.
sess
=
K
.
get_session
()
#self.sess.run(K.tf.global_variables_initializer())
self
.
model
=
textModel
self
.
layers
=
{
weight
.
name
:
weight
for
weight
in
self
.
model
.
weights
}
self
.
fhandle
=
open
(
output_path
,
'wb'
)
self
.
_write_head
()
...
...
@@ -146,17 +330,43 @@ class KerasParser(object):
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
)
print
(
'loading weights...'
)
darknet_parser
=
DarkNetParser
(
args
.
cfg_path
,
args
.
weights_path
)
print
(
'creating keras model...'
)
layers_fun
=
{
'convolutional'
:
darknet_parser
.
conv
,
'net'
:
darknet_parser
.
net
,
'yolo'
:
darknet_parser
.
yolo
,
'route'
:
darknet_parser
.
route
,
'upsample'
:
darknet_parser
.
upsample
,
'maxpool'
:
darknet_parser
.
maxpool
,
'shortcut'
:
darknet_parser
.
shortcut
}
print
(
'Parsing Darknet config.'
)
for
ind
,
block
in
enumerate
(
darknet_parser
.
block_gen
):
type
=
block
[
'type'
]
layers_fun
[
type
](
block
)
darknet_parser
.
create_and_save
()
keras_loader
=
KerasParser
(
args
.
cfg_path
,
darknet_parser
.
model
,
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__"
:
if
__name__
==
'__main__'
:
main
()
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录