From 4ad0ce2ea7cfb5fc4680a953c2e468fb4c107ba6 Mon Sep 17 00:00:00 2001 From: aliabd Date: Wed, 10 Jun 2020 02:34:24 -0700 Subject: [PATCH 1/5] changed all f-strings to .format --- build-interface.py | 2 +- gradio/inputs.py | 20 ++++++++++---------- gradio/interface.py | 9 +++++---- gradio/networking.py | 8 +++++--- gradio/outputs.py | 5 +++-- gradio/tunneling.py | 22 +++++++++++++--------- screenshots/.image_interface.png.icloud | Bin 0 -> 171 bytes web/img/.cheetah-clean.png.icloud | Bin 0 -> 169 bytes 8 files changed, 37 insertions(+), 29 deletions(-) create mode 100644 screenshots/.image_interface.png.icloud create mode 100644 web/img/.cheetah-clean.png.icloud diff --git a/build-interface.py b/build-interface.py index c2376def13..d53695fa21 100644 --- a/build-interface.py +++ b/build-interface.py @@ -32,7 +32,7 @@ def launch_interface(args): pass def service_shutdown(signum, frame): - print('Shutting server down due to signal %d' % signum) + print('Shutting server down due to signal {}'.format(signum)) httpd.shutdown() raise ServiceExit diff --git a/gradio/inputs.py b/gradio/inputs.py index baaf7700b0..be173e7a6f 100644 --- a/gradio/inputs.py +++ b/gradio/inputs.py @@ -125,8 +125,8 @@ class Sketchpad(AbstractInput): im = preprocessing_utils.decode_base64_to_image(msg) timestamp = time.time()*1000 - filename = f'input_{timestamp}.png' - im.save(f'{dir}/{filename}', 'PNG') + filename = 'input_{}.png'.format(timestamp) + im.save('{}/{}'.format(dir, filename), 'PNG') return filename def get_sample_inputs(self): @@ -171,8 +171,8 @@ class Webcam(AbstractInput): inp = msg['data']['input'] im = preprocessing_utils.decode_base64_to_image(inp) timestamp = time.time()*1000 - filename = f'input_{timestamp}.png' - im.save(f'{dir}/{filename}', 'PNG') + filename = 'input_{}.png'.format(timestamp) + im.save('{}/{}'.format(dir, filename), 'PNG') return filename @@ -198,8 +198,8 @@ class Textbox(AbstractInput): Default rebuild method for text saves it .txt file """ timestamp = time.time()*1000 - filename = f'input_{timestamp}' - with open(f'{dir}/{filename}.txt','w') as f: + filename = 'input_{}'.format(timestamp) + with open('{}/{}.txt'.format(dir, filename),'w') as f: f.write(msg) return filename @@ -252,8 +252,8 @@ class ImageUpload(AbstractInput): """ im = preprocessing_utils.decode_base64_to_image(msg) timestamp = time.time()*1000 - filename = f'input_{timestamp}.png' - im.save(f'{dir}/{filename}', 'PNG') + filename = 'input_{}.png'.format(timestamp) + im.save('{}/{}'.format(dir, filename), 'PNG') return filename # TODO(abidlabs): clean this up @@ -261,8 +261,8 @@ class ImageUpload(AbstractInput): """ """ timestamp = time.time()*1000 - filename = f'input_{timestamp}.png' - img.save(f'{dir}/{filename}', 'PNG') + filename = 'input_{}.png'.format(timestamp) + img.save('{}/{}'.format(dir, filename), 'PNG') return filename diff --git a/gradio/interface.py b/gradio/interface.py index 6fbd4be638..1a6d7aa469 100644 --- a/gradio/interface.py +++ b/gradio/interface.py @@ -191,7 +191,7 @@ class Interface: for m, msg in enumerate(validation_inputs): if self.verbose: print( - f"Validating samples: {m+1}/{n} [" + "Validating samples: {}/{} [".format(m+1, n) + "=" * (m + 1) + "." * (n - m - 1) + "]", @@ -272,9 +272,10 @@ class Interface: current_pkg_version = pkg_resources.require("gradio")[0].version latest_pkg_version = requests.get(url=PKG_VERSION_URL).json()["version"] if StrictVersion(latest_pkg_version) > StrictVersion(current_pkg_version): - print(f"IMPORTANT: You are using gradio version {current_pkg_version}, " - f"however version {latest_pkg_version} " - f"is available, please upgrade.") + print("IMPORTANT: You are using gradio version {}, " + "however version {} " + "is available, please upgrade.".format( + current_pkg_version, latest_pkg_version)) print('--------') except: # TODO(abidlabs): don't catch all exceptions pass diff --git a/gradio/networking.py b/gradio/networking.py index 3a25636e63..efd4ffb207 100644 --- a/gradio/networking.py +++ b/gradio/networking.py @@ -254,7 +254,8 @@ def serve_files_in_background(interface, port, directory_to_serve=None): output = {'input': interface.input_interface.save_to_file(flag_dir, img), 'output': interface.output_interface.rebuild_flagged( flag_dir, {'data': {'output': processed_output}}), - 'message': f'rotation by {deg} degrees'} + 'message': 'rotation by {} degrees'.format( + deg)} with open(os.path.join(flag_dir, FLAGGING_FILENAME), 'a+') as f: f.write(json.dumps(output)) @@ -287,7 +288,8 @@ def serve_files_in_background(interface, port, directory_to_serve=None): output = {'input': interface.input_interface.save_to_file(flag_dir, img), 'output': interface.output_interface.rebuild_flagged( flag_dir, {'data': {'output': processed_output}}), - 'message': f'brighting adjustment by a factor of {i}'} + 'message': 'brighting adjustment by a factor ' + 'of {}'.format(i)} with open(os.path.join(flag_dir, FLAGGING_FILENAME), 'a+') as f: f.write(json.dumps(output)) @@ -297,7 +299,7 @@ def serve_files_in_background(interface, port, directory_to_serve=None): self.wfile.write(json.dumps({}).encode()) else: - self.send_error(404, 'Path not found: %s' % self.path) + self.send_error(404, 'Path not found: {}'.format(self.path)) class HTTPServer(BaseHTTPServer): """The main server, you pass in base_path which is the path you want to serve requests from""" diff --git a/gradio/outputs.py b/gradio/outputs.py index 1a495e3207..a249dc376e 100644 --- a/gradio/outputs.py +++ b/gradio/outputs.py @@ -159,8 +159,9 @@ class Image(AbstractOutput): """ im = preprocessing_utils.decode_base64_to_image(msg) timestamp = datetime.datetime.now() - filename = f'output_{timestamp.strftime("%Y-%m-%d-%H-%M-%S")}.png' - im.save(f'{dir}/{filename}', 'PNG') + filename = 'output_{}.png'.format(timestamp. + strftime("%Y-%m-%d-%H-%M-%S")) + im.save('{}/{}'.format(dir, filename), 'PNG') return filename diff --git a/gradio/tunneling.py b/gradio/tunneling.py index 990eee3d0b..45122c484a 100644 --- a/gradio/tunneling.py +++ b/gradio/tunneling.py @@ -19,12 +19,13 @@ def handler(chan, host, port): try: sock.connect((host, port)) except Exception as e: - verbose("Forwarding request to %s:%d failed: %r" % (host, port, e)) + verbose("Forwarding request to {}:{} failed: {}".format(host, port, e)) return verbose( - "Connected! Tunnel open %r -> %r -> %r" - % (chan.origin_addr, chan.getpeername(), (host, port)) + "Connected! Tunnel open {} -> {} -> {}".format(chan.origin_addr, + chan.getpeername(), + (host, port)) ) while True: r, w, x = select.select([sock, chan], [], []) @@ -40,7 +41,7 @@ def handler(chan, host, port): sock.send(data) chan.close() sock.close() - verbose("Tunnel closed from %r" % (chan.origin_addr,)) + verbose("Tunnel closed from {}".format(chan.origin_addr,)) def reverse_forward_tunnel(server_port, remote_host, remote_port, transport): @@ -65,7 +66,8 @@ def create_tunnel(payload, local_server, local_server_port): client.set_missing_host_key_policy(paramiko.WarningPolicy()) verbose( - "Connecting to ssh host %s:%d ..." % (payload["host"], int(payload["port"])) + "Connecting to ssh host {}:{} ...".format(payload["host"], int(payload[ + "port"])) ) try: with warnings.catch_warnings(): @@ -78,14 +80,16 @@ def create_tunnel(payload, local_server, local_server_port): ) except Exception as e: print( - "*** Failed to connect to %s:%d: %r" - % (payload["host"], int(payload["port"]), e) + "*** Failed to connect to {}:{}: {}}".format(payload["host"], + int(payload["port"]), e) ) sys.exit(1) verbose( - "Now forwarding remote port %d to %s:%d ..." - % (int(payload["remote_port"]), local_server, local_server_port) + "Now forwarding remote port {} to {}:{} ...".format(int(payload[ + "remote_port"]), + local_server, + local_server_port) ) thread = threading.Thread( diff --git a/screenshots/.image_interface.png.icloud b/screenshots/.image_interface.png.icloud new file mode 100644 index 0000000000000000000000000000000000000000..4f5ecae07b73d2b00f2850963ee03527f6639109 GIT binary patch literal 171 zcmYc)$jK}&F)+By$i&RT$`<1n92(@~mzbOComv?$AOPmNW#*&?XI4RkB;Z0psm1xF zMaiill?4zf;mq8`^wjvwypq(Sw8Z38y@I@SAqFL7w|D^=th$0y(@S#_i#YgY^t}>N R8Nh&%5kfPtLunY*0ss{3E_46@ literal 0 HcmV?d00001 diff --git a/web/img/.cheetah-clean.png.icloud b/web/img/.cheetah-clean.png.icloud new file mode 100644 index 0000000000000000000000000000000000000000..54e3e47420f3e193e1bb45460683d0f13fa5bbc0 GIT binary patch literal 169 zcmYc)$jK}&F)+By$i&RT$`<1n92(@~mzbOComv?$AOPmNW#*&?XI4RkB;Z0psm1xF zMaiill?4zf!Q_n8)RM#u-Q=9q#5}!%ymTQ3C1tmG0U4}%f>P5 Date: Thu, 11 Jun 2020 00:16:50 -0700 Subject: [PATCH 2/5] imdb demo with saliency --- demo/sentiment-analysis.py | 177 +++++++++++++++++++++++++++++++++ examples/__init__.py | 0 examples/imdb_saliency_only.py | 124 ----------------------- examples/imdb_utils.py | 52 ++++++++++ gradio/interface.py | 5 +- gradio/networking.py | 3 +- gradio/outputs.py | 2 +- 7 files changed, 234 insertions(+), 129 deletions(-) create mode 100644 demo/sentiment-analysis.py create mode 100644 examples/__init__.py delete mode 100644 examples/imdb_saliency_only.py create mode 100644 examples/imdb_utils.py diff --git a/demo/sentiment-analysis.py b/demo/sentiment-analysis.py new file mode 100644 index 0000000000..2ba0b59cc9 --- /dev/null +++ b/demo/sentiment-analysis.py @@ -0,0 +1,177 @@ +#!/usr/bin/env python +# coding: utf-8 + +# In[9]: + + +import tensorflow as tf +import sys +import gradio +from tensorflow.keras.layers import * +from tensorflow.keras.datasets import imdb +import json +from tensorflow.keras import backend as K +import numpy as np + + +# In[2]: + + +top_words = 5000 # Only keep the 5,000 most frequent words +max_word_length = 500 # The maximum length of the review should be 500 words (trim/pad otherwise) + +# (X_train, y_train), (X_test, y_test) = imdb.load_data(num_words=top_words); +# # save np.load +np_load_old = np.load +np.load = lambda *a,**k: np_load_old(*a, allow_pickle=True, **k) + +# # # call load_data with allow_pickle implicitly set to true +(X_train, y_train), (X_test, y_test) = imdb.load_data(num_words=top_words); + +# # restore np.load for future normal usage +np.load = np_load_old + +X_train = tf.keras.preprocessing.sequence.pad_sequences(X_train, maxlen=max_word_length) +X_test = tf.keras.preprocessing.sequence.pad_sequences(X_test, maxlen=max_word_length) + + +def get_trained_model(n): + model = tf.keras.models.Sequential() + model.add(Embedding(top_words, 32, input_length=max_word_length)) + model.add(Dropout(0.2)) + model.add(Conv1D(250, 3, padding='valid', activation='relu', strides=1)) + model.add(GlobalMaxPooling1D()) + model.add(Dense(250)) + model.add(Dropout(0.2)) + model.add(Activation('relu')) + model.add(Dense(1)) + model.add(Activation('sigmoid')) + model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy']) + model.fit(X_train[:n], y_train[:n], epochs=1, batch_size=128) + print(model.evaluate(X_test[:n], y_test[:n])) + return model + + +# In[3]: + + +model = get_trained_model(n=1000) #25000 + + +# In[4]: + + +graph = tf.get_default_graph() +sess = tf.keras.backend.get_session() + + +# In[5]: + + +NUM_SPECIAL_TOKENS = 3 +PAD_TOKEN = 0 +START_TOKEN = 1 +UNK_TOKEN = 2 + +word_to_id = tf.keras.datasets.imdb.get_word_index() +word_to_id = {k: (v + NUM_SPECIAL_TOKENS) for k, v in word_to_id.items()} + +id_to_word = {value: key for key, value in word_to_id.items()} +id_to_word[PAD_TOKEN] = "" # Padding tokens are converted to empty strings. +id_to_word[START_TOKEN] = "" # Start tokens are converted to empty strings. +id_to_word[UNK_TOKEN] = "UNK" # tokens are converted to "UNK". + + +def decode_vector_to_text(vector): + text = " ".join(id_to_word[id] for id in vector if id >= 2) + return text + + +def encode_text_to_vector(text, max_word_length=500, top_words=5000): + text_vector = text.split(" ") + encoded_vector = [ + word_to_id.get(element, UNK_TOKEN) if word_to_id.get(element, UNK_TOKEN) < top_words else UNK_TOKEN for element + in text_vector] + encoded_vector = [START_TOKEN] + encoded_vector + if len(encoded_vector) < max_word_length: + encoded_vector = (max_word_length - len(encoded_vector)) * [PAD_TOKEN] + encoded_vector + else: + encoded_vector = encoded_vector[:max_word_length] + return encoded_vector + + +def preprocessing(text): + new = encode_text_to_vector(text) + return tf.keras.preprocessing.sequence.pad_sequences([new], maxlen=max_word_length) + + +def postprocessing(pred): + return { + "Positive review": f"{pred[0][0]}", + "Negative review": f"{1-pred[0][0]}" + } + +def predict(inp): + inp = preprocessing(inp) + with graph.as_default(): + with sess.as_default(): + prediction = model.predict(inp) + prediction = postprocessing(prediction) + return prediction + + +def saliency(input, output): + with graph.as_default(): + with sess.as_default(): + processed_input = preprocessing(input) + processed_output = output + + output = 0 if float(output["Positive review"]) > 0.5 else 1 + input_tensors = [model.layers[0].input, K.learning_phase()] + saliency_input = model.layers[1].input + saliency_output = model.layers[-1].output[:, output] + gradients = model.optimizer.get_gradients(saliency_output, saliency_input) + compute_gradients = K.function(inputs=input_tensors, outputs=gradients) + saliency_graph = compute_gradients(processed_input.reshape(1, 500))[0] + + saliency_graph = saliency_graph.reshape(500, 32) + + saliency_graph = np.abs(saliency_graph).sum(axis=1) + normalized_saliency = (saliency_graph - saliency_graph.min()) / (saliency_graph.max() - saliency_graph.min()) + + start_idx = np.where(processed_input[0] == START_TOKEN)[0][0] + heat_map = [] + counter = 0 + words = input.split(" ") + for i in range(start_idx + 1, 500): + heat_map.extend([normalized_saliency[i]] * len(words[counter])) + heat_map.append(0) # zero saliency value assigned to the spaces between words + counter += 1 + return np.array(heat_map) + + +# In[6]: + + +textbox = gradio.inputs.Textbox() +label = gradio.outputs.Label() +interface = gradio.Interface(inputs=textbox, outputs=label, fn=predict, saliency=saliency) + + +# In[8]: + + +interface.launch(inbrowser=True, share=False) + + +# In[ ]: + + + + + +# In[ ]: + + + + diff --git a/examples/__init__.py b/examples/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/examples/imdb_saliency_only.py b/examples/imdb_saliency_only.py deleted file mode 100644 index 33debc5ea6..0000000000 --- a/examples/imdb_saliency_only.py +++ /dev/null @@ -1,124 +0,0 @@ -import tensorflow as tf -import sys -sys.path.insert(1, '../gradio') -import gradio -from tensorflow.keras.layers import * -from tensorflow.keras.datasets import imdb -import json -from tensorflow.keras import backend as K -import numpy as np - - -top_words = 5000 # Only keep the 5,000 most frequent words -max_word_length = 500 # The maximum length of the review should be 500 words (trim/pad otherwise) - -(X_train, y_train), (X_test, y_test) = imdb.load_data(num_words=top_words); -X_train = tf.keras.preprocessing.sequence.pad_sequences(X_train, maxlen=max_word_length) -X_test = tf.keras.preprocessing.sequence.pad_sequences(X_test, maxlen=max_word_length) - - -def get_trained_model(n): - model = tf.keras.models.Sequential() - model.add(Embedding(top_words, 32, input_length=max_word_length)) - model.add(Dropout(0.2)) - model.add(Conv1D(250, 3, padding='valid', activation='relu', strides=1)) - model.add(GlobalMaxPooling1D()) - model.add(Dense(250)) - model.add(Dropout(0.2)) - model.add(Activation('relu')) - model.add(Dense(1)) - model.add(Activation('sigmoid')) - model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy']) - model.fit(X_train[:n], y_train[:n], epochs=2, batch_size=128) - print(model.evaluate(X_test, y_test)) - return model - - -model = get_trained_model(n=25000) - -# Gradio code # -NUM_SPECIAL_TOKENS = 3 -PAD_TOKEN = 0 -START_TOKEN = 1 -UNK_TOKEN = 2 - -word_to_id = tf.keras.datasets.imdb.get_word_index() -word_to_id = {k: (v + NUM_SPECIAL_TOKENS) for k, v in word_to_id.items()} - -id_to_word = {value: key for key, value in word_to_id.items()} -id_to_word[PAD_TOKEN] = "" # Padding tokens are converted to empty strings. -id_to_word[START_TOKEN] = "" # Start tokens are converted to empty strings. -id_to_word[UNK_TOKEN] = "UNK" # tokens are converted to "UNK". - - -def decode_vector_to_text(vector): - text = " ".join(id_to_word[id] for id in vector if id >= 2) - return text - - -def encode_text_to_vector(text, max_word_length=500, top_words=5000): - text_vector = text.split(" ") - encoded_vector = [ - word_to_id.get(element, UNK_TOKEN) if word_to_id.get(element, UNK_TOKEN) < top_words else UNK_TOKEN for element - in text_vector] - encoded_vector = [START_TOKEN] + encoded_vector - if len(encoded_vector) < max_word_length: - encoded_vector = (max_word_length - len(encoded_vector)) * [PAD_TOKEN] + encoded_vector - else: - encoded_vector = encoded_vector[:max_word_length] - return encoded_vector - - -def preprocessing(text): - new = encode_text_to_vector(text) - return tf.keras.preprocessing.sequence.pad_sequences([new], maxlen=max_word_length) - - -def postprocessing(pred): - if pred[0][0] > 0.5: - return json.dumps({"label": "Positive review"}) - else: - return json.dumps({"label": "Negative review"}) - - -def saliency(interface, model, input, processed_input, output, processed_output): - with interface.graph.as_default(): - with interface.sess.as_default(): - output = output.argmax() - input_tensors = [model.layers[0].input, K.learning_phase()] - saliency_input = model.layers[1].input - saliency_output = model.layers[-1].output[:, output] - gradients = model.optimizer.get_gradients(saliency_output, saliency_input) - compute_gradients = K.function(inputs=input_tensors, outputs=gradients) - saliency_graph = compute_gradients(processed_input.reshape(1, 500))[0] - - saliency_graph = saliency_graph.reshape(500, 32) - - saliency_graph = np.abs(saliency_graph).sum(axis=1) - normalized_saliency = (saliency_graph - saliency_graph.min()) / \ - (saliency_graph.max() - saliency_graph.min()) - - start_idx = np.where(processed_input[0] == START_TOKEN)[0][0] - heat_map = [] - counter = 0 - words = input.split(" ") - for i in range(start_idx + 1, 500): - heat_map.extend([normalized_saliency[i]] * len(words[counter])) - heat_map.append(0) # zero saliency value assigned to the spaces between words - counter += 1 - return np.array(heat_map) - - -textbox = gradio.inputs.Textbox(preprocessing_fn=preprocessing, - sample_inputs=[ - "A wonderful little production. The filming technique is very unassuming- very old-time-BBC fashion and gives a comforting, and sometimes discomforting, sense of realism to the entire piece. The actors are extremely well chosen- Michael Sheen not only has got all the polari but he has all the voices down pat too! You can truly see the seamless editing guided by the references to Williams' diary entries, not only is it well worth the watching but it is a terrificly written and performed piece. A masterful production about one of the great master's of comedy and his life. The realism really comes home with the little things: the fantasy of the guard which, rather than use the traditional 'dream' techniques remains solid then disappears.", - "This was a very brief episode that appeared in one of the Night Gallery show back in 1971. The episode starred Sue Lyon (of Lolita movie fame) and Joseph Campanella who play a baby sitter and a vampire, respectively. The vampire hires a baby sitter to watch his child (which appears to be some kind of werewolf or monster) while he goes out at night for blood. I don't know what purpose it was to make such an abbreviated episode that lasted just 5 minutes. They should just have expanded the earlier episode by those same 5 minutes and skipped this one. A total wasted effort.", - "No one expects the Star Trek movies to be high art, but the fans do expect a movie that is as good as some of the best episodes. Unfortunately, this movie had a muddled, implausible plot that just left me cringing - this is by far the worst of the nine (so far) movies. Even the chance to watch the well known characters interact in another movie can't save this movie - including the goofy scenes with Kirk, Spock and McCoy at Yosemite.I would say this movie is not worth a rental, and hardly worth watching, however for the True Fan who needs to see all the movies, renting this movie is about the only way you'll see it - even the cable channels avoid this movie.", - "This movie started out cringe-worthy--but it was meant to, with an overbearing mother, a witch of a rival, and a hesitant beauty queen constantly coming in second. There was some goofy overacting, and a few implausible plot points (She comes in second in EVERY single competition? ALL of them?) Unfortunately, the movie suffers horribly from it's need to, well, be a TV movie. Rather than end at the ending of the movie, an amusing twist in which the killer is (semi-plausibly) revealed, the movie continues for another twenty minutes, just to make sure that justice is done. Of course, now that the killer is revealed, she suddenly undergoes a complete personality shift--her character gets completely rewritten, because the writers don't need to keep her identity secret any more. The cheese completely sinks what otherwise could have been a passably amusing movie.", - "I thought this movie did a down right good job. It wasn't as creative or original as the first, but who was expecting it to be. It was a whole lotta fun. the more i think about it the more i like it, and when it comes out on DVD I'm going to pay the money for it very proudly, every last cent. Sharon Stone is great, she always is, even if her movie is horrible(Catwoman), but this movie isn't, this is one of those movies that will be underrated for its lifetime, and it will probably become a classic in like 20 yrs. Don't wait for it to be a classic, watch it now and enjoy it. Don't expect a masterpiece, or something thats gripping and soul touching, just allow yourself to get out of your life and get yourself involved in theirs.All in all, this movie is entertaining and i recommend people who haven't seen it see it.", - "I rented this movie, but I wasn't too sure what to expect of it. I was very glad to find that it's about the best Brazilian movie I've ever seen. The story is rather odd and simple, and above all, extremely original. We have Antonio, who is a young man living in Nordestina, a town in the middle of nowhere in the north east of Brazil, and who is deeply in love with Karina. The main conflict between the two is that, while Antonio loves his little town and has no wish to leave it, Karina wants to see the world and resents the place. As a prove of his love for her, he decides to go out himself and bring the world to her. He'll put Nordestina in the map, as he says. And the way he does it is unbelievable. This is a good movie; might be a bit stagy for some people due to its different editing job, but I think that it's also that that improves the story. It's just fun, and it makes you feel good."]) -label = gradio.outputs.Label(postprocessing_fn=postprocessing) -io = gradio.Interface(inputs=textbox, outputs=label, model_type="keras", model=model, saliency=saliency, always_flag=True, interactivity_disabled=True) -httpd, path_to_local_server, share_url = io.launch(share=True, inbrowser=True, inline=False) - -print("URL for IMDB model interface: ", share_url) diff --git a/examples/imdb_utils.py b/examples/imdb_utils.py new file mode 100644 index 0000000000..561700c868 --- /dev/null +++ b/examples/imdb_utils.py @@ -0,0 +1,52 @@ +import tensorflow as tf +from tensorflow.keras.layers import * +from tensorflow.keras.datasets import imdb +import json +import numpy as np + +top_words = 5000 # Only keep the 5,000 most frequent words +max_word_length = 500 # The maximum length of the review should be 500 words (trim/pad otherwise) + + +NUM_SPECIAL_TOKENS = 3 +PAD_TOKEN = 0 +START_TOKEN = 1 +UNK_TOKEN = 2 + +word_to_id = tf.keras.datasets.imdb.get_word_index() +word_to_id = {k: (v + NUM_SPECIAL_TOKENS) for k, v in word_to_id.items()} + +id_to_word = {value: key for key, value in word_to_id.items()} +id_to_word[PAD_TOKEN] = "" # Padding tokens are converted to empty strings. +id_to_word[START_TOKEN] = "" # Start tokens are converted to empty strings. +id_to_word[UNK_TOKEN] = "UNK" # tokens are converted to "UNK". + + +def decode_vector_to_text(vector): + text = " ".join(id_to_word[id] for id in vector if id >= 2) + return text + + +def encode_text_to_vector(text, max_word_length=500, top_words=5000): + text_vector = text.split(" ") + encoded_vector = [ + word_to_id.get(element, UNK_TOKEN) if word_to_id.get(element, UNK_TOKEN) < top_words else UNK_TOKEN for element + in text_vector] + encoded_vector = [START_TOKEN] + encoded_vector + if len(encoded_vector) < max_word_length: + encoded_vector = (max_word_length - len(encoded_vector)) * [PAD_TOKEN] + encoded_vector + else: + encoded_vector = encoded_vector[:max_word_length] + return encoded_vector + + +def preprocessing(text): + new = encode_text_to_vector(text) + return tf.keras.preprocessing.sequence.pad_sequences([new], maxlen=max_word_length) + + +def postprocessing(pred): + return { + "Positive review": f"{pred[0][0]}", + "Negative review": f"{1-pred[0][0]}" + } diff --git a/gradio/interface.py b/gradio/interface.py index 5ba8e191ff..b9f0582f3a 100644 --- a/gradio/interface.py +++ b/gradio/interface.py @@ -28,7 +28,8 @@ class Interface: the appropriate inputs and outputs """ - def __init__(self, fn, inputs, outputs, verbose=False, live=False): + def __init__(self, fn, inputs, outputs, saliency=None, verbose=False, \ + live=False): """ :param fn: a function that will process the input panel data from the interface and return the output panel data. :param inputs: a string or `AbstractInput` representing the input interface. @@ -51,7 +52,7 @@ class Interface: self.predict = fn self.verbose = verbose self.status = "OFF" - self.saliency = None + self.saliency = saliency self.live = live diff --git a/gradio/networking.py b/gradio/networking.py index fd2c8973ca..366c84448d 100644 --- a/gradio/networking.py +++ b/gradio/networking.py @@ -156,8 +156,7 @@ def serve_files_in_background(interface, port, directory_to_serve=None): processed_output = interface.output_interface.postprocess(prediction) output = {"action": "output", "data": processed_output} if interface.saliency is not None: - import numpy as np - saliency = interface.saliency(interface, interface.model_obj, raw_input, processed_input, prediction, processed_output) + saliency = interface.saliency(raw_input, prediction) output['saliency'] = saliency.tolist() # if interface.always_flag: # msg = json.loads(data_string) diff --git a/gradio/outputs.py b/gradio/outputs.py index 3c912c39f6..0552096597 100644 --- a/gradio/outputs.py +++ b/gradio/outputs.py @@ -7,7 +7,7 @@ automatically added to a registry, which allows them to be easily referenced in from abc import ABC, abstractmethod import numpy as np import json -from gradio import imagenet_class_labels, preprocessing_utils +from gradio import preprocessing_utils import datetime # Where to find the static resources associated with each template. From a4f865b209db08d4a3f967c269fef4d49144fe16 Mon Sep 17 00:00:00 2001 From: aliabd Date: Thu, 11 Jun 2020 01:08:27 -0700 Subject: [PATCH 3/5] gpt-2 demo --- demo/GPT-2-Demo.py | 48 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 demo/GPT-2-Demo.py diff --git a/demo/GPT-2-Demo.py b/demo/GPT-2-Demo.py new file mode 100644 index 0000000000..a2de3493e5 --- /dev/null +++ b/demo/GPT-2-Demo.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python +# coding: utf-8 + +# In[2]: + + +# installing transformers +# !pip install -q git+https://github.com/huggingface/transformers.git +# !pip install -q tensorflow==2.1 + + +# In[12]: + + +import tensorflow as tf +from transformers import TFGPT2LMHeadModel, GPT2Tokenizer +import gradio + + +# In[4]: + + +tokenizer = GPT2Tokenizer.from_pretrained("gpt2") + +# add the EOS token as PAD token to avoid warnings +model = TFGPT2LMHeadModel.from_pretrained("gpt2", pad_token_id=tokenizer.eos_token_id) + + +# In[15]: + + +def predict(inp): + input_ids = tokenizer.encode(inp, return_tensors='tf') + beam_output = model.generate(input_ids, max_length=49, num_beams=5, no_repeat_ngram_size=2, early_stopping=True) + return tokenizer.decode(beam_output[0], skip_special_tokens=True, clean_up_tokenization_spaces=True) + + +# In[18]: + + +gradio.Interface(predict,"textbox","textbox").launch(inbrowser=True) + + +# In[ ]: + + + + From e017a23225a6127b3618b85f502af29f09a7a411 Mon Sep 17 00:00:00 2001 From: aliabd Date: Thu, 11 Jun 2020 02:21:12 -0700 Subject: [PATCH 4/5] flagging fixes --- gradio/inputs.py | 20 ++++++++------------ gradio/interface.py | 2 +- gradio/networking.py | 16 ++++++++++++---- static/flagged/1617829583/data.txt | 2 ++ 4 files changed, 23 insertions(+), 17 deletions(-) create mode 100644 static/flagged/1617829583/data.txt diff --git a/gradio/inputs.py b/gradio/inputs.py index 05a7561275..87a59089d0 100644 --- a/gradio/inputs.py +++ b/gradio/inputs.py @@ -11,7 +11,7 @@ from PIL import Image, ImageOps import time import warnings import json - +import datetime # Where to find the static resources associated with each template. # BASE_INPUT_INTERFACE_TEMPLATE_PATH = 'static/js/interfaces/input/{}.js' @@ -113,8 +113,8 @@ class Sketchpad(AbstractInput): """ im = preprocessing_utils.decode_base64_to_image(msg) - timestamp = time.time()*1000 - filename = f'input_{timestamp}.png' + timestamp = datetime.datetime.now() + filename = f'input_{timestamp.strftime("%Y-%m-%d-%H-%M-%S")}.png' im.save(f'{dir}/{filename}', 'PNG') return filename @@ -159,8 +159,8 @@ class Webcam(AbstractInput): """ inp = msg['data']['input'] im = preprocessing_utils.decode_base64_to_image(inp) - timestamp = time.time()*1000 - filename = f'input_{timestamp}.png' + timestamp = datetime.datetime.now() + filename = f'input_{timestamp.strftime("%Y-%m-%d-%H-%M-%S")}.png' im.save(f'{dir}/{filename}', 'PNG') return filename @@ -186,11 +186,7 @@ class Textbox(AbstractInput): """ Default rebuild method for text saves it .txt file """ - timestamp = time.time()*1000 - filename = f'input_{timestamp}' - with open(f'{dir}/{filename}.txt','w') as f: - f.write(msg) - return filename + return json.loads(msg) def get_sample_inputs(self): return self.sample_inputs @@ -240,8 +236,8 @@ class ImageIn(AbstractInput): Default rebuild method to decode a base64 image """ im = preprocessing_utils.decode_base64_to_image(msg) - timestamp = time.time()*1000 - filename = f'input_{timestamp}.png' + timestamp = datetime.datetime.now() + filename = f'input_{timestamp.strftime("%Y-%m-%d-%H-%M-%S")}.png' im.save(f'{dir}/{filename}', 'PNG') return filename diff --git a/gradio/interface.py b/gradio/interface.py index ee7a46077c..705b3f4671 100644 --- a/gradio/interface.py +++ b/gradio/interface.py @@ -66,7 +66,7 @@ class Interface: self.live = live self.show_input = show_input self.show_output = show_output - + self.flag_hash = random.getrandbits(32) def update_config_file(self, output_directory): config = { diff --git a/gradio/networking.py b/gradio/networking.py index efab2effbc..d163aef95d 100644 --- a/gradio/networking.py +++ b/gradio/networking.py @@ -163,11 +163,19 @@ def serve_files_in_background(interface, port, directory_to_serve=None): self._set_headers() data_string = self.rfile.read(int(self.headers["Content-Length"])) msg = json.loads(data_string) - flag_dir = os.path.join(FLAGGING_DIRECTORY, str(interface.hash)) - os.makedirs(FLAGGING_DIRECTORY, exist_ok=True) - output = {'input': interface.input_interface.rebuild_flagged(flag_dir, msg['data']['input_data']), - 'output': interface.output_interface.rebuild_flagged(flag_dir, msg['data']['output_data']), + flag_dir = os.path.join(FLAGGING_DIRECTORY, + str(interface.flag_hash)) + os.makedirs(flag_dir, exist_ok=True) + output = {'inputs': [interface.input_interfaces[ + i].rebuild_flagged( + flag_dir, msg['data']['input_data']) for i + in range(len(interface.input_interfaces))], + 'outputs': [interface.output_interfaces[ + i].rebuild_flagged( + flag_dir, msg['data']['output_data']) for i + in range(len(interface.output_interfaces))], 'message': msg['data']['message']} + with open(os.path.join(flag_dir, FLAGGING_FILENAME), 'a+') as f: f.write(json.dumps(output)) f.write("\n") diff --git a/static/flagged/1617829583/data.txt b/static/flagged/1617829583/data.txt new file mode 100644 index 0000000000..54b39816a3 --- /dev/null +++ b/static/flagged/1617829583/data.txt @@ -0,0 +1,2 @@ +{"inputs": [["It was all a dream. I used to read word up magazine. "]], "outputs": [["It was all a dream. I used to read word up magazine. It was like, \"Oh my God, this is going to be a big deal.\" And then I read it and I thought, Oh my god, I can't believe I'm reading this.\n\nSo I went back and read the book, and it was a really good book. And I think it's one of the best books I've read in a long time."]], "message": "Biggie smalls"} +{"inputs": [["I went to Sudan last week and "]], "outputs": [["I went to Sudan last week and met with the president of the Sudanese government,\" he said.\n\n\"He told me that he was going to send a delegation to the United Nations to discuss the situation in Sudan, and I told him that I would be happy to meet with him."]], "message": "Sudan"} From 5314f54c79acff9dca3f48b9d106b1335b910a93 Mon Sep 17 00:00:00 2001 From: aliabd Date: Thu, 11 Jun 2020 02:24:48 -0700 Subject: [PATCH 5/5] gpt fix --- demo/GPT-2-Demo.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/demo/GPT-2-Demo.py b/demo/GPT-2-Demo.py index a2de3493e5..2203452166 100644 --- a/demo/GPT-2-Demo.py +++ b/demo/GPT-2-Demo.py @@ -32,8 +32,8 @@ model = TFGPT2LMHeadModel.from_pretrained("gpt2", pad_token_id=tokenizer.eos_tok def predict(inp): input_ids = tokenizer.encode(inp, return_tensors='tf') beam_output = model.generate(input_ids, max_length=49, num_beams=5, no_repeat_ngram_size=2, early_stopping=True) - return tokenizer.decode(beam_output[0], skip_special_tokens=True, clean_up_tokenization_spaces=True) - + output = tokenizer.decode(beam_output[0], skip_special_tokens=True, clean_up_tokenization_spaces=True) + return ".".join(output.split(".")[:-1]) + "." # In[18]: