NicolasVana/image-captioning
2
1import json2import os, shutil3import random4import streamlit as st5import os6from pathlib import Path7import numpy as np8 9from PIL import Image10import tensorflow as tf11from tensorflow.keras.applications.inception_v3 import preprocess_input12from tensorflow.keras.preprocessing import image13from tensorflow.keras.applications.inception_v3 import InceptionV314from tensorflow.keras.models import Model15from tensorflow.keras.preprocessing.sequence import pad_sequences16 17 18 19root = Path(os.getcwd())20aux_pre = root / 'Inception' / 'PretrainedInceptionLSTM'21aux_re = root / 'Inception' / 'RetrainedInceptionLSTM'22 23model_re_path = root / 'Inception' / 'RetrainedInceptionLSTM' / 'Model'24model_inception_path = root / 'Inception' / 'RetrainedInceptionFeatureExtraction' / 'Model'25model_pre_path = root / 'Inception' / 'PretrainedInceptionLSTM' / 'Model'26 27# Must create28 29def get_pretrained_inceptionV3():30 model = InceptionV3(weights='imagenet')31 model2 = Model(model.input, model.layers[-2].output)32 return model233 34def fetch_auxiliary_files(type):35 if type == 'Pretrained Inception':36 word2Index = np.load(aux_pre / "word2Index.npy", allow_pickle=True).item()37 index2Word = np.load(aux_pre / "index2Word.npy", allow_pickle=True).item()38 variable_params = np.load(aux_pre / "variable_params.npy", allow_pickle=True).item()39 return word2Index, index2Word, variable_params40 if type == 'Retrained Inception':41 word2Index = np.load(aux_re / "word2Index.npy", allow_pickle=True).item()42 index2Word = np.load(aux_re / "index2Word.npy", allow_pickle=True).item()43 variable_params = np.load(aux_re / "variable_params.npy", allow_pickle=True).item()44 return word2Index, index2Word, variable_params45 46@st.cache(allow_output_mutation=True, show_spinner=False)47def fetch_model(type):48 with st.spinner(text="Fetching Model"):49 if type == 'Pretrained Inception':50 model_pre = tf.keras.models.load_model(model_pre_path)51 model_inc = get_pretrained_inceptionV3()52 return model_inc, model_pre53 if type == 'Retrained Inception':54 model_re = tf.keras.models.load_model(model_re_path)55 model_inc = tf.keras.models.load_model(model_inception_path)56 return model_inc, model_re57 58def preprocess_image_inception(image):59 if image.mode != "RGB":60 image = image.convert(mode="RGB")61 62 x = np.array(image)63 x = np.expand_dims(x, axis = 0)64 x = preprocess_input(x)65 x = x.reshape(1, 299, 299, 3)66 67 return x68 69def extract_features(model, image):70 features = model.predict(image, verbose = 0)71 return features72 73def generate_caption(model, features, max_len, word2Index, index2Word, beam_index = 3):74 caption = beam_search(model, features, max_len, word2Index, index2Word, beam_index)75 return caption76 77def beam_search(model, features, max_len, word2Index, index2Word, beam_index):78 start = [word2Index["startseq"]]79 start_word = [[start, 1]]80 81 final_preds = []82 live_seqs = beam_index83 features = np.tile(features, (beam_index,1))84 count = 085 while len(start_word) > 0:86 #print(count)87 count+=188 temp = []89 padded_seqs = []90 #Get padded seqs for each of the starting seqs so far, misnamed as start_word91 for s in start_word:92 par_caps = pad_sequences([s[0]], maxlen=max_len, padding='post')93 padded_seqs.append(par_caps)94 95 #Formatting input so that it can be used for a prediction96 padded_seqs = np.array(padded_seqs).reshape(len(start_word), max_len)97 98 preds = model.predict([features[:len(start_word)],padded_seqs], verbose=0)99 100 #Getting the best branches for each of the start seqs that we had101 for index, pred in enumerate(preds):102 word_preds = np.argsort(pred)[-live_seqs:]103 for w in word_preds:104 next_cap, prob = start_word[index][0][:], start_word[index][1]105 next_cap.append(w)106 prob *= pred[w]107 temp.append([next_cap, prob])108 109 start_word = temp110 # Sorting according to the probabilities111 start_word = sorted(start_word, reverse=False, key=lambda l: l[1])112 # Getting the top words from all branches113 start_word = start_word[-live_seqs:]114 115 for pair in start_word:116 if index2Word[pair[0][-1]] == 'endseq':117 final_preds.append([pair[0][:-1], pair[1]])118 start_word = start_word[:-1]119 live_seqs -= 1120 if len(pair[0]) == max_len:121 final_preds.append(pair)122 start_word = start_word[:-1]123 live_seqs -= 1124 125 # Between all the finished sequences (either max len or predicted endseq), decide which is best126 max_prob = 0127 for index, pred in enumerate(final_preds):128 if pred[1] > max_prob:129 best_index = index130 max_prob = pred[1]131 132 # Convert to readable text133 final_pred = final_preds[best_index]134 final_caption = [index2Word[i] for i in final_pred[0]]135 final_caption = ' '.join(final_caption[1:])136 return final_caption137 138# # create target model directory139# model_dir = './models/'140# os.makedirs(model_dir, exist_ok=True)141#142# files_to_download = [143# "config.json",144# "flax_model.msgpack",145# "merges.txt",146# "special_tokens_map.json",147# "tokenizer.json",148# "tokenizer_config.json",149# "vocab.json",150# "preprocessor_config.json",151# ]152 153def _compile():154 155 image_path = 'samples/ROCO_00929.jpg'156 image = Image.open(image_path)157 #predict(image)158 image.close()159 160 161_compile()162 163 164sample_dir = './samples/'165sample_image_ids = tuple(["None"] + [int(f.replace('ROCO_', '').replace('.jpg', '')) for f in os.listdir(sample_dir) if f.startswith('ROCO_')])166 167with open(os.path.join(sample_dir, "Roco-img-ids.json"), "r", encoding="UTF-8") as fp:168 roco_image_ids = json.load(fp)169 170 171def get_random_image_id():172 173 image_id = random.sample(roco_image_ids, k=1)[0]174 return image_id175 