Skip to content

Commit 3eddd44

Browse files
committed
fixed training procedure
1 parent ac25142 commit 3eddd44

9 files changed

+85
-99
lines changed

.gitignore

+4-1
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,7 @@ dataset/annotations
1111
dataset/coco
1212
.idea
1313
__pycache__
14-
.ipynb_checkpoints
14+
.ipynb_checkpoints
15+
logs/
16+
training.csv
17+
weights.best.h5

README.md

+19-14
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,30 @@ any image file as an input.
4444
- `python demo_camera.py` to run the web demo.
4545

4646
## Training steps
47-
**UPDATE 10/2017:**
4847

49-
**-Augmented samples are fetched from the [server](https://github.com/michalfaber/rmpe_dataset_server). The network never sees the same image twice
48+
**UPDATE 26/10/2017**
49+
50+
**Fixed problem with the training procedure.
51+
Here are my results after training for 5 epochs = 25000 iterations (1 epoch is ~5000 batches)
52+
The loss values are quite similar as in the original training - [output.txt](https://github.com/ZheC/Realtime_Multi-Person_Pose_Estimation/blob/master/training/example_loss/output.txt)**
53+
54+
<p align="center">
55+
<img src="https://github.com/michalfaber/keras_Realtime_Multi-Person_Pose_Estimation/blob/master/readme/losses.png", width="700">
56+
</p>
57+
58+
**Results of running `demo_image --image sample_images/ski.jpg --model training/weights.best.h5` with weights trained only 25000 iterations. Not too bad !!! Training on my single 1070 GPU took around 10 hours.**
59+
60+
<p align="center">
61+
<img src="https://github.com/michalfaber/keras_Realtime_Multi-Person_Pose_Estimation/blob/master/readme/5ep_result.png", width="700">
62+
</p>
63+
64+
**UPDATE 22/10/2017:**
65+
66+
**Augmented samples are fetched from the [server](https://github.com/michalfaber/rmpe_dataset_server). The network never sees the same image twice
5067
which was a problem in previous approach (tool rmpe_dataset_transformer)
5168
This allows you to run augmentation locally or on separate node.
5269
You can start 2 instances, one serving training set and a second one serving validation set (on different port if locally)**
5370

54-
**-Experimentally I've added image normalization as in vgg paper (images should be zero-centered by mean pixel subtraction)**
55-
5671
- Install gsutil `curl https://sdk.cloud.google.com | bash`. This is a really helpful tool for downloading large datasets.
5772
- Download the data set (~25 GB) `cd dataset; sh get_dataset.sh`,
5873
- Download [COCO official toolbox](https://github.com/pdollar/coco) in `dataset/coco/` .
@@ -73,16 +88,6 @@ any image file as an input.
7388
- Set the correct number of samples within `python train_pose.py` - variables "train_samples = ???" and "val_samples = ???".
7489
This number is used by keras to determine how many samples are in 1 epoch.
7590
- Train the model in a third terminal `python train_pose.py`
76-
77-
NOTE:
78-
I trained the model from scratch for 3,5 days on a single GPU 1070 but did't obtain satisfactory results.
79-
38 epochs is about 200000 iterations in caffe.
80-
I noticed that reducing learning rate after the step 136106 (as in orginal caffe model) was probably too early
81-
because learning process slowed down.
82-
83-
<div align="center">
84-
<img src="https://github.com/michalfaber/keras_Realtime_Multi-Person_Pose_Estimation/blob/master/readme/tr_results.png", width="450", height="563">
85-
</div>
8691

8792
## Related repository
8893
- CVPR'16, [Convolutional Pose Machines](https://github.com/shihenw/convolutional-pose-machines-release).

caffe_to_keras.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
from model import get_model
1+
from model import get_testing_model
22
import numpy as np
33
import os
44

55
CAFFE_LAYERS_DIR = "model/caffe/layers"
66
KERAS_MODEL_FILE = "model/keras/model.h5"
77

8-
m = get_model()
8+
m = get_testing_model()
99

1010
for layer in m.layers:
1111
layer_name = layer.name

demo.ipynb

+30-35
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,17 @@
22
"cells": [
33
{
44
"cell_type": "code",
5-
"execution_count": 6,
6-
"metadata": {
7-
"collapsed": false
8-
},
9-
"outputs": [],
5+
"execution_count": 1,
6+
"metadata": {},
7+
"outputs": [
8+
{
9+
"name": "stderr",
10+
"output_type": "stream",
11+
"text": [
12+
"Using TensorFlow backend.\n"
13+
]
14+
}
15+
],
1016
"source": [
1117
"import keras\n",
1218
"from keras.models import Sequential\n",
@@ -30,9 +36,9 @@
3036
},
3137
{
3238
"cell_type": "code",
33-
"execution_count": 8,
39+
"execution_count": 2,
3440
"metadata": {
35-
"collapsed": false
41+
"collapsed": true
3642
},
3743
"outputs": [],
3844
"source": [
@@ -134,11 +140,12 @@
134140
"cell_type": "code",
135141
"execution_count": 18,
136142
"metadata": {
137-
"collapsed": false
143+
"collapsed": true
138144
},
139145
"outputs": [],
140146
"source": [
141-
"weights_path = \"model/keras/model.h5\"\n",
147+
"weights_path = \"model/keras/model.h5\" # orginal weights converted from caffe\n",
148+
"#weights_path = \"training/weights.best.h5\" # weights tarined from scratch \n",
142149
"\n",
143150
"input_shape = (None,None,3)\n",
144151
"\n",
@@ -195,9 +202,7 @@
195202
{
196203
"cell_type": "code",
197204
"execution_count": 20,
198-
"metadata": {
199-
"collapsed": false
200-
},
205+
"metadata": {},
201206
"outputs": [
202207
{
203208
"data": {
@@ -237,7 +242,7 @@
237242
"cell_type": "code",
238243
"execution_count": 21,
239244
"metadata": {
240-
"collapsed": false
245+
"collapsed": true
241246
},
242247
"outputs": [],
243248
"source": [
@@ -256,9 +261,7 @@
256261
{
257262
"cell_type": "code",
258263
"execution_count": 22,
259-
"metadata": {
260-
"collapsed": false
261-
},
264+
"metadata": {},
262265
"outputs": [
263266
{
264267
"name": "stdout",
@@ -380,9 +383,7 @@
380383
{
381384
"cell_type": "code",
382385
"execution_count": 23,
383-
"metadata": {
384-
"collapsed": false
385-
},
386+
"metadata": {},
386387
"outputs": [
387388
{
388389
"data": {
@@ -416,9 +417,7 @@
416417
{
417418
"cell_type": "code",
418419
"execution_count": 25,
419-
"metadata": {
420-
"collapsed": false
421-
},
420+
"metadata": {},
422421
"outputs": [
423422
{
424423
"data": {
@@ -463,7 +462,7 @@
463462
"cell_type": "code",
464463
"execution_count": 26,
465464
"metadata": {
466-
"collapsed": false
465+
"collapsed": true
467466
},
468467
"outputs": [],
469468
"source": [
@@ -516,7 +515,7 @@
516515
"cell_type": "code",
517516
"execution_count": 28,
518517
"metadata": {
519-
"collapsed": false
518+
"collapsed": true
520519
},
521520
"outputs": [],
522521
"source": [
@@ -573,7 +572,7 @@
573572
"cell_type": "code",
574573
"execution_count": 29,
575574
"metadata": {
576-
"collapsed": false
575+
"collapsed": true
577576
},
578577
"outputs": [],
579578
"source": [
@@ -645,9 +644,7 @@
645644
{
646645
"cell_type": "code",
647646
"execution_count": 31,
648-
"metadata": {
649-
"collapsed": false
650-
},
647+
"metadata": {},
651648
"outputs": [
652649
{
653650
"data": {
@@ -691,9 +688,7 @@
691688
{
692689
"cell_type": "code",
693690
"execution_count": 32,
694-
"metadata": {
695-
"collapsed": false
696-
},
691+
"metadata": {},
697692
"outputs": [
698693
{
699694
"data": {
@@ -744,9 +739,9 @@
744739
"metadata": {
745740
"anaconda-cloud": {},
746741
"kernelspec": {
747-
"display_name": "Python [conda env:python35]",
742+
"display_name": "Python 3",
748743
"language": "python",
749-
"name": "conda-env-python35-py"
744+
"name": "python3"
750745
},
751746
"language_info": {
752747
"codemirror_mode": {
@@ -758,9 +753,9 @@
758753
"name": "python",
759754
"nbconvert_exporter": "python",
760755
"pygments_lexer": "ipython3",
761-
"version": "3.5.2"
756+
"version": "3.6.1"
762757
}
763758
},
764759
"nbformat": 4,
765-
"nbformat_minor": 0
760+
"nbformat_minor": 1
766761
}

demo_image.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
from model import get_testing_model
1010

1111

12-
keras_weights_file = "model/keras/model.h5"
13-
1412
# find connection in the specified sequence, center 29 is in the position 15
1513
limbSeq = [[2, 3], [2, 6], [3, 4], [4, 5], [6, 7], [7, 8], [2, 9], [9, 10], \
1614
[10, 11], [2, 12], [12, 13], [13, 14], [2, 1], [1, 15], [15, 17], \
@@ -229,10 +227,12 @@ def process (input_image, params, model_params):
229227
parser = argparse.ArgumentParser()
230228
parser.add_argument('--image', type=str, required=True, help='input image')
231229
parser.add_argument('--output', type=str, default='result.png', help='output image')
230+
parser.add_argument('--model', type=str, default='model/keras/model.h5', help='path to the weights file')
232231

233232
args = parser.parse_args()
234233
input_image = args.image
235234
output = args.output
235+
keras_weights_file = args.model
236236

237237
tic = time.time()
238238
print('start processing...')
@@ -241,7 +241,7 @@ def process (input_image, params, model_params):
241241

242242
# authors of original model don't use
243243
# vgg normalization (subtracting mean) on input images
244-
model = get_testing_model(vgg_norm=False)
244+
model = get_testing_model()
245245
model.load_weights(keras_weights_file)
246246

247247
# load config

model.py

+4-13
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
from keras.layers.merge import Multiply
77
from keras.regularizers import l2
88
from keras.initializers import random_normal,constant
9-
import numpy as np
109

1110
def relu(x): return Activation('relu')(x)
1211

@@ -110,7 +109,7 @@ def apply_mask(x, mask1, mask2, num_p, stage, branch):
110109
return w
111110

112111

113-
def get_training_model(weight_decay, vgg_norm):
112+
def get_training_model(weight_decay):
114113

115114
stages = 6
116115
np_branch1 = 38
@@ -131,11 +130,7 @@ def get_training_model(weight_decay, vgg_norm):
131130
inputs.append(vec_weight_input)
132131
inputs.append(heat_weight_input)
133132

134-
if vgg_norm:
135-
vgg_mean = np.array([103.939, 116.779, 123.68]) # BGR
136-
img_normalized = Lambda(lambda x: x - vgg_mean)(img_input)
137-
else:
138-
img_normalized = Lambda(lambda x: x / 256 - 0.5)(img_input) # [-0.5, 0.5]
133+
img_normalized = Lambda(lambda x: x / 256 - 0.5)(img_input) # [-0.5, 0.5]
139134

140135
# VGG
141136
stage0_out = vgg_block(img_normalized, weight_decay)
@@ -174,7 +169,7 @@ def get_training_model(weight_decay, vgg_norm):
174169
return model
175170

176171

177-
def get_testing_model(vgg_norm=False):
172+
def get_testing_model():
178173
stages = 6
179174
np_branch1 = 38
180175
np_branch2 = 19
@@ -183,11 +178,7 @@ def get_testing_model(vgg_norm=False):
183178

184179
img_input = Input(shape=img_input_shape)
185180

186-
if vgg_norm:
187-
vgg_mean = np.array([103.939, 116.779, 123.68]) # BGR
188-
img_normalized = Lambda(lambda x: x - vgg_mean)(img_input)
189-
else:
190-
img_normalized = Lambda(lambda x: x / 256 - 0.5)(img_input) # [-0.5, 0.5]
181+
img_normalized = Lambda(lambda x: x / 256 - 0.5)(img_input) # [-0.5, 0.5]
191182

192183
# VGG
193184
stage0_out = vgg_block(img_normalized, None)

readme/5ep_result.png

123 KB
Loading

readme/losses.png

77.8 KB
Loading

0 commit comments

Comments
 (0)