Skip to content

Commit 3a94ee7

Browse files
committed
feat(hb-base): migrate project structure by hb-base
1 parent 0cf0234 commit 3a94ee7

8 files changed

+207
-202
lines changed

README.md

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,26 @@ This code implements [Convolutional Neural Networks for Sentence Classification]
1111

1212
- Python 3.6
1313
- TensorFlow 1.4
14-
- hb-config
14+
- [hb-config](https://github.com/hb-research/hb-config) (Singleton Config)
1515
- tqdm
1616

17-
## Features
17+
## Project Structure
18+
19+
init Project by [hb-base](https://github.com/hb-research/hb-base)
20+
21+
.
22+
├── config # Config files (.yml, .json) using with hb-config
23+
├── data # dataset path
24+
├── notebooks # Prototyping with numpy or tf.interactivesession
25+
├── text-cnn # text-cnn architecture graphs (from input to logits)
26+
├── __init__.py # Graph logic
27+
├── data_loader.py # raw_date -> precossed_data -> generate_batch (using Dataset)
28+
├── hook.py # training or test hook feature (eg. print_variables)
29+
├── main.py # define experiment_fn
30+
└── model.py # define EstimatorSpec
31+
32+
Reference : [hb-config](https://github.com/hb-research/hb-config), [Dataset](https://www.tensorflow.org/api_docs/python/tf/data/Dataset#from_generator), [experiments_fn](https://www.tensorflow.org/api_docs/python/tf/contrib/learn/Experiment), [EstimatorSpec](https://www.tensorflow.org/api_docs/python/tf/estimator/EstimatorSpec)
1833

19-
- Using Higher-APIs in TensorFlow
20-
- [Estimator](https://www.tensorflow.org/api_docs/python/tf/estimator/Estimator)
21-
- [Experiment](https://www.tensorflow.org/api_docs/python/tf/contrib/learn/Experiment)
22-
- [Dataset](https://www.tensorflow.org/api_docs/python/tf/contrib/data/Dataset)
2334
- Dataset : [rt-polarity](https://github.com/yoonkim/CNN_sentence), [Sentiment Analysis on Movie Reviews](https://www.kaggle.com/c/sentiment-analysis-on-movie-reviews/data)
2435

2536
## Todo
@@ -30,7 +41,6 @@ This code implements [Convolutional Neural Networks for Sentence Classification]
3041
- CNN-nonstatic
3142
- CNN-multichannel
3243

33-
3444
## Config
3545

3646
example: kaggle\_movie\_review.yml
@@ -46,7 +56,8 @@ data:
4656
PAD_ID: 0
4757

4858
model:
49-
embed_type: 'rand' (rand, static, non-static, multichannel)
59+
batch_size: 64
60+
embed_type: 'rand' #(rand, static, non-static, multichannel)
5061
pretrained_embed: ""
5162
embed_dim: 300
5263
num_filters: 256
@@ -58,11 +69,13 @@ model:
5869
dropout: 0.5
5970

6071
train:
61-
batch_size: 64
6272
learning_rate: 0.00005
73+
6374
train_steps: 100000
6475
model_dir: 'logs/kaggle_movie_review'
65-
save_checkpoints_steps: 2000
76+
77+
save_checkpoints_steps: 1000
78+
loss_hook_n_iter: 1000
6679
check_hook_n_iter: 1000
6780
min_eval_frequency: 1000
6881
```
@@ -81,6 +94,20 @@ sh prepare_kaggle_movie_reviews.sh
8194
python main.py --config kaggle_movie_review --mode train_and_evaluate
8295
```
8396
97+
### Experiments modes
98+
99+
:white_check_mark: : Working
100+
:white_medium_small_square: : Not tested yet.
101+
102+
- :white_check_mark: `evaluate` : Evaluate on the evaluation data.
103+
- :white_medium_small_square: `extend_train_hooks` : Extends the hooks for training.
104+
- :white_medium_small_square: `reset_export_strategies` : Resets the export strategies with the new_export_strategies.
105+
- :white_medium_small_square: `run_std_server` : Starts a TensorFlow server and joins the serving thread.
106+
- :white_medium_small_square: `test` : Tests training, evaluating and exporting the estimator for a single step.
107+
- :white_check_mark: `train` : Fit the estimator using the training data.
108+
- :white_check_mark: `train_and_evaluate` : Interleaves training and evaluation.
109+
110+
84111
### Tensorboard
85112
86113
```tensorboard --logdir logs```
@@ -101,5 +128,5 @@ python main.py --config kaggle_movie_review --mode train_and_evaluate
101128
## Reference
102129
103130
- [Implementing a CNN for Text Classification in TensorFlow](http://www.wildml.com/2015/12/implementing-a-cnn-for-text-classification-in-tensorflow/) by Denny Britz
104-
- [Convolutional Neural Networks for Sentence Classification](http://arxiv.org/abs/1408.5882) (2014) by Y Kim
105-
- [A Sensitivity Analysis of (and Practitioners' Guide to) Convolutional Neural Networks for Sentence Classification](https://arxiv.org/pdf/1510.03820.pdf) (2015) Y Zhang
131+
- [Paper - Convolutional Neural Networks for Sentence Classification](http://arxiv.org/abs/1408.5882) (2014) by Y Kim
132+
- [Paper - A Sensitivity Analysis of (and Practitioners' Guide to) Convolutional Neural Networks for Sentence Classification](https://arxiv.org/pdf/1510.03820.pdf) (2015) Y Zhang

config/kaggle_movie_review.yml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ data:
88
PAD_ID: 0
99

1010
model:
11-
embed_type: 'rand'
11+
batch_size: 64
12+
embed_type: 'rand' #(rand, static, non-static, multichannel)
1213
pretrained_embed: ""
1314
embed_dim: 300
1415
num_filters: 256
@@ -20,10 +21,15 @@ model:
2021
dropout: 0.5
2122

2223
train:
23-
batch_size: 64
2424
learning_rate: 0.00005
25+
2526
train_steps: 100000
2627
model_dir: 'logs/kaggle_movie_review'
27-
save_checkpoints_steps: 2000
28+
29+
save_checkpoints_steps: 1000
30+
loss_hook_n_iter: 1000
2831
check_hook_n_iter: 1000
2932
min_eval_frequency: 1000
33+
34+
print_verbose: True
35+
debug: False

config/rt-polarity.yml

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,28 @@ data:
88
PAD_ID: 0
99

1010
model:
11-
embed_type: 'rand'
11+
batch_size: 64
12+
embed_type: 'rand' #(rand, static, non-static, multichannel)
1213
pretrained_embed: ""
13-
embed_dim: 128
14-
num_filters: 128
14+
embed_dim: 300
15+
num_filters: 256
1516
filter_sizes:
17+
- 2
1618
- 3
1719
- 4
1820
- 5
1921
dropout: 0.5
2022

2123
train:
22-
batch_size: 64
2324
learning_rate: 0.00001
25+
2426
train_steps: 20000
2527
model_dir: 'logs/rt-polarity'
26-
save_checkpoints_steps: 1000
28+
29+
save_checkpoints_steps: 100
30+
loss_hook_n_iter: 100
2731
check_hook_n_iter: 100
2832
min_eval_frequency: 100
33+
34+
print_verbose: True
35+
debug: False

data_loader.py

Lines changed: 78 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
import re
99

1010
import numpy as np
11-
from tqdm import tqdm
1211
from hbconfig import Config
13-
12+
import tensorflow as tf
13+
from tqdm import tqdm
1414

1515

1616
def clean_str(string):
@@ -214,26 +214,31 @@ def process_data():
214214
token2id('test_X')
215215

216216

217-
def make_train_and_test_set():
217+
def make_train_and_test_set(shuffle=True):
218218
print("make Training data and Test data Start....")
219219

220-
set_max_seq_length(['train_X_ids', 'test_X_ids'])
220+
if Config.data.get('max_seq_length', None) is None:
221+
set_max_seq_length(['train_X_ids', 'test_X_ids'])
221222

222223
train_X, train_y = load_data('train_X_ids', 'train_y')
223224
test_X, test_y = load_data('test_X_ids', 'test_y')
224225

225-
if len(train_X) == len(train_y) and len(test_X) == len(test_y):
226-
print(f"train data count : {len(train_X)}")
227-
print(f"test data count : {len(test_X)}")
228-
return train_X, test_X, train_y, test_y
229-
else:
230-
train_count = min(len(train_X), len(train_y))
231-
test_count = min(len(test_X), len(test_y))
226+
assert len(train_X) == len(train_y)
227+
assert len(test_X) == len(test_y)
228+
229+
print(f"train data count : {len(train_y)}")
230+
print(f"test data count : {len(test_y)}")
232231

233-
print(f"train data count : {train_count}")
234-
print(f"test data count : {test_count}")
232+
if shuffle:
233+
print("shuffle dataset ...")
234+
train_p = np.random.permutation(len(train_y))
235+
test_p = np.random.permutation(len(test_y))
235236

236-
return train_X[:train_count], test_X[:test_count], train_y[:train_count], test_y[:test_count]
237+
return ((train_X[train_p], train_y[train_p]),
238+
(test_X[test_p], test_y[test_p]))
239+
else:
240+
return ((train_X, train_y),
241+
(test_X, test_y))
237242

238243

239244
def load_data(X_fname, y_fname):
@@ -281,15 +286,66 @@ def set_max_seq_length(dataset_fnames):
281286
print(f"Setting max_seq_length to Config : {max_seq_length}")
282287

283288

284-
def _reshape_batch(inputs, size, batch_size):
285-
""" Create batch-major inputs. Batch inputs are just re-indexed inputs
286-
"""
287-
batch_inputs = []
288-
for length_id in range(size):
289-
batch_inputs.append(np.array([inputs[batch_id][length_id]
290-
for batch_id in range(batch_size)], dtype=np.int32))
291-
return batch_inputs
289+
def make_batch(data, buffer_size=10000, batch_size=64, scope="train"):
290+
291+
class IteratorInitializerHook(tf.train.SessionRunHook):
292+
"""Hook to initialise data iterator after Session is created."""
293+
294+
def __init__(self):
295+
super(IteratorInitializerHook, self).__init__()
296+
self.iterator_initializer_func = None
297+
298+
def after_create_session(self, session, coord):
299+
"""Initialise the iterator after the session has been created."""
300+
self.iterator_initializer_func(session)
301+
302+
303+
def get_inputs():
304+
305+
iterator_initializer_hook = IteratorInitializerHook()
306+
307+
def train_inputs():
308+
with tf.name_scope(scope):
309+
310+
X, y = data
311+
312+
# Define placeholders
313+
input_placeholder = tf.placeholder(
314+
tf.int32, [None, Config.data.max_seq_length])
315+
output_placeholder = tf.placeholder(
316+
tf.int32, [None, Config.data.num_classes])
317+
318+
# Build dataset iterator
319+
dataset = tf.data.Dataset.from_tensor_slices(
320+
(input_placeholder, output_placeholder))
321+
322+
if scope == "train":
323+
dataset = dataset.repeat(None) # Infinite iterations
324+
else:
325+
dataset = dataset.repeat(1) # 1 Epoch
326+
# dataset = dataset.shuffle(buffer_size=buffer_size)
327+
dataset = dataset.batch(batch_size)
328+
329+
iterator = dataset.make_initializable_iterator()
330+
next_X, next_y = iterator.get_next()
331+
332+
tf.identity(next_X[0], 'input_0')
333+
tf.identity(next_y[0], 'target_0')
334+
335+
# Set runhook to initialize iterator
336+
iterator_initializer_hook.iterator_initializer_func = \
337+
lambda sess: sess.run(
338+
iterator.initializer,
339+
feed_dict={input_placeholder: X,
340+
output_placeholder: y})
341+
342+
# Return batched (features, labels)
343+
return next_X, next_y
344+
345+
# Return function and hook
346+
return train_inputs, iterator_initializer_hook
292347

348+
return get_inputs()
293349

294350
if __name__ == '__main__':
295351

dataset.py

Lines changed: 0 additions & 104 deletions
This file was deleted.

0 commit comments

Comments
 (0)