{ "cells": [ { "cell_type": "code", "execution_count": 236, "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "import numpy as np\n", "import pickle as pkl\n", "import math\n", "import gradio as gr\n", "from tqdm.notebook import tqdm\n", "\n", "import tensorflow as tf\n", "from tensorflow.keras.applications.vgg16 import VGG16, preprocess_input\n", "from tensorflow.keras.models import Model\n", "from tensorflow.keras.utils import load_img, img_to_array\n", "from tensorflow.keras.utils import Sequence\n", "from tensorflow.keras.preprocessing.text import Tokenizer\n", "from tensorflow.keras.preprocessing.sequence import pad_sequences\n", "from tensorflow.keras.utils import to_categorical, plot_model\n", "from tensorflow.keras import layers\n", "from tensorflow.keras.layers import Resizing" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'2.10.0'" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tf.__version__" ] }, { "cell_type": "code", "execution_count": 237, "metadata": {}, "outputs": [], "source": [ "# Read data \n", "df = pd.read_csv('captions.txt')" ] }, { "cell_type": "code", "execution_count": 238, "metadata": {}, "outputs": [], "source": [ "def preprocess_text(text):\n", " text = 'startseq ' + text + ' endseq'\n", " return text" ] }, { "cell_type": "code", "execution_count": 239, "metadata": {}, "outputs": [], "source": [ "# Adding start and end token\n", "df['caption'] = df['caption'].apply(preprocess_text)" ] }, { "cell_type": "code", "execution_count": 240, "metadata": {}, "outputs": [], "source": [ "# Tokenizer\n", "tokenizer = Tokenizer(num_words=5000)\n", "tokenizer.fit_on_texts(df['caption'])" ] }, { "cell_type": "code", "execution_count": 241, "metadata": {}, "outputs": [], "source": [ "# Vocabulary Size\n", "vocab_size = len(tokenizer.word_index) + 1" ] }, { "cell_type": "code", "execution_count": 242, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "39" ] }, "execution_count": 242, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Max len caption\n", "max_len = max(len(i) for i in tokenizer.texts_to_sequences(df['caption']))" ] }, { "cell_type": "code", "execution_count": 243, "metadata": {}, "outputs": [], "source": [ "# Join all different list of caption into one\n", "df = df.groupby('image',as_index=False).aggregate({'caption':list})" ] }, { "cell_type": "code", "execution_count": 246, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
imagecaption
01000268201_693b08cb0e.jpg[startseq A child in a pink dress is climbing ...
11001773457_577c3a7d70.jpg[startseq A black dog and a spotted dog are fi...
21002674143_1b742ab4b8.jpg[startseq A little girl covered in paint sits ...
31003163366_44323f5815.jpg[startseq A man lays on a bench while his dog ...
41007129816_e794419615.jpg[startseq A man in an orange hat starring at s...
\n", "
" ], "text/plain": [ " image \\\n", "0 1000268201_693b08cb0e.jpg \n", "1 1001773457_577c3a7d70.jpg \n", "2 1002674143_1b742ab4b8.jpg \n", "3 1003163366_44323f5815.jpg \n", "4 1007129816_e794419615.jpg \n", "\n", " caption \n", "0 [startseq A child in a pink dress is climbing ... \n", "1 [startseq A black dog and a spotted dog are fi... \n", "2 [startseq A little girl covered in paint sits ... \n", "3 [startseq A man lays on a bench while his dog ... \n", "4 [startseq A man in an orange hat starring at s... " ] }, "execution_count": 246, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.head()" ] }, { "cell_type": "code", "execution_count": 247, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 [startseq A child in a pink dress is climbing ...\n", "1 [startseq A black dog and a spotted dog are fi...\n", "2 [startseq A little girl covered in paint sits ...\n", "3 [startseq A man lays on a bench while his dog ...\n", "4 [startseq A man in an orange hat starring at s...\n", " ... \n", "8086 [startseq A man does a wheelie on his bicycle ...\n", "8087 [startseq A group is sitting around a snowy cr...\n", "8088 [startseq A grey bird stands majestically on a...\n", "8089 [startseq A person stands near golden walls . ...\n", "8090 [startseq A man in a pink shirt climbs a rock ...\n", "Name: caption, Length: 8091, dtype: object" ] }, "execution_count": 247, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df['caption']" ] }, { "cell_type": "code", "execution_count": 248, "metadata": {}, "outputs": [], "source": [ "# Train Test Split\n", "train_data = df.iloc[:6500]\n", "test = df.iloc[6500:]" ] }, { "cell_type": "code", "execution_count": 253, "metadata": {}, "outputs": [ { "ename": "ResourceExhaustedError", "evalue": "{{function_node __wrapped__Mul_device_/job:localhost/replica:0/task:0/device:GPU:0}} failed to allocate memory [Op:Mul]", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mResourceExhaustedError\u001b[0m Traceback (most recent call last)", "Cell \u001b[1;32mIn[253], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m vgg_model \u001b[38;5;241m=\u001b[39m \u001b[43mVGG16\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 3\u001b[0m vgg_model\u001b[38;5;241m.\u001b[39mtrainable \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mFalse\u001b[39;00m\n", "File \u001b[1;32mc:\\Users\\VICTUS\\anaconda3\\envs\\GPU\\lib\\site-packages\\keras\\applications\\vgg16.py:210\u001b[0m, in \u001b[0;36mVGG16\u001b[1;34m(include_top, weights, input_tensor, input_shape, pooling, classes, classifier_activation)\u001b[0m\n\u001b[0;32m 207\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m include_top:\n\u001b[0;32m 208\u001b[0m \u001b[38;5;66;03m# Classification block\u001b[39;00m\n\u001b[0;32m 209\u001b[0m x \u001b[38;5;241m=\u001b[39m layers\u001b[38;5;241m.\u001b[39mFlatten(name\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mflatten\u001b[39m\u001b[38;5;124m\"\u001b[39m)(x)\n\u001b[1;32m--> 210\u001b[0m x \u001b[38;5;241m=\u001b[39m \u001b[43mlayers\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mDense\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m4096\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mactivation\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mrelu\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mname\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mfc1\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[43mx\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 211\u001b[0m x \u001b[38;5;241m=\u001b[39m layers\u001b[38;5;241m.\u001b[39mDense(\u001b[38;5;241m4096\u001b[39m, activation\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mrelu\u001b[39m\u001b[38;5;124m\"\u001b[39m, name\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mfc2\u001b[39m\u001b[38;5;124m\"\u001b[39m)(x)\n\u001b[0;32m 213\u001b[0m imagenet_utils\u001b[38;5;241m.\u001b[39mvalidate_activation(classifier_activation, weights)\n", "File \u001b[1;32mc:\\Users\\VICTUS\\anaconda3\\envs\\GPU\\lib\\site-packages\\keras\\utils\\traceback_utils.py:70\u001b[0m, in \u001b[0;36mfilter_traceback..error_handler\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m 67\u001b[0m filtered_tb \u001b[38;5;241m=\u001b[39m _process_traceback_frames(e\u001b[38;5;241m.\u001b[39m__traceback__)\n\u001b[0;32m 68\u001b[0m \u001b[38;5;66;03m# To get the full stack trace, call:\u001b[39;00m\n\u001b[0;32m 69\u001b[0m \u001b[38;5;66;03m# `tf.debugging.disable_traceback_filtering()`\u001b[39;00m\n\u001b[1;32m---> 70\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m e\u001b[38;5;241m.\u001b[39mwith_traceback(filtered_tb) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[0;32m 71\u001b[0m \u001b[38;5;28;01mfinally\u001b[39;00m:\n\u001b[0;32m 72\u001b[0m \u001b[38;5;28;01mdel\u001b[39;00m filtered_tb\n", "File \u001b[1;32mc:\\Users\\VICTUS\\anaconda3\\envs\\GPU\\lib\\site-packages\\keras\\backend.py:2100\u001b[0m, in \u001b[0;36mRandomGenerator.random_uniform\u001b[1;34m(self, shape, minval, maxval, dtype, nonce)\u001b[0m\n\u001b[0;32m 2098\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m nonce:\n\u001b[0;32m 2099\u001b[0m seed \u001b[38;5;241m=\u001b[39m tf\u001b[38;5;241m.\u001b[39mrandom\u001b[38;5;241m.\u001b[39mexperimental\u001b[38;5;241m.\u001b[39mstateless_fold_in(seed, nonce)\n\u001b[1;32m-> 2100\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mtf\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrandom\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mstateless_uniform\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 2101\u001b[0m \u001b[43m \u001b[49m\u001b[43mshape\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mshape\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 2102\u001b[0m \u001b[43m \u001b[49m\u001b[43mminval\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mminval\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 2103\u001b[0m \u001b[43m \u001b[49m\u001b[43mmaxval\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mmaxval\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 2104\u001b[0m \u001b[43m \u001b[49m\u001b[43mdtype\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdtype\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 2105\u001b[0m \u001b[43m \u001b[49m\u001b[43mseed\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mseed\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 2106\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 2107\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m tf\u001b[38;5;241m.\u001b[39mrandom\u001b[38;5;241m.\u001b[39muniform(\n\u001b[0;32m 2108\u001b[0m shape\u001b[38;5;241m=\u001b[39mshape,\n\u001b[0;32m 2109\u001b[0m minval\u001b[38;5;241m=\u001b[39mminval,\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 2112\u001b[0m seed\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mmake_legacy_seed(),\n\u001b[0;32m 2113\u001b[0m )\n", "\u001b[1;31mResourceExhaustedError\u001b[0m: {{function_node __wrapped__Mul_device_/job:localhost/replica:0/task:0/device:GPU:0}} failed to allocate memory [Op:Mul]" ] } ], "source": [ "# Image Feauture extraction model\n", "vgg_model = VGG16()\n", "vgg_model.trainable = False\n", "img_model = Model(inputs = vgg_model.input,outputs=vgg_model.layers[-2].output)" ] }, { "cell_type": "code", "execution_count": 127, "metadata": {}, "outputs": [], "source": [ "target_shape = (224, 224)\n", "batch_size = 32" ] }, { "cell_type": "code", "execution_count": 128, "metadata": {}, "outputs": [], "source": [ "# Load all image preprocess it and Extract feature from image\n", "image_features = {}\n", "base_dir = 'Images/'\n", "\n", "for image in tqdm(df['image']):\n", " img_path = base_dir + image\n", " img = load_img(img_path,\n", " target_size=target_shape)\n", " img = img_to_array(img)\n", " img = tf.expand_dims(img,axis=0)\n", " img = preprocess_input(img)\n", "\n", " feature = vgg_model.predict(img,verbose=False)\n", " image_features[image] = feature\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": 129, "metadata": {}, "outputs": [], "source": [ "# with open('img_features.pkl','wb') as f:\n", "# pkl.dump(image_features,f)" ] }, { "cell_type": "code", "execution_count": 130, "metadata": {}, "outputs": [], "source": [ "# pickling the image feature dict\n", "with open('img_features.pkl','rb') as f:\n", " img_features = pkl.load(f)" ] }, { "cell_type": "code", "execution_count": 131, "metadata": {}, "outputs": [], "source": [ "# Custome Data genarator for seq-to-seq Modeling\n", "class data_genarator(Sequence):\n", "\n", " def __init__(self,data,img_features,tokenizer,batch_size=32):\n", " self.data = data\n", " self.img_features = img_features\n", " self.tokenizer = tokenizer\n", " self.batch_size = batch_size\n", "\n", " def __len__(self):\n", " # Returns the number of batches\n", " return len(self.data) // self.batch_size\n", " \n", " def __getitem__(self,index):\n", " # Return each batch of data\n", " batch_data = self.data.iloc[index * self.batch_size : (index+1) * self.batch_size, :]\n", " X1, X2, y = self.__get_data(batch_data)\n", " return [X1, X2], y\n", " \n", " def __get_data(self,batch_data):\n", " # Genarate Sequntial data \n", " X1 , X2, y = list(), list(), list()\n", "\n", " for image_id in batch_data['image']:\n", " img_vector = self.img_features[image_id][0]\n", " captions = batch_data[batch_data['image']==image_id]['caption'].values[0]\n", " \n", " for caption in captions:\n", " seq = self.tokenizer.texts_to_sequences([caption])[0]\n", " for i in range(1,len(seq)):\n", "\n", " input_seq = seq[:i]\n", " output_seq = seq[i]\n", " input_seq = pad_sequences([input_seq],\n", " maxlen=30,\n", " padding='post')[0]\n", " \n", " output_seq = to_categorical([output_seq],\n", " num_classes=vocab_size)[0]\n", "\n", " X1.append(img_vector)\n", " X2.append(input_seq)\n", " y.append(output_seq)\n", " \n", " X1, X2, y = np.array(X1),np.array(X2),np.array(y)\n", " return X1, X2, y\n", "\n", "\n", "\n", " \n", "\n", " \n", "\n", " \n", "\n", " \n", "\n", "\n", "\n", "\n", " " ] }, { "cell_type": "code", "execution_count": 132, "metadata": {}, "outputs": [], "source": [ "# class CustomDataGenerator(Sequence):\n", " \n", "# def __init__(self, df, X_col, y_col, batch_size, tokenizer, \n", "# vocab_size, max_length, features,shuffle=True):\n", " \n", "# self.df = df.copy()\n", "# self.X_col = X_col\n", "# self.y_col = y_col\n", "# self.batch_size = batch_size\n", "# self.tokenizer = tokenizer\n", "# self.vocab_size = vocab_size\n", "# self.max_length = max_length\n", "# self.features = features\n", "# self.shuffle = shuffle\n", "# self.n = len(self.df)\n", " \n", "# def on_epoch_end(self):\n", "# if self.shuffle:\n", "# self.df = self.df.sample(frac=1).reset_index(drop=True)\n", " \n", "# def __len__(self):\n", "# return self.n // self.batch_size\n", " \n", "# def __getitem__(self,index):\n", " \n", "# batch = self.df.iloc[index * self.batch_size:(index + 1) * self.batch_size,:]\n", "# X1, X2, y = self.__get_data(batch) \n", "# return (X1, X2), y\n", " \n", "# def __get_data(self,batch): \n", " \n", "# X1, X2, y = list(), list(), list()\n", "# images = batch[self.X_col].tolist()\n", " \n", "# for image in images:\n", "# feature = self.features[image][0]\n", "# captions = batch.loc[batch[self.X_col]==image, self.y_col].values[0]\n", "\n", "# for caption in captions:\n", "# seq = self.tokenizer.texts_to_sequences([caption])[0]\n", "\n", "# for i in range(1,len(seq)):\n", "# in_seq, out_seq = seq[:i], seq[i]\n", "# in_seq = pad_sequences([in_seq], maxlen=self.max_length,padding='post')[0]\n", "# out_seq = to_categorical([out_seq], num_classes=self.vocab_size)[0]\n", "# X1.append(feature)\n", "# X2.append(in_seq)\n", "# y.append(out_seq)\n", " \n", "# X1, X2, y = np.array(X1), np.array(X2), np.array(y)\n", " \n", "# return X1, X2, y" ] }, { "cell_type": "code", "execution_count": 135, "metadata": {}, "outputs": [], "source": [ "# Model Building\n", "\n", "input_1 = layers.Input(shape=(1000,))\n", "fc1 = layers.Dense(512,activation='relu')(input_1)\n", "\n", "input_2 = layers.Input(shape=(30,))\n", "embedding = layers.Embedding(vocab_size,512,mask_zero=True)(input_2)\n", "\n", "add = layers.add([fc1,embedding])\n", "\n", "lstm = layers.LSTM(128)(add)\n", "fc2 = layers.Dense(256, activation='relu')(lstm)\n", "softmax = layers.Dense(vocab_size,activation='softmax')(fc2)\n", "\n", "\n", "model = Model(inputs=[input_1,input_2],\n", " outputs=softmax )\n", "\n", "model.compile(loss='categorical_crossentropy', optimizer='rmsprop')" ] }, { "cell_type": "code", "execution_count": 136, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Model: \"model_3\"\n", "__________________________________________________________________________________________________\n", " Layer (type) Output Shape Param # Connected to \n", "==================================================================================================\n", " input_7 (InputLayer) [(None, 1000)] 0 [] \n", " \n", " input_8 (InputLayer) [(None, 30)] 0 [] \n", " \n", " dense_9 (Dense) (None, 512) 512512 ['input_7[0][0]'] \n", " \n", " embedding_3 (Embedding) (None, 30, 512) 4349952 ['input_8[0][0]'] \n", " \n", " add_3 (Add) (None, 30, 512) 0 ['dense_9[0][0]', \n", " 'embedding_3[0][0]'] \n", " \n", " lstm_3 (LSTM) (None, 128) 328192 ['add_3[0][0]'] \n", " \n", " dense_10 (Dense) (None, 256) 33024 ['lstm_3[0][0]'] \n", " \n", " dense_11 (Dense) (None, 8496) 2183472 ['dense_10[0][0]'] \n", " \n", "==================================================================================================\n", "Total params: 7,407,152\n", "Trainable params: 7,407,152\n", "Non-trainable params: 0\n", "__________________________________________________________________________________________________\n" ] } ], "source": [ "model.summary()" ] }, { "cell_type": "code", "execution_count": 137, "metadata": {}, "outputs": [ { "data": { "image/png": "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mTMH999/P1566SW8++67uPLKK7Fr1y58+OGHdodG5CiRSATLli3Dv//7v+Pf/u3fcOjQISxdutTusIioABaTRFXU0tKCiYkJ9Pf348EHH8T111+PX/ziF3aHRWS7d999F1u2bMH111+PJUuW4Be/+AXuv/9+zJrFjykip+NRSlRl8izlz372M5w8eRLLli3DQw89hJMnT9odGpEtnn/+eVx55ZXYvXs3vvOd7+DAgQNYsmSJ3WERkUEsJolsctlllyESieChhx7Czp07cfXVV+PVV1+1OyyiqvnTn/6ELVu24IYbbsDFF1+Mo0ePYtOmTXC5XHaHRkQlYDFJZKOzzjoL999/P44ePYqmpiZce+212LJlCz744AO7QyOqqOeeew4tLS3Ys2cPnnjiCTzzzDO46KKL7A6LiExgMUnkABdffDF+/OMf4/HHH8fjjz+Oq666Ci+//LLdYRFZLp1O46677sKNN96Iz33uczh27Bg2bdpkd1hEVAYWk0QOMWvWLGzatAmvvfYaLrzwQqxcuRJbtmzB+++/b3doRJY4cOAALr/8cnz/+9/Hd7/7XYTDYSxevNjusIioTCwmiRzmM5/5DMbGxvDtb38b3/72t7F8+XK8+OKLdodFZFoqlcJdd92FdevWYcWKFTh27BjuuOMOu8MiIouwmCRyIJfLhU2bNuHIkSNYtGgRrrvuOvzLv/wL/vjHP9odGlFJnnnmGVx22WUIhUJ4+umnMTo6igsvvNDusIjIQiwmiRzs05/+NH70ox/hO9/5Dr773e+ipaUFzz77rN1hERX1zjvv4K677sLNN9+M6667DkePHsVtt91md1hEVAEsJokcTp6l/J//+R9ceumlaG1txV133YU//OEPdodGpGvfvn245JJLEA6H8f3vfx+jo6P42Mc+ZndYRFQhLCaJasSiRYvwgx/8ACMjI3j66adxxRVXYGxszO6wiFSJRAJtbW3o7OzE3/zN3+DYsWO45ZZb7A6LiCqMxSRRjWlvb8fRo0dx5ZVX4stf/jLuuusu/P73v7c7LGpw+/btw6WXXoqf/exn+NGPfoT//M//xPnnn293WERUBSwmiWrQJz7xCXzve9/DyMgIvve97+Hyyy/Hf//3f9sdFjWg//u//8Ott96Kzs5O/N3f/R1ee+01rFmzxu6wiKiKWEwS1bD29nYcO3YM11xzDb7yla+go6MDv/3tb+0OixrEvn37cNlll+G1117D2NgY9uzZg3PPPdfusIioylhMEtW45uZmjI6OIhQK4ac//SkuvfRSfP/737c7LKpj8XgcX/nKV7B+/Xq0tbXhtddew+rVq+0Oi4hswmKSqE4oioKjR4/C7Xbj1ltvRUdHB95++227w6I6IoRAIBDA5Zdfjtdffx0//vGPsWfPHsyfP9/u0IjIRiwmierI+eefjz179uCZZ55BJBLBZZddhqefftrusKgOvP7661izZg3uuece3H333Thy5AhWrVpld1hE5AAsJonq0Lp163D06FHccsstaG9vR0dHB37zm9/YHRbVIHk28oorrkAymcThw4exc+dOnH322XaHRkQOwWKSqE41NTVhz549OHDgAF544QVccsklCAQCdodFNeRXv/oVVq9ejXvuuQf33HMPXn75ZVx99dV2h0VEDsNikqjOrV27FkeOHEF3dzd6e3tx8803480337Q7LHKwmZkZPPbYY7jiiivwzjvv4IUXXsDOnTsxb948u0MjIgdiMUnUAM477zw89thjePbZZzE1NYXLLruMZylJ17Fjx/DFL34R3/jGN/BP//RPeOmll7Bs2TK7wyIiB2MxSdRArr/+ekSjUdx1113o7e3FTTfdhDfeeMPusMgBZmZmsGvXLixfvhyzZs1CNBrFzp07MXfuXLtDIyKHYzFJ1GA++tGPYufOnfjJT36C//3f/1XPUgoh7A6NbPLaa69hxYoV2Lp1K7Zu3Yrnn38en//85+0Oi4hqBItJogZ13XXX4ZVXXkFvby/uvvtu3HjjjfjlL39Z9H3vv/9+FaKjcp06dQonT54sOM/Jkyexa9cuXH311Zg3bx5eeeUV3H///Zg9e3aVoiSiesBikqiBfeQjH8HOnTvx/PPP4+2330ZLSwt27dqFU6dO6c5/5MgRrF69mgVlDdi2bRsefvjhvK9Ho1Fce+212Lp1K/71X/8Vzz33HD73uc9VMUIiqhcsJokIK1asQDQaxYMPPogHH3wQq1atwuTkZMY8MzMz6O7uRiQSwb333mtTpGTEwYMHsXXrVmzbtg1HjhzJeO29997Dli1bcNVVV+Gcc85BLBbj2UgiKguLSSICAMyZMwf3338/XnrpJbz77rv4whe+gF27duHDDz8EAPj9fhw9ehQAsHv3bvzXf/2XneFSHm+++SY6OjrgcrkAAN3d3ZiZmQEARCIRfOELX8ATTzyBgYEBPPvss/jsZz9rZ7hEVAdcgqPuiSjLzMwMBgYG8OCDD2L58uX45je/iVtvvVUdg+dyuTBv3jy8/PLLuPTSS22OlqSZmRmsWrUKL7/8stpWs2fPRn9/P/74xz/C7/djzZo1CAQCWLJkic3RElGd2Mdikojyeu2113DnnXfi5z//OT788MOMGzrOOussfOpTn0IsFsO5555rY5Qk9fX14dFHH1XPJkuzZs3C/Pnz8dhjj+HOO++0KToiqlP7eJmbiPK64oor0NnZiQ8++CDnzuCZmRm88cYb6OnpsSk60gqHw/jWt76VU0gCp4vJT3/607jjjjtsiIyI6t3shx566CG7gyAiZ5qamkJ7e7s65i7bqVOn8POf/xwLFy7EVVddVeXoSIrH4/jyl7+MkydP6j4v9NSpU3j77bdx3nnnYeXKlTZESER17Oe8zE1Euk6dOoXrr78eL730UtHnFc6ZMweRSATLly+vUnQkvffee7j22mvxi1/8omg7zZ07F0ePHuVNN0RkJV7mJiJ93/72t3H48OGiBQoACCFw66234p133qlCZKT1z//8z/j5z39uqJ0++OAD/MM//EPe54gSEZnBYpKIdF155ZX45je/iWuuuUZ9BuG8efN0552ZmcGvf/1r3HHHHfxZxioaGhrC4OBg3mEIc+bMUR8RtGTJEmzatAm9vb344IMPqhkmEdU5XuYmoqL+9Kc/4ZVXXsFPf/pT/PCHP0QkEsHJkycxb968jF/DmTVrFnbu3IlvfOMbNkbbGI4dO4arrroK77//vlrAz507FzMzMzh16hQ++clPorW1FV/60pewdu1a/MVf/IXNERNRneKjgRrd6Oio3SFQDXr//fcxOTmJY8eO4ciRI3j99dfVS6ezZs1Cf38/f5qvgt577z3cf//9+PWvf61O+9jHPoaWlhZceuml+PznP48LLrjAxgipVl133XW46KKL7A6DaguLyUYnL4ERERGNjIygo6PD7jCotuw7y+4IyH5MHqfP0HZ2dnK8XxEul8tQf/nDH/6A3/3ud1i8eHGVImsc7777Lv7f//t/PHtEluPJBTKLxSQRWe6cc87BOeecY3cYdekjH/kIC0kichTezU1EREREprGYJCIiIiLTWEwSERERkWksJomIiIjINBaTRERE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", "text/plain": [ "" ] }, "execution_count": 137, "metadata": {}, "output_type": "execute_result" } ], "source": [ "plot_model(model,show_shapes=True)" ] }, { "cell_type": "code", "execution_count": 138, "metadata": {}, "outputs": [], "source": [ "train_ds = data_genarator(data=train_data,img_features=img_features,tokenizer=tokenizer)\n", "\n", "test_ds = data_genarator(data=test,img_features=img_features,tokenizer=tokenizer)" ] }, { "cell_type": "code", "execution_count": 139, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(1998, 30)" ] }, "execution_count": 139, "metadata": {}, "output_type": "execute_result" } ], "source": [ "train_ds[0][0][1].shape" ] }, { "cell_type": "code", "execution_count": 140, "metadata": {}, "outputs": [], "source": [ "# train_generator = CustomDataGenerator(df=train_data,\n", "# X_col='image',\n", "# y_col='caption',\n", "# batch_size=32,\n", "# tokenizer=tokenizer,\n", "# vocab_size=vocab_size,\n", "# max_length=30,\n", "# features=img_features)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Epoch 1/20\n", "203/203 [==============================] - 40s 176ms/step - loss: 4.9081 - val_loss: 4.1670\n", "Epoch 2/20\n", "203/203 [==============================] - 34s 166ms/step - loss: 3.9464 - val_loss: 3.7417\n", "Epoch 3/20\n", "203/203 [==============================] - 33s 161ms/step - loss: 3.6003 - val_loss: 3.5350\n", "Epoch 4/20\n", "203/203 [==============================] - 32s 155ms/step - loss: 3.3984 - val_loss: 3.4103\n", "Epoch 5/20\n", "203/203 [==============================] - 32s 158ms/step - loss: 3.2561 - val_loss: 3.3249\n", "Epoch 6/20\n", "203/203 [==============================] - 34s 166ms/step - loss: 3.1435 - val_loss: 3.2565\n", "Epoch 7/20\n", "203/203 [==============================] - 35s 170ms/step - loss: 3.0519 - val_loss: 3.2185\n", "Epoch 8/20\n", "203/203 [==============================] - 35s 172ms/step - loss: 2.9731 - val_loss: 3.1798\n", "Epoch 9/20\n", "203/203 [==============================] - 401s 2s/step - loss: 2.9064 - val_loss: 3.1590\n", "Epoch 10/20\n", "203/203 [==============================] - 18453s 91s/step - loss: 2.8465 - val_loss: 3.1371\n", "Epoch 11/20\n", "203/203 [==============================] - 21s 106ms/step - loss: 2.7938 - val_loss: 3.1293\n", "Epoch 12/20\n", "203/203 [==============================] - 21s 104ms/step - loss: 2.7434 - val_loss: 3.1344\n", "Epoch 13/20\n", "203/203 [==============================] - 22s 106ms/step - loss: 2.6983 - val_loss: 3.1293\n", "Epoch 14/20\n", "203/203 [==============================] - 25s 125ms/step - loss: 2.6549 - val_loss: 3.1152\n", "Epoch 15/20\n", "203/203 [==============================] - 26s 127ms/step - loss: 2.6134 - val_loss: 3.1209\n", "Epoch 16/20\n", "203/203 [==============================] - 25s 124ms/step - loss: 2.5752 - val_loss: 3.1269\n", "Epoch 17/20\n", " 42/203 [=====>........................] - ETA: 17s - loss: 2.4897" ] }, { "ename": "KeyboardInterrupt", "evalue": "", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", "Cell \u001b[1;32mIn[145], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[43mmodel\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtrain_ds\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 2\u001b[0m \u001b[43m \u001b[49m\u001b[43mepochs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;241;43m20\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[0;32m 3\u001b[0m \u001b[43m \u001b[49m\u001b[43mvalidation_data\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtest_ds\u001b[49m\u001b[43m)\u001b[49m\n", "File \u001b[1;32mc:\\Users\\VICTUS\\anaconda3\\envs\\GPU\\lib\\site-packages\\keras\\utils\\traceback_utils.py:65\u001b[0m, in \u001b[0;36mfilter_traceback..error_handler\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m 63\u001b[0m filtered_tb \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[0;32m 64\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m---> 65\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfn\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 66\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[0;32m 67\u001b[0m filtered_tb \u001b[38;5;241m=\u001b[39m _process_traceback_frames(e\u001b[38;5;241m.\u001b[39m__traceback__)\n", "File \u001b[1;32mc:\\Users\\VICTUS\\anaconda3\\envs\\GPU\\lib\\site-packages\\keras\\engine\\training.py:1564\u001b[0m, in \u001b[0;36mModel.fit\u001b[1;34m(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, validation_batch_size, validation_freq, max_queue_size, workers, use_multiprocessing)\u001b[0m\n\u001b[0;32m 1556\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m tf\u001b[38;5;241m.\u001b[39mprofiler\u001b[38;5;241m.\u001b[39mexperimental\u001b[38;5;241m.\u001b[39mTrace(\n\u001b[0;32m 1557\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtrain\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[0;32m 1558\u001b[0m epoch_num\u001b[38;5;241m=\u001b[39mepoch,\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 1561\u001b[0m _r\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m1\u001b[39m,\n\u001b[0;32m 1562\u001b[0m ):\n\u001b[0;32m 1563\u001b[0m callbacks\u001b[38;5;241m.\u001b[39mon_train_batch_begin(step)\n\u001b[1;32m-> 1564\u001b[0m tmp_logs \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtrain_function\u001b[49m\u001b[43m(\u001b[49m\u001b[43miterator\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1565\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m data_handler\u001b[38;5;241m.\u001b[39mshould_sync:\n\u001b[0;32m 1566\u001b[0m context\u001b[38;5;241m.\u001b[39masync_wait()\n", "File \u001b[1;32mc:\\Users\\VICTUS\\anaconda3\\envs\\GPU\\lib\\site-packages\\tensorflow\\python\\util\\traceback_utils.py:150\u001b[0m, in \u001b[0;36mfilter_traceback..error_handler\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m 148\u001b[0m filtered_tb \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[0;32m 149\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m--> 150\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfn\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 151\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[0;32m 152\u001b[0m filtered_tb \u001b[38;5;241m=\u001b[39m _process_traceback_frames(e\u001b[38;5;241m.\u001b[39m__traceback__)\n", "File \u001b[1;32mc:\\Users\\VICTUS\\anaconda3\\envs\\GPU\\lib\\site-packages\\tensorflow\\python\\eager\\def_function.py:915\u001b[0m, in \u001b[0;36mFunction.__call__\u001b[1;34m(self, *args, **kwds)\u001b[0m\n\u001b[0;32m 912\u001b[0m compiler \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mxla\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_jit_compile \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mnonXla\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 914\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m OptionalXlaContext(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_jit_compile):\n\u001b[1;32m--> 915\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_call\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwds\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 917\u001b[0m new_tracing_count \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mexperimental_get_tracing_count()\n\u001b[0;32m 918\u001b[0m without_tracing \u001b[38;5;241m=\u001b[39m (tracing_count \u001b[38;5;241m==\u001b[39m new_tracing_count)\n", "File \u001b[1;32mc:\\Users\\VICTUS\\anaconda3\\envs\\GPU\\lib\\site-packages\\tensorflow\\python\\eager\\def_function.py:947\u001b[0m, in \u001b[0;36mFunction._call\u001b[1;34m(self, *args, **kwds)\u001b[0m\n\u001b[0;32m 944\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_lock\u001b[38;5;241m.\u001b[39mrelease()\n\u001b[0;32m 945\u001b[0m \u001b[38;5;66;03m# In this case we have created variables on the first call, so we run the\u001b[39;00m\n\u001b[0;32m 946\u001b[0m \u001b[38;5;66;03m# defunned version which is guaranteed to never create variables.\u001b[39;00m\n\u001b[1;32m--> 947\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_stateless_fn\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwds\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;66;03m# pylint: disable=not-callable\u001b[39;00m\n\u001b[0;32m 948\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_stateful_fn \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 949\u001b[0m \u001b[38;5;66;03m# Release the lock early so that multiple threads can perform the call\u001b[39;00m\n\u001b[0;32m 950\u001b[0m \u001b[38;5;66;03m# in parallel.\u001b[39;00m\n\u001b[0;32m 951\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_lock\u001b[38;5;241m.\u001b[39mrelease()\n", "File \u001b[1;32mc:\\Users\\VICTUS\\anaconda3\\envs\\GPU\\lib\\site-packages\\tensorflow\\python\\eager\\function.py:2496\u001b[0m, in \u001b[0;36mFunction.__call__\u001b[1;34m(self, *args, **kwargs)\u001b[0m\n\u001b[0;32m 2493\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_lock:\n\u001b[0;32m 2494\u001b[0m (graph_function,\n\u001b[0;32m 2495\u001b[0m filtered_flat_args) \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_maybe_define_function(args, kwargs)\n\u001b[1;32m-> 2496\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mgraph_function\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_call_flat\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 2497\u001b[0m \u001b[43m \u001b[49m\u001b[43mfiltered_flat_args\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcaptured_inputs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mgraph_function\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcaptured_inputs\u001b[49m\u001b[43m)\u001b[49m\n", "File \u001b[1;32mc:\\Users\\VICTUS\\anaconda3\\envs\\GPU\\lib\\site-packages\\tensorflow\\python\\eager\\function.py:1862\u001b[0m, in \u001b[0;36mConcreteFunction._call_flat\u001b[1;34m(self, args, captured_inputs, cancellation_manager)\u001b[0m\n\u001b[0;32m 1858\u001b[0m possible_gradient_type \u001b[38;5;241m=\u001b[39m gradients_util\u001b[38;5;241m.\u001b[39mPossibleTapeGradientTypes(args)\n\u001b[0;32m 1859\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m (possible_gradient_type \u001b[38;5;241m==\u001b[39m gradients_util\u001b[38;5;241m.\u001b[39mPOSSIBLE_GRADIENT_TYPES_NONE\n\u001b[0;32m 1860\u001b[0m \u001b[38;5;129;01mand\u001b[39;00m executing_eagerly):\n\u001b[0;32m 1861\u001b[0m \u001b[38;5;66;03m# No tape is watching; skip to running the function.\u001b[39;00m\n\u001b[1;32m-> 1862\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_build_call_outputs(\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_inference_function\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcall\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 1863\u001b[0m \u001b[43m \u001b[49m\u001b[43mctx\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcancellation_manager\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mcancellation_manager\u001b[49m\u001b[43m)\u001b[49m)\n\u001b[0;32m 1864\u001b[0m forward_backward \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_select_forward_and_backward_functions(\n\u001b[0;32m 1865\u001b[0m args,\n\u001b[0;32m 1866\u001b[0m possible_gradient_type,\n\u001b[0;32m 1867\u001b[0m executing_eagerly)\n\u001b[0;32m 1868\u001b[0m forward_function, args_with_tangents \u001b[38;5;241m=\u001b[39m forward_backward\u001b[38;5;241m.\u001b[39mforward()\n", "File \u001b[1;32mc:\\Users\\VICTUS\\anaconda3\\envs\\GPU\\lib\\site-packages\\tensorflow\\python\\eager\\function.py:499\u001b[0m, in \u001b[0;36m_EagerDefinedFunction.call\u001b[1;34m(self, ctx, args, cancellation_manager)\u001b[0m\n\u001b[0;32m 497\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m _InterpolateFunctionError(\u001b[38;5;28mself\u001b[39m):\n\u001b[0;32m 498\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m cancellation_manager \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m--> 499\u001b[0m outputs \u001b[38;5;241m=\u001b[39m \u001b[43mexecute\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mexecute\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 500\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mstr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msignature\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mname\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 501\u001b[0m \u001b[43m \u001b[49m\u001b[43mnum_outputs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_num_outputs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 502\u001b[0m \u001b[43m \u001b[49m\u001b[43minputs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 503\u001b[0m \u001b[43m \u001b[49m\u001b[43mattrs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mattrs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 504\u001b[0m \u001b[43m \u001b[49m\u001b[43mctx\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mctx\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 505\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m 506\u001b[0m outputs \u001b[38;5;241m=\u001b[39m execute\u001b[38;5;241m.\u001b[39mexecute_with_cancellation(\n\u001b[0;32m 507\u001b[0m \u001b[38;5;28mstr\u001b[39m(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msignature\u001b[38;5;241m.\u001b[39mname),\n\u001b[0;32m 508\u001b[0m num_outputs\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_num_outputs,\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 511\u001b[0m ctx\u001b[38;5;241m=\u001b[39mctx,\n\u001b[0;32m 512\u001b[0m cancellation_manager\u001b[38;5;241m=\u001b[39mcancellation_manager)\n", "File \u001b[1;32mc:\\Users\\VICTUS\\anaconda3\\envs\\GPU\\lib\\site-packages\\tensorflow\\python\\eager\\execute.py:54\u001b[0m, in \u001b[0;36mquick_execute\u001b[1;34m(op_name, num_outputs, inputs, attrs, ctx, name)\u001b[0m\n\u001b[0;32m 52\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m 53\u001b[0m ctx\u001b[38;5;241m.\u001b[39mensure_initialized()\n\u001b[1;32m---> 54\u001b[0m tensors \u001b[38;5;241m=\u001b[39m \u001b[43mpywrap_tfe\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mTFE_Py_Execute\u001b[49m\u001b[43m(\u001b[49m\u001b[43mctx\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_handle\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdevice_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mop_name\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 55\u001b[0m \u001b[43m \u001b[49m\u001b[43minputs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mattrs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mnum_outputs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 56\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m core\u001b[38;5;241m.\u001b[39m_NotOkStatusException \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[0;32m 57\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m name \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n", "\u001b[1;31mKeyboardInterrupt\u001b[0m: " ] } ], "source": [ "model.fit(train_ds,\n", " epochs=15,\n", " validation_data=test_ds)" ] }, { "cell_type": "code", "execution_count": 254, "metadata": {}, "outputs": [], "source": [ "# model.save('caption_genaration_model.h5')" ] }, { "cell_type": "code", "execution_count": 177, "metadata": {}, "outputs": [], "source": [ "def index_to_word(word_idx):\n", " return tokenizer.index_word[word_idx]" ] }, { "cell_type": "code", "execution_count": 192, "metadata": {}, "outputs": [], "source": [ "def predict_next(img):\n", "\n", " seq_in = 'startseq'\n", " feature_img = img_features[img]\n", "\n", " for i in range(30):\n", " seq_in_sequence = tokenizer.texts_to_sequences([seq_in])[0]\n", " seq_in_padded = pad_sequences([seq_in_sequence], padding='post',maxlen=30)\n", " y_hat = model.predict([feature_img,seq_in_padded],verbose=False)\n", " word_index = y_hat.argmax(axis=1)\n", " predicted_word = index_to_word(word_index[0])\n", "\n", " if predicted_word == 'endseq':\n", " break\n", " seq_in = seq_in + ' ' + predicted_word \n", "\n", " return seq_in\n" ] }, { "cell_type": "code", "execution_count": 193, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'startseq a man in a black helmet and a black helmet riding a bike'" ] }, "execution_count": 193, "metadata": {}, "output_type": "execute_result" } ], "source": [ "predict_next('990890291_afc72be141.jpg')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Caption Genaration" ] }, { "cell_type": "code", "execution_count": 230, "metadata": {}, "outputs": [], "source": [ "resize_img = Resizing(height=224, width=224)\n", "\n", "def img_preprocces(img): \n", " # preprocces image & Extract feature\n", " img = tf.expand_dims(img,axis=0)\n", " resized_image = resize_img(img)\n", " img = preprocess_input(resized_image)\n", " feature = vgg_model.predict(img,verbose=False)\n", "\n", " return feature" ] }, { "cell_type": "code", "execution_count": 231, "metadata": {}, "outputs": [], "source": [ "\n", "def genarate_caption(img):\n", "\n", " seq_in = 'startseq'\n", " feature_img = img_preprocces(img)\n", " \n", " for i in range(30):\n", " seq_in_sequence = tokenizer.texts_to_sequences([seq_in])[0]\n", " seq_in_padded = pad_sequences([seq_in_sequence], padding='post',maxlen=30)\n", " y_hat = model.predict([feature_img,seq_in_padded],verbose=False)\n", " word_index = y_hat.argmax(axis=1)\n", " predicted_word = index_to_word(word_index[0])\n", " seq_in = seq_in + ' ' + predicted_word \n", " if predicted_word == 'endseq':\n", " break\n", " \n", " return seq_in" ] }, { "cell_type": "code", "execution_count": 232, "metadata": {}, "outputs": [ { "ename": "UnimplementedError", "evalue": "Exception encountered when calling layer \"resizing_2\" \" f\"(type Resizing).\n\n{{function_node __wrapped__Cast_device_/job:localhost/replica:0/task:0/device:CPU:0}} Cast string to float is not supported [Op:Cast]\n\nCall arguments received by layer \"resizing_2\" \" f\"(type Resizing):\n • inputs=tf.Tensor(shape=(1,), dtype=string)", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mUnimplementedError\u001b[0m Traceback (most recent call last)", "Cell \u001b[1;32mIn[232], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[43mpredict_next\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mimg.jpg\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m)\u001b[49m\n", "Cell \u001b[1;32mIn[206], line 5\u001b[0m, in \u001b[0;36mpredict_next\u001b[1;34m(img)\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mpredict_next\u001b[39m(img):\n\u001b[0;32m 3\u001b[0m seq_in \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mstartseq\u001b[39m\u001b[38;5;124m'\u001b[39m\n\u001b[1;32m----> 5\u001b[0m feature_img \u001b[38;5;241m=\u001b[39m \u001b[43mimg_preprocces\u001b[49m\u001b[43m(\u001b[49m\u001b[43mimg\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 7\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m i \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mrange\u001b[39m(\u001b[38;5;241m30\u001b[39m):\n\u001b[0;32m 8\u001b[0m seq_in_sequence \u001b[38;5;241m=\u001b[39m tokenizer\u001b[38;5;241m.\u001b[39mtexts_to_sequences([seq_in])[\u001b[38;5;241m0\u001b[39m]\n", "Cell \u001b[1;32mIn[230], line 7\u001b[0m, in \u001b[0;36mimg_preprocces\u001b[1;34m(img)\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mimg_preprocces\u001b[39m(img): \n\u001b[0;32m 5\u001b[0m img \u001b[38;5;241m=\u001b[39m tf\u001b[38;5;241m.\u001b[39mexpand_dims(img,axis\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m0\u001b[39m)\n\u001b[1;32m----> 7\u001b[0m resized_image \u001b[38;5;241m=\u001b[39m \u001b[43mresize_img\u001b[49m\u001b[43m(\u001b[49m\u001b[43mimg\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 9\u001b[0m img \u001b[38;5;241m=\u001b[39m preprocess_input(resized_image)\n\u001b[0;32m 12\u001b[0m feature \u001b[38;5;241m=\u001b[39m vgg_model\u001b[38;5;241m.\u001b[39mpredict(img,verbose\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mFalse\u001b[39;00m)\n", "File \u001b[1;32mc:\\Users\\VICTUS\\anaconda3\\envs\\GPU\\lib\\site-packages\\keras\\utils\\traceback_utils.py:70\u001b[0m, in \u001b[0;36mfilter_traceback..error_handler\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m 67\u001b[0m filtered_tb \u001b[38;5;241m=\u001b[39m _process_traceback_frames(e\u001b[38;5;241m.\u001b[39m__traceback__)\n\u001b[0;32m 68\u001b[0m \u001b[38;5;66;03m# To get the full stack trace, call:\u001b[39;00m\n\u001b[0;32m 69\u001b[0m \u001b[38;5;66;03m# `tf.debugging.disable_traceback_filtering()`\u001b[39;00m\n\u001b[1;32m---> 70\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m e\u001b[38;5;241m.\u001b[39mwith_traceback(filtered_tb) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[0;32m 71\u001b[0m \u001b[38;5;28;01mfinally\u001b[39;00m:\n\u001b[0;32m 72\u001b[0m \u001b[38;5;28;01mdel\u001b[39;00m filtered_tb\n", "File \u001b[1;32mc:\\Users\\VICTUS\\anaconda3\\envs\\GPU\\lib\\site-packages\\tensorflow\\python\\framework\\ops.py:7209\u001b[0m, in \u001b[0;36mraise_from_not_ok_status\u001b[1;34m(e, name)\u001b[0m\n\u001b[0;32m 7207\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mraise_from_not_ok_status\u001b[39m(e, name):\n\u001b[0;32m 7208\u001b[0m e\u001b[38;5;241m.\u001b[39mmessage \u001b[38;5;241m+\u001b[39m\u001b[38;5;241m=\u001b[39m (\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m name: \u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;241m+\u001b[39m name \u001b[38;5;28;01mif\u001b[39;00m name \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m-> 7209\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m core\u001b[38;5;241m.\u001b[39m_status_to_exception(e) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m\n", "\u001b[1;31mUnimplementedError\u001b[0m: Exception encountered when calling layer \"resizing_2\" \" f\"(type Resizing).\n\n{{function_node __wrapped__Cast_device_/job:localhost/replica:0/task:0/device:CPU:0}} Cast string to float is not supported [Op:Cast]\n\nCall arguments received by layer \"resizing_2\" \" f\"(type Resizing):\n • inputs=tf.Tensor(shape=(1,), dtype=string)" ] } ], "source": [ "predict_next('img.jpg')" ] }, { "cell_type": "code", "execution_count": 234, "metadata": {}, "outputs": [], "source": [ "# Demo modeling\n", "\n", "demo = gr.Interface(\n", " fn=genarate_caption,\n", " inputs=['image'],\n", " outputs=['text']\n", ")" ] }, { "cell_type": "code", "execution_count": 235, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Running on local URL: http://127.0.0.1:7863\n", "\n", "To create a public link, set `share=True` in `launch()`.\n" ] }, { "data": { "text/html": [ "
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [] }, "execution_count": 235, "metadata": {}, "output_type": "execute_result" }, { "name": "stderr", "output_type": "stream", "text": [ "ERROR: Exception in ASGI application\n", "Traceback (most recent call last):\n", " File \"c:\\Users\\VICTUS\\anaconda3\\envs\\GPU\\lib\\site-packages\\uvicorn\\protocols\\http\\httptools_impl.py\", line 401, in run_asgi\n", " result = await app( # type: ignore[func-returns-value]\n", " File \"c:\\Users\\VICTUS\\anaconda3\\envs\\GPU\\lib\\site-packages\\uvicorn\\middleware\\proxy_headers.py\", line 60, in __call__\n", " return await self.app(scope, receive, send)\n", " File \"c:\\Users\\VICTUS\\anaconda3\\envs\\GPU\\lib\\site-packages\\fastapi\\applications.py\", line 1054, in __call__\n", " await super().__call__(scope, receive, send)\n", " File \"c:\\Users\\VICTUS\\anaconda3\\envs\\GPU\\lib\\site-packages\\starlette\\applications.py\", line 113, in __call__\n", " await self.middleware_stack(scope, receive, send)\n", " File \"c:\\Users\\VICTUS\\anaconda3\\envs\\GPU\\lib\\site-packages\\starlette\\middleware\\errors.py\", line 187, in __call__\n", " raise exc\n", " File \"c:\\Users\\VICTUS\\anaconda3\\envs\\GPU\\lib\\site-packages\\starlette\\middleware\\errors.py\", line 165, in __call__\n", " await self.app(scope, receive, _send)\n", " File \"c:\\Users\\VICTUS\\anaconda3\\envs\\GPU\\lib\\site-packages\\gradio\\route_utils.py\", line 761, in __call__\n", " await self.app(scope, receive, send)\n", " File \"c:\\Users\\VICTUS\\anaconda3\\envs\\GPU\\lib\\site-packages\\starlette\\middleware\\exceptions.py\", line 62, in __call__\n", " await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)\n", " File \"c:\\Users\\VICTUS\\anaconda3\\envs\\GPU\\lib\\site-packages\\starlette\\_exception_handler.py\", line 53, in wrapped_app\n", " raise exc\n", " File \"c:\\Users\\VICTUS\\anaconda3\\envs\\GPU\\lib\\site-packages\\starlette\\_exception_handler.py\", line 42, in wrapped_app\n", " await app(scope, receive, sender)\n", " File \"c:\\Users\\VICTUS\\anaconda3\\envs\\GPU\\lib\\site-packages\\starlette\\routing.py\", line 715, in __call__\n", " await self.middleware_stack(scope, receive, send)\n", " File \"c:\\Users\\VICTUS\\anaconda3\\envs\\GPU\\lib\\site-packages\\starlette\\routing.py\", line 735, in app\n", " await route.handle(scope, receive, send)\n", " File \"c:\\Users\\VICTUS\\anaconda3\\envs\\GPU\\lib\\site-packages\\starlette\\routing.py\", line 288, in handle\n", " await self.app(scope, receive, send)\n", " File \"c:\\Users\\VICTUS\\anaconda3\\envs\\GPU\\lib\\site-packages\\starlette\\routing.py\", line 76, in app\n", " await wrap_app_handling_exceptions(app, request)(scope, receive, send)\n", " File \"c:\\Users\\VICTUS\\anaconda3\\envs\\GPU\\lib\\site-packages\\starlette\\_exception_handler.py\", line 53, in wrapped_app\n", " raise exc\n", " File \"c:\\Users\\VICTUS\\anaconda3\\envs\\GPU\\lib\\site-packages\\starlette\\_exception_handler.py\", line 42, in wrapped_app\n", " await app(scope, receive, sender)\n", " File \"c:\\Users\\VICTUS\\anaconda3\\envs\\GPU\\lib\\site-packages\\starlette\\routing.py\", line 74, in app\n", " await response(scope, receive, send)\n", " File \"c:\\Users\\VICTUS\\anaconda3\\envs\\GPU\\lib\\site-packages\\starlette\\responses.py\", line 348, in __call__\n", " await self._handle_simple(send, send_header_only)\n", " File \"c:\\Users\\VICTUS\\anaconda3\\envs\\GPU\\lib\\site-packages\\starlette\\responses.py\", line 377, in _handle_simple\n", " await send({\"type\": \"http.response.body\", \"body\": chunk, \"more_body\": more_body})\n", " File \"c:\\Users\\VICTUS\\anaconda3\\envs\\GPU\\lib\\site-packages\\starlette\\_exception_handler.py\", line 39, in sender\n", " await send(message)\n", " File \"c:\\Users\\VICTUS\\anaconda3\\envs\\GPU\\lib\\site-packages\\starlette\\_exception_handler.py\", line 39, in sender\n", " await send(message)\n", " File \"c:\\Users\\VICTUS\\anaconda3\\envs\\GPU\\lib\\site-packages\\starlette\\middleware\\errors.py\", line 162, in _send\n", " await send(message)\n", " File \"c:\\Users\\VICTUS\\anaconda3\\envs\\GPU\\lib\\site-packages\\uvicorn\\protocols\\http\\httptools_impl.py\", line 536, in send\n", " raise RuntimeError(\"Response content shorter than Content-Length\")\n", "RuntimeError: Response content shorter than Content-Length\n" ] } ], "source": [ "demo.launch()" ] }, { "cell_type": "code", "execution_count": 255, "metadata": {}, "outputs": [], "source": [ "with open('tokenizer.pkl','wb') as f:\n", " pkl.dump(tokenizer,f)" ] }, { "cell_type": "code", "execution_count": 256, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "ename": "NameError", "evalue": "name 'tf' is not defined", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", "Cell \u001b[1;32mIn[1], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[43mtf\u001b[49m\u001b[38;5;241m.\u001b[39m__version__\n", "\u001b[1;31mNameError\u001b[0m: name 'tf' is not defined" ] } ], "source": [ "tf.__version__" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "GPU", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.20" } }, "nbformat": 4, "nbformat_minor": 2 }