Views
No views yet
| Model | B-1 | B-2 | B-3 | B-4 | M | R | C | S | BERTscore |
|---|---|---|---|---|---|---|---|---|---|
| BLIP Beam Search b=3 | .797 | .649 | .514 | .403 | .311 | .606 | 1.365 | .243 | .9484 |
| + BERT-CNN $th=0$ | .798 | .646 | .506 | .392 | .305 | .598 | 1.339 | .238 | .9473 |
| + BERT-CNN $th\geq0.2$ | .798 | .647 | .507 | .393 | .306 | .600 | 1.342 | .238 | .9473 |
| + BERT-CNN $th\geq0.3$ | .802 | .651 | .511 | .397 | .307 | .601 | 1.349 | .238 | .9479 |
| + BERT-CNN $th\geq0.4$ | .806 | .654 | .513 | .397 | .303 | .599 | 1.343 | .235 | .9476 |
| Model | Uniq | Voc | mBLeu-1↓ | Div-1 | Div-2 | SBERT-sts |
|---|---|---|---|---|---|---|
| BLIP Beam Search b=3 | 8.60 | 1406 | .461 | .68 | .80 | .8058 |
| + BERT-CNN $th=0$ | 8.49 | 1532 | .457 | .68 | .80 | .8046 |
| + BERT-CNN $th\geq0.2$ | 8.48 | 1486 | .458 | .68 | .80 | .8052 |
| + BERT-CNN $th\geq0.3$ | 8.41 | 1448 | .458 | .68 | .80 | .8060 |
| + BERT-CNN $th\geq0.4$ | 8.30 | 1448 | .455 | .68 | .80 | .8053 |
| human | 9.14 | 3425 | .375 | .74 | .84 | NA |
conda create -n BERT_visual python=3.6 anaconda
conda activate BERT_visual
pip install tensorflow==1.15.0
pip install --upgrade tensorflow_hub==0.7.0git clone https://github.com/gaphex/bert_experimental/1import tensorflow as tf
2import numpy as np
3import pandas as pd
4import sys
5from sklearn.model_selection import train_test_split
6
7sys.path.insert(0, "bert_experimental")
8
9from bert_experimental.finetuning.text_preprocessing import build_preprocessor
10from bert_experimental.finetuning.graph_ops import load_graph
11
12df = pd.read_csv("test.tsv", sep='\t')
13
14texts = []
15delimiter = " ||| "
16
17for vis, cap in zip(df.visual.tolist(), df.caption.tolist()):
18 texts.append(delimiter.join((str(vis), str(cap))))
19
20texts = np.array(texts)
21
22trX, tsX = train_test_split(texts, shuffle=False, test_size=0.01)
23
24restored_graph = load_graph("frozen_graph.pb")
25
26graph_ops = restored_graph.get_operations()
27input_op, output_op = graph_ops[0].name, graph_ops[-1].name
28print(input_op, output_op)
29
30x = restored_graph.get_tensor_by_name(input_op + ':0')
31y = restored_graph.get_tensor_by_name(output_op + ':0')
32
33preprocessor = build_preprocessor("vocab.txt", 64)
34py_func = tf.numpy_function(preprocessor, [x], [tf.int32, tf.int32, tf.int32], name='preprocessor')
35
36##predictions
37sess = tf.Session(graph=restored_graph)
38
39print(trX[:4])
40
41y = tf.print(y, summarize=-1)
42y_out = sess.run(y, feed_dict={
43 x: trX[:4].reshape((-1,1))
44
45 })
46
47
48print(y_out)python BERT_CNN.py --train train_0.4.tsv --epochs 51# -*- coding: utf-8 -*-
2#!/bin/env python
3import sys
4import argparse
5import re
6import os
7import sys
8import json
9
10import logging
11import numpy as np
12import pandas as pd
13import tensorflow as tf
14import tensorflow_hub as hub
15from BertLayer import BertLayer
16from BertLayer import build_preprocessor
17from freeze_keras_model import freeze_keras_model
18
19from data_pre import *
20from tensorflow import keras
21from tensorflow.keras.callbacks import ReduceLROnPlateau, ModelCheckpoint
22from sklearn.model_selection import train_test_split
23
24
25if not 'bert_repo' in sys.path:
26 sys.path.insert(0, 'bert_repo')
27
28from modeling import BertModel, BertConfig
29from tokenization import FullTokenizer, convert_to_unicode
30from extract_features import InputExample, convert_examples_to_features
31
32
33# get TF logger
34log = logging.getLogger('tensorflow')
35log.handlers = []
36
37
38parser=argparse.ArgumentParser()
39parser.add_argument('--train', default='train.tsv', help='beam serach', type=str,required=False)
40parser.add_argument('--num_bert_layer', default='12', help='truned layers', type=int,required=False)
41parser.add_argument('--batch_size', default='128', help='truned layers', type=int,required=False)
42parser.add_argument('--epochs', default='5', help='', type=int,required=False)
43parser.add_argument('--seq_len', default='64', help='', type=int,required=False)
44parser.add_argument('--CNN_kernel_size', default='3', help='', type=int,required=False)
45parser.add_argument('--CNN_filters', default='32', help='', type=int,required=False)
46args = parser.parse_args()
47
48
49# Downlaod the pre-trained model
50
51#!wget https://storage.googleapis.com/bert_models/2018_10_18/uncased_L-12_H-768_A-12.zip
52#!unzip uncased_L-12_H-768_A-12.zip
53
54
55# tf.Module
56def build_module_fn(config_path, vocab_path, do_lower_case=True):
57
58 def bert_module_fn(is_training):
59 """Spec function for a token embedding module."""
60
61 input_ids = tf.placeholder(shape=[None, None], dtype=tf.int32, name="input_ids")
62 input_mask = tf.placeholder(shape=[None, None], dtype=tf.int32, name="input_mask")
63 token_type = tf.placeholder(shape=[None, None], dtype=tf.int32, name="segment_ids")
64
65 config = BertConfig.from_json_file(config_path)
66 model = BertModel(config=config, is_training=is_training,
67 input_ids=input_ids, input_mask=input_mask, token_type_ids=token_type)
68
69 seq_output = model.all_encoder_layers[-1]
70 pool_output = model.get_pooled_output()
71
72 config_file = tf.constant(value=config_path, dtype=tf.string, name="config_file")
73 vocab_file = tf.constant(value=vocab_path, dtype=tf.string, name="vocab_file")
74 lower_case = tf.constant(do_lower_case)
75
76 tf.add_to_collection(tf.GraphKeys.ASSET_FILEPATHS, config_file)
77 tf.add_to_collection(tf.GraphKeys.ASSET_FILEPATHS, vocab_file)
78
79 input_map = {"input_ids": input_ids,
80 "input_mask": input_mask,
81 "segment_ids": token_type}
82
83 output_map = {"pooled_output": pool_output,
84 "sequence_output": seq_output}
85
86 output_info_map = {"vocab_file": vocab_file,
87 "do_lower_case": lower_case}
88
89 hub.add_signature(name="tokens", inputs=input_map, outputs=output_map)
90 hub.add_signature(name="tokenization_info", inputs={}, outputs=output_info_map)
91
92 return bert_module_fn
93
94
95#MODEL_DIR = "uncased_L-12_H-768_A-12"
96config_path = "/{}/bert_config.json".format(MODEL_DIR)
97vocab_path = "/{}/vocab.txt".format(MODEL_DIR)
98
99
100tags_and_args = []
101for is_training in (True, False):
102 tags = set()
103 if is_training:
104 tags.add("train")
105 tags_and_args.append((tags, dict(is_training=is_training)))
106
107module_fn = build_module_fn(config_path, vocab_path)
108spec = hub.create_module_spec(module_fn, tags_and_args=tags_and_args)
109spec.export("bert-module",
110 checkpoint_path="/{}/bert_model.ckpt".format(MODEL_DIR))
111
112class BertLayer(tf.keras.layers.Layer):
113 def __init__(self, bert_path, seq_len=64, n_tune_layers=3,
114 pooling="cls", do_preprocessing=True, verbose=False,
115 tune_embeddings=False, trainable=True, **kwargs):
116
117 self.trainable = trainable
118 self.n_tune_layers = n_tune_layers
119 self.tune_embeddings = tune_embeddings
120 self.do_preprocessing = do_preprocessing
121
122 self.verbose = verbose
123 self.seq_len = seq_len
124 self.pooling = pooling
125 self.bert_path = bert_path
126
127 self.var_per_encoder = 16
128 if self.pooling not in ["cls", "mean", None]:
129 raise NameError(
130 f"Undefined pooling type (must be either 'cls', 'mean', or None, but is {self.pooling}"
131 )
132
133 super(BertLayer, self).__init__(**kwargs)
134
135 def build(self, input_shape):
136
137 self.bert = hub.Module(self.build_abspath(self.bert_path),
138 trainable=self.trainable, name=f"{self.name}_module")
139
140 trainable_layers = []
141 if self.tune_embeddings:
142 trainable_layers.append("embeddings")
143
144 if self.pooling == "cls":
145 trainable_layers.append("pooler")
146
147 if self.n_tune_layers > 0:
148 encoder_var_names = [var.name for var in self.bert.variables if 'encoder' in var.name]
149 n_encoder_layers = int(len(encoder_var_names) / self.var_per_encoder)
150 for i in range(self.n_tune_layers):
151 trainable_layers.append(f"encoder/layer_{str(n_encoder_layers - 1 - i)}/")
152
153 # Add module variables to layer's trainable weights
154 for var in self.bert.variables:
155 if any([l in var.name for l in trainable_layers]):
156 self._trainable_weights.append(var)
157 else:
158 self._non_trainable_weights.append(var)
159
160 if self.verbose:
161 print("*** TRAINABLE VARS *** ")
162 for var in self._trainable_weights:
163 print(var)
164
165 self.build_preprocessor()
166 self.initialize_module()
167
168 super(BertLayer, self).build(input_shape)
169
170 def build_abspath(self, path):
171 if path.startswith("https://") or path.startswith("gs://"):
172 return path
173 else:
174 return os.path.abspath(path)
175
176 def build_preprocessor(self):
177 sess = tf.keras.backend.get_session()
178 tokenization_info = self.bert(signature="tokenization_info", as_dict=True)
179 vocab_file, do_lower_case = sess.run([tokenization_info["vocab_file"],
180 tokenization_info["do_lower_case"]])
181 self.preprocessor = build_preprocessor(vocab_file, self.seq_len, do_lower_case)
182
183 def initialize_module(self):
184 sess = tf.keras.backend.get_session()
185
186 vars_initialized = sess.run([tf.is_variable_initialized(var)
187 for var in self.bert.variables])
188
189 uninitialized = []
190 for var, is_initialized in zip(self.bert.variables, vars_initialized):
191 if not is_initialized:
192 uninitialized.append(var)
193
194 if len(uninitialized):
195 sess.run(tf.variables_initializer(uninitialized))
196
197 def call(self, input):
198
199 if self.do_preprocessing:
200 input = tf.numpy_function(self.preprocessor,
201 [input], [tf.int32, tf.int32, tf.int32],
202 name='preprocessor')
203 for feature in input:
204 feature.set_shape((None, self.seq_len))
205
206 input_ids, input_mask, segment_ids = input
207
208 bert_inputs = dict(
209 input_ids=input_ids, input_mask=input_mask, segment_ids=segment_ids
210 )
211 output = self.bert(inputs=bert_inputs, signature="tokens", as_dict=True)
212
213 if self.pooling == "cls":
214 pooled = output["pooled_output"]
215 else:
216 result = output["sequence_output"]
217
218 input_mask = tf.cast(input_mask, tf.float32)
219 mul_mask = lambda x, m: x * tf.expand_dims(m, axis=-1)
220 masked_reduce_mean = lambda x, m: tf.reduce_sum(mul_mask(x, m), axis=1) / (
221 tf.reduce_sum(m, axis=1, keepdims=True) + 1e-10)
222
223 if self.pooling == "mean":
224 pooled = masked_reduce_mean(result, input_mask)
225 else:
226 pooled = mul_mask(result, input_mask)
227
228 return pooled
229
230 def get_config(self):
231 config_dict = {
232 "bert_path": self.bert_path,
233 "seq_len": self.seq_len,
234 "pooling": self.pooling,
235 "n_tune_layers": self.n_tune_layers,
236 "tune_embeddings": self.tune_embeddings,
237 "do_preprocessing": self.do_preprocessing,
238 "verbose": self.verbose
239 }
240 super(BertLayer, self).get_config()
241 return config_dict
242
243
244# read the train data
245df = pd.read_csv(args.train, sep='\t')
246
247
248labels = df.is_related.values
249
250texts = []
251delimiter = " ||| "
252
253for vis, cap in zip(df.visual.tolist(), df.caption.tolist()):
254 texts.append(delimiter.join((str(vis), str(cap))))
255
256
257texts = np.array(texts)
258
259trX, tsX, trY, tsY = train_test_split(texts, labels, shuffle=True, test_size=0.2)
260
261
262# Buliding the model
263embedding_size = 768
264
265# input
266inp = tf.keras.Input(shape=(1,), dtype=tf.string)
267
268# BERT encoder
269# For CLS with linear layer
270#encoder = BertLayer(bert_path="./bert-module/", seq_len=48, tune_embeddings=False,
271# pooling='cls', n_tune_layers=3, verbose=False)
272
273
274# CNN Layers
275encoder = BertLayer(bert_path="./bert-module/", seq_len=args.seq_len, tune_embeddings=False, pooling=None, n_tune_layers=args.num_bert_layer, verbose=False)
276cnn_out = tf.keras.layers.Conv1D(args.CNN_filters, args.CNN_kernel_size, padding='VALID', activation=tf.nn.relu)(encoder(inp))
277pool = tf.keras.layers.MaxPooling1D(pool_size=2)(cnn_out)
278flat = tf.keras.layers.Flatten()(pool)
279pred = tf.keras.layers.Dense(1, activation="sigmoid")(flat)
280
281
282model = tf.keras.models.Model(inputs=[inp], outputs=[pred])
283
284model.summary()
285
286model.compile(
287 optimizer=tf.keras.optimizers.Adam(learning_rate=1e-5, ),
288 loss="binary_crossentropy",
289 metrics=["accuracy"])
290
291# fit the data
292import logging
293logging.getLogger("tensorflow").setLevel(logging.WARNING)
294
295saver = keras.callbacks.ModelCheckpoint("bert_CNN_tuned.hdf5")
296
297model.fit(trX, trY, validation_data=[tsX, tsY], batch_size=args.batch_size, epochs=args.epochs, callbacks=[saver])
298
299#save the model
300model.predict(trX[:10])
301
302import json
303json.dump(model.to_json(), open("model.json", "w"))
304
305model = tf.keras.models.model_from_json(json.load(open("model.json")),
306 custom_objects={"BertLayer": BertLayer})
307
308model.load_weights("bert_CNN_tuned.hdf5")
309
310model.predict(trX[:10])
311
312# For fast inference and less RAM usesage as post-processing we need to "freezing" the model.
313from tensorflow.python.framework.graph_util import convert_variables_to_constants
314from tensorflow.python.tools.optimize_for_inference_lib import optimize_for_inference
315
316def freeze_keras_model(model, export_path=None, clear_devices=True):
317 sess = tf.keras.backend.get_session()
318 graph = sess.graph
319
320 with graph.as_default():
321
322 input_tensors = model.inputs
323 output_tensors = model.outputs
324 dtypes = [t.dtype.as_datatype_enum for t in input_tensors]
325 input_ops = [t.name.rsplit(":", maxsplit=1)[0] for t in input_tensors]
326 output_ops = [t.name.rsplit(":", maxsplit=1)[0] for t in output_tensors]
327
328 tmp_g = graph.as_graph_def()
329 if clear_devices:
330 for node in tmp_g.node:
331 node.device = ""
332
333 tmp_g = optimize_for_inference(
334 tmp_g, input_ops, output_ops, dtypes, False)
335
336 tmp_g = convert_variables_to_constants(sess, tmp_g, output_ops)
337
338 if export_path is not None:
339 with tf.gfile.GFile(export_path, "wb") as f:
340 f.write(tmp_g.SerializeToString())
341
342 return tmp_g
343
344
345# freeze and save the model
346frozen_graph = freeze_keras_model(model, export_path="frozen_graph.pb")
347
348
349# inference
350#!git clone https://github.com/gaphex/bert_experimental/
351
352import tensorflow as tf
353import numpy as np
354import sys
355
356sys.path.insert(0, "bert_experimental")
357
358from bert_experimental.finetuning.text_preprocessing import build_preprocessor
359from bert_experimental.finetuning.graph_ops import load_graph
360
361
362restored_graph = load_graph("frozen_graph.pb")
363graph_ops = restored_graph.get_operations()
364input_op, output_op = graph_ops[0].name, graph_ops[-1].name
365print(input_op, output_op)
366
367x = restored_graph.get_tensor_by_name(input_op + ':0')
368y = restored_graph.get_tensor_by_name(output_op + ':0')
369
370
371preprocessor = build_preprocessor("vocab.txt", 64)
372py_func = tf.numpy_function(preprocessor, [x], [tf.int32, tf.int32, tf.int32], name='preprocessor')
373
374py_func = tf.numpy_function(preprocessor, [x], [tf.int32, tf.int32, tf.int32])
375
376# predictions
377sess = tf.Session(graph=restored_graph)
378
379trX[:10]
380
381y_out = sess.run(y, feed_dict={
382 x: trX[:10].reshape((-1,1))
383 })
384
385print(y_out)
386
387