题记
关于yolov3的目标检测模型,的确是真香。
然后为了训练自己的数据,已经有很多人写过的文章。
但是有些人使用这个使用那个,导致一直都训练不成功。
环境
系统:win10
语言:python3.7
神经网络Backend:Tensorflow1.14.0
神经网络高层API:Keras2.2.5
CUDA:V10.0
cuDNN:V7.4.15
Github:https://github.com/qqwweee/keras-yolo3
以上要配合好来,不然你使用其他版本会改死你的,如Tensorflow2.0。
训练
标注数据
可以参考手把手教你用深度学习做物体检测(二):数据标注
但
千万要注意不要使用这篇文章提供生成yolov3需要的数据格式代码。
直接使用项目中自带的voc_annotation.py即可。
最后把train.txt放在与train.py在同一个目录。
同时修改voc_annotation.py内容
# classes = ["aeroplane", "bicycle", "bird", "boat", "bottle", "bus", "car", "cat", "chair", "cow", "diningtable", "dog", "horse", "motorbike", "person", "pottedplant", "sheep", "sofa", "train", "tvmonitor"]
classes = ["xx1", "xx2", "xx3", "xx4"]
代码修改
- 通过yolov3.weights文件生成yolo.h5
yolov3.weights在这里下载https://pjreddie.com/media/files/yolov3.weights
python convert.py yolov3.cfg yolov3.weights model_data/yolo.h5
- 修改train.py(不贴大段代码了,请自行搜索):
def _main():
annotation_path = 'train.txt'
log_dir = 'logs/000/'
classes_path = 'model_data/voc_classes.txt'
anchors_path = 'model_data/yolo_anchors.txt'
class_names = get_classes(classes_path)
num_classes = len(class_names)
anchors = get_anchors(anchors_path)
input_shape = (416,416) # multiple of 32, hw
is_tiny_version = len(anchors)==6 # default setting
if is_tiny_version:
model = create_tiny_model(input_shape, anchors, num_classes,
freeze_body=2, weights_path='model_data/tiny_yolo_weights.h5')
else:
model = create_model(input_shape, anchors, num_classes,
# freeze_body=2, weights_path='model_data/yolo_weights.h5') # make sure you know what you freeze
freeze_body=2, weights_path='model_data/yolo.h5') # make sure you know what you freeze
# 主要是修改一下原始的模型位置
修改voc_classes.txt里的分类名字
当时,你可以复制一份,然后修改classes_path = 'model_data/voc_classes_new.txt'
也可以
- 由于我使用的是比较高版本的Tensorflow,所以要修改一下yolo3\model.py(不贴大段代码了,请自行搜索)
原始:
def loop_body(b, ignore_mask):
true_box = tf.boolean_mask(y_true[l][b,...,0:4], object_mask_bool[b,...,0])
iou = box_iou(pred_box[b], true_box)
best_iou = K.max(iou, axis=-1)
ignore_mask = ignore_mask.write(b, K.cast(best_iou<ignore_thresh, K.dtype(true_box)))
return b+1, ignore_mask
_, ignore_mask = K.control_flow_ops.while_loop(lambda b,*args: b<m, loop_body, [0, ignore_mask])
ignore_mask = ignore_mask.stack()
ignore_mask = K.expand_dims(ignore_mask, -1)
现在:
from tensorflow.python.ops import control_flow_ops
def loop_body(b, ignore_mask):
true_box = tf.boolean_mask(y_true[l][b,...,0:4], object_mask_bool[b,...,0])
iou = box_iou(pred_box[b], true_box)
best_iou = K.max(iou, axis=-1)
ignore_mask = ignore_mask.write(b, K.cast(best_iou<ignore_thresh, K.dtype(true_box)))
return b+1, ignore_mask
_, ignore_mask = control_flow_ops.while_loop(lambda b,*args: b<m, loop_body, [0, ignore_mask])
ignore_mask = ignore_mask.stack()
ignore_mask = K.expand_dims(ignore_mask, -1)
- 修改yolov3.cfg,搜索关键字“yolo”,找出3个地方修改上下文。
[convolutional]
size=1
stride=1
pad=1
filters=27 # 这里是3*(5+classes)
activation=linear
[yolo]
mask = 6,7,8
anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326
classes=4 # 这里的classes
num=9
jitter=.3
ignore_thresh = .5
truth_thresh = 1
random=0 # 这里是0 或 1 ,显存小用0吧
# 。。。
# 。。。
[convolutional]
size=1
stride=1
pad=1
filters=27 # 这里是3*(5+classes)
activation=linear
[yolo]
mask = 3,4,5
anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326
classes=4 # 这里的classes
num=9
jitter=.3
ignore_thresh = .5
truth_thresh = 1
random=0 # 这里是0 或 1 ,显存小用0吧
# 。。。
# 。。。
[convolutional]
size=1
stride=1
pad=1
filters=27 # 这里是3*(5+classes)
activation=linear
[yolo]
mask = 0,1,2
anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326
classes=4 # 这里的classes
num=9
jitter=.3
ignore_thresh = .5
truth_thresh = 1
random=0 # 这里是0 或 1 ,显存小用0吧
- 记得在train.py的同目录下新建logs\000
- 走你
python train.py
- 结果loss在14左右就early_stop了。