Harthika2004 V2004 commited on
Commit
31d8d12
0 Parent(s):

Duplicate from V2004/AutoPoem-Generator

Browse files

Co-authored-by: Manikandan A <V2004@users.noreply.huggingface.co>

.gitattributes ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tflite filter=lfs diff=lfs merge=lfs -text
29
+ *.tgz filter=lfs diff=lfs merge=lfs -text
30
+ *.wasm filter=lfs diff=lfs merge=lfs -text
31
+ *.xz filter=lfs diff=lfs merge=lfs -text
32
+ *.zip filter=lfs diff=lfs merge=lfs -text
33
+ *.zst filter=lfs diff=lfs merge=lfs -text
34
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
35
+ example/flower.png filter=lfs diff=lfs merge=lfs -text
36
+ saved_vocabulary/vocab_coco.file filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Auto Poem Generator
3
+ emoji: 💻
4
+ colorFrom: red
5
+ colorTo: yellow
6
+ sdk: streamlit
7
+ sdk_version: 1.21.0
8
+ app_file: app.py
9
+ pinned: false
10
+ duplicated_from: V2004/AutoPoem-Generator
11
+ ---
12
+
13
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app.py ADDED
@@ -0,0 +1,430 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import io
2
+ import os
3
+ import re
4
+ import pickle
5
+ import base64
6
+ import tensorflow as tf
7
+ import pandas as pd
8
+ import numpy as np
9
+ import streamlit as st
10
+ import requests
11
+ import nltk
12
+ from PIL import Image
13
+ from poetpy import get_poetry
14
+ from nltk.corpus import stopwords
15
+ nltk.download('stopwords')
16
+
17
+ # CONTANTS
18
+ MAX_LENGTH = 40
19
+ # VOCABULARY_SIZE = 10000
20
+ BATCH_SIZE = 32
21
+ BUFFER_SIZE = 1000
22
+ EMBEDDING_DIM = 512
23
+ UNITS = 512
24
+
25
+
26
+ # LOADING DATA
27
+ vocab = pickle.load(open('saved_vocabulary/vocab_coco.file', 'rb'))
28
+
29
+ tokenizer = tf.keras.layers.TextVectorization(
30
+ # max_tokens=VOCABULARY_SIZE,
31
+ standardize=None,
32
+ output_sequence_length=MAX_LENGTH,
33
+ vocabulary=vocab
34
+ )
35
+
36
+ idx2word = tf.keras.layers.StringLookup(
37
+ mask_token="",
38
+ vocabulary=tokenizer.get_vocabulary(),
39
+ invert=True
40
+ )
41
+
42
+
43
+ # MODEL
44
+ def CNN_Encoder():
45
+ inception_v3 = tf.keras.applications.InceptionV3(
46
+ include_top=False,
47
+ weights='imagenet'
48
+ )
49
+
50
+ output = inception_v3.output
51
+ output = tf.keras.layers.Reshape(
52
+ (-1, output.shape[-1]))(output)
53
+
54
+ cnn_model = tf.keras.models.Model(inception_v3.input, output)
55
+ return cnn_model
56
+
57
+
58
+ class TransformerEncoderLayer(tf.keras.layers.Layer):
59
+
60
+ def __init__(self, embed_dim, num_heads):
61
+ super().__init__()
62
+ self.layer_norm_1 = tf.keras.layers.LayerNormalization()
63
+ self.layer_norm_2 = tf.keras.layers.LayerNormalization()
64
+ self.attention = tf.keras.layers.MultiHeadAttention(
65
+ num_heads=num_heads, key_dim=embed_dim)
66
+ self.dense = tf.keras.layers.Dense(embed_dim, activation="relu")
67
+
68
+
69
+ def call(self, x, training):
70
+ x = self.layer_norm_1(x)
71
+ x = self.dense(x)
72
+
73
+ attn_output = self.attention(
74
+ query=x,
75
+ value=x,
76
+ key=x,
77
+ attention_mask=None,
78
+ training=training
79
+ )
80
+
81
+ x = self.layer_norm_2(x + attn_output)
82
+ return x
83
+
84
+
85
+ class Embeddings(tf.keras.layers.Layer):
86
+
87
+ def __init__(self, vocab_size, embed_dim, max_len):
88
+ super().__init__()
89
+ self.token_embeddings = tf.keras.layers.Embedding(
90
+ vocab_size, embed_dim)
91
+ self.position_embeddings = tf.keras.layers.Embedding(
92
+ max_len, embed_dim, input_shape=(None, max_len))
93
+
94
+
95
+ def call(self, input_ids):
96
+ length = tf.shape(input_ids)[-1]
97
+ position_ids = tf.range(start=0, limit=length, delta=1)
98
+ position_ids = tf.expand_dims(position_ids, axis=0)
99
+
100
+ token_embeddings = self.token_embeddings(input_ids)
101
+ position_embeddings = self.position_embeddings(position_ids)
102
+
103
+ return token_embeddings + position_embeddings
104
+
105
+
106
+ class TransformerDecoderLayer(tf.keras.layers.Layer):
107
+
108
+ def __init__(self, embed_dim, units, num_heads):
109
+ super().__init__()
110
+ self.embedding = Embeddings(
111
+ tokenizer.vocabulary_size(), embed_dim, MAX_LENGTH)
112
+
113
+ self.attention_1 = tf.keras.layers.MultiHeadAttention(
114
+ num_heads=num_heads, key_dim=embed_dim, dropout=0.1
115
+ )
116
+ self.attention_2 = tf.keras.layers.MultiHeadAttention(
117
+ num_heads=num_heads, key_dim=embed_dim, dropout=0.1
118
+ )
119
+
120
+ self.layernorm_1 = tf.keras.layers.LayerNormalization()
121
+ self.layernorm_2 = tf.keras.layers.LayerNormalization()
122
+ self.layernorm_3 = tf.keras.layers.LayerNormalization()
123
+
124
+ self.ffn_layer_1 = tf.keras.layers.Dense(units, activation="relu")
125
+ self.ffn_layer_2 = tf.keras.layers.Dense(embed_dim)
126
+
127
+ self.out = tf.keras.layers.Dense(tokenizer.vocabulary_size(), activation="softmax")
128
+
129
+ self.dropout_1 = tf.keras.layers.Dropout(0.3)
130
+ self.dropout_2 = tf.keras.layers.Dropout(0.5)
131
+
132
+
133
+ def call(self, input_ids, encoder_output, training, mask=None):
134
+ embeddings = self.embedding(input_ids)
135
+
136
+ combined_mask = None
137
+ padding_mask = None
138
+
139
+ if mask is not None:
140
+ causal_mask = self.get_causal_attention_mask(embeddings)
141
+ padding_mask = tf.cast(mask[:, :, tf.newaxis], dtype=tf.int32)
142
+ combined_mask = tf.cast(mask[:, tf.newaxis, :], dtype=tf.int32)
143
+ combined_mask = tf.minimum(combined_mask, causal_mask)
144
+
145
+ attn_output_1 = self.attention_1(
146
+ query=embeddings,
147
+ value=embeddings,
148
+ key=embeddings,
149
+ attention_mask=combined_mask,
150
+ training=training
151
+ )
152
+
153
+ out_1 = self.layernorm_1(embeddings + attn_output_1)
154
+
155
+ attn_output_2 = self.attention_2(
156
+ query=out_1,
157
+ value=encoder_output,
158
+ key=encoder_output,
159
+ attention_mask=padding_mask,
160
+ training=training
161
+ )
162
+
163
+ out_2 = self.layernorm_2(out_1 + attn_output_2)
164
+
165
+ ffn_out = self.ffn_layer_1(out_2)
166
+ ffn_out = self.dropout_1(ffn_out, training=training)
167
+ ffn_out = self.ffn_layer_2(ffn_out)
168
+
169
+ ffn_out = self.layernorm_3(ffn_out + out_2)
170
+ ffn_out = self.dropout_2(ffn_out, training=training)
171
+ preds = self.out(ffn_out)
172
+ return preds
173
+
174
+
175
+ def get_causal_attention_mask(self, inputs):
176
+ input_shape = tf.shape(inputs)
177
+ batch_size, sequence_length = input_shape[0], input_shape[1]
178
+ i = tf.range(sequence_length)[:, tf.newaxis]
179
+ j = tf.range(sequence_length)
180
+ mask = tf.cast(i >= j, dtype="int32")
181
+ mask = tf.reshape(mask, (1, input_shape[1], input_shape[1]))
182
+ mult = tf.concat(
183
+ [tf.expand_dims(batch_size, -1), tf.constant([1, 1], dtype=tf.int32)],
184
+ axis=0
185
+ )
186
+ return tf.tile(mask, mult)
187
+
188
+
189
+ class ImageCaptioningModel(tf.keras.Model):
190
+
191
+ def __init__(self, cnn_model, encoder, decoder, image_aug=None):
192
+ super().__init__()
193
+ self.cnn_model = cnn_model
194
+ self.encoder = encoder
195
+ self.decoder = decoder
196
+ self.image_aug = image_aug
197
+ self.loss_tracker = tf.keras.metrics.Mean(name="loss")
198
+ self.acc_tracker = tf.keras.metrics.Mean(name="accuracy")
199
+
200
+
201
+ def calculate_loss(self, y_true, y_pred, mask):
202
+ loss = self.loss(y_true, y_pred)
203
+ mask = tf.cast(mask, dtype=loss.dtype)
204
+ loss *= mask
205
+ return tf.reduce_sum(loss) / tf.reduce_sum(mask)
206
+
207
+
208
+ def calculate_accuracy(self, y_true, y_pred, mask):
209
+ accuracy = tf.equal(y_true, tf.argmax(y_pred, axis=2))
210
+ accuracy = tf.math.logical_and(mask, accuracy)
211
+ accuracy = tf.cast(accuracy, dtype=tf.float32)
212
+ mask = tf.cast(mask, dtype=tf.float32)
213
+ return tf.reduce_sum(accuracy) / tf.reduce_sum(mask)
214
+
215
+
216
+ def compute_loss_and_acc(self, img_embed, captions, training=True):
217
+ encoder_output = self.encoder(img_embed, training=True)
218
+ y_input = captions[:, :-1]
219
+ y_true = captions[:, 1:]
220
+ mask = (y_true != 0)
221
+ y_pred = self.decoder(
222
+ y_input, encoder_output, training=True, mask=mask
223
+ )
224
+ loss = self.calculate_loss(y_true, y_pred, mask)
225
+ acc = self.calculate_accuracy(y_true, y_pred, mask)
226
+ return loss, acc
227
+
228
+
229
+ def train_step(self, batch):
230
+ imgs, captions = batch
231
+
232
+ if self.image_aug:
233
+ imgs = self.image_aug(imgs)
234
+
235
+ img_embed = self.cnn_model(imgs)
236
+
237
+ with tf.GradientTape() as tape:
238
+ loss, acc = self.compute_loss_and_acc(
239
+ img_embed, captions
240
+ )
241
+
242
+ train_vars = (
243
+ self.encoder.trainable_variables + self.decoder.trainable_variables
244
+ )
245
+ grads = tape.gradient(loss, train_vars)
246
+ self.optimizer.apply_gradients(zip(grads, train_vars))
247
+ self.loss_tracker.update_state(loss)
248
+ self.acc_tracker.update_state(acc)
249
+
250
+ return {"loss": self.loss_tracker.result(), "acc": self.acc_tracker.result()}
251
+
252
+
253
+ def test_step(self, batch):
254
+ imgs, captions = batch
255
+
256
+ img_embed = self.cnn_model(imgs)
257
+
258
+ loss, acc = self.compute_loss_and_acc(
259
+ img_embed, captions, training=False
260
+ )
261
+
262
+ self.loss_tracker.update_state(loss)
263
+ self.acc_tracker.update_state(acc)
264
+
265
+ return {"loss": self.loss_tracker.result(), "acc": self.acc_tracker.result()}
266
+
267
+ @property
268
+ def metrics(self):
269
+ return [self.loss_tracker, self.acc_tracker]
270
+
271
+
272
+ def load_image_from_path(img_path):
273
+ img = tf.io.read_file(img_path)
274
+ img = tf.io.decode_jpeg(img, channels=3)
275
+ img = tf.keras.layers.Resizing(299, 299)(img)
276
+ img = tf.keras.applications.inception_v3.preprocess_input(img)
277
+ return img
278
+
279
+
280
+ def generate_caption(img, caption_model, add_noise=False):
281
+ if isinstance(img, str):
282
+ img = load_image_from_path(img)
283
+
284
+ if add_noise == True:
285
+ noise = tf.random.normal(img.shape)*0.1
286
+ img = (img + noise)
287
+ img = (img - tf.reduce_min(img))/(tf.reduce_max(img) - tf.reduce_min(img))
288
+
289
+ img = tf.expand_dims(img, axis=0)
290
+ img_embed = caption_model.cnn_model(img)
291
+ img_encoded = caption_model.encoder(img_embed, training=False)
292
+
293
+ y_inp = '[start]'
294
+ for i in range(MAX_LENGTH-1):
295
+ tokenized = tokenizer([y_inp])[:, :-1]
296
+ mask = tf.cast(tokenized != 0, tf.int32)
297
+ pred = caption_model.decoder(
298
+ tokenized, img_encoded, training=False, mask=mask)
299
+
300
+ pred_idx = np.argmax(pred[0, i, :])
301
+ pred_word = idx2word(pred_idx).numpy().decode('utf-8')
302
+ if pred_word == '[end]':
303
+ break
304
+
305
+ y_inp += ' ' + pred_word
306
+
307
+ y_inp = y_inp.replace('[start] ', '')
308
+ return y_inp
309
+
310
+
311
+ def get_caption_model():
312
+ encoder = TransformerEncoderLayer(EMBEDDING_DIM, 1)
313
+ decoder = TransformerDecoderLayer(EMBEDDING_DIM, UNITS, 8)
314
+
315
+ cnn_model = CNN_Encoder()
316
+
317
+ caption_model = ImageCaptioningModel(
318
+ cnn_model=cnn_model, encoder=encoder, decoder=decoder, image_aug=None,
319
+ )
320
+
321
+ def call_fn(batch, training):
322
+ return batch
323
+
324
+ caption_model.call = call_fn
325
+ sample_x, sample_y = tf.random.normal((1, 299, 299, 3)), tf.zeros((1, 40))
326
+
327
+ caption_model((sample_x, sample_y))
328
+
329
+ sample_img_embed = caption_model.cnn_model(sample_x)
330
+ sample_enc_out = caption_model.encoder(sample_img_embed, training=False)
331
+ caption_model.decoder(sample_y, sample_enc_out, training=False)
332
+
333
+ try:
334
+ caption_model.load_weights('saved_models/image_captioning_coco_weights.h5')
335
+ except FileNotFoundError:
336
+ caption_model.load_weights('Image-Captioning/saved_models/image_captioning_coco_weights.h5')
337
+
338
+ return caption_model
339
+
340
+ #part-2
341
+
342
+ @st.cache_resource
343
+ def get_model():
344
+ return get_caption_model()
345
+
346
+ caption_model = get_model()
347
+
348
+ @st.cache_data
349
+ def extract_important_term(caption):
350
+ # Remove stopwords
351
+ stop_words = set(stopwords.words('english'))
352
+ words = caption.lower().split()
353
+ filtered_words = [word for word in words if word not in stop_words]
354
+
355
+ # Find the longest word
356
+ important_term = max(filtered_words, key=len)
357
+
358
+ return important_term
359
+
360
+
361
+ def generate_poem(word, num_lines):
362
+ # Retrieve poetry lines containing the given word
363
+ poetry_lines = get_poetry('lines', word)
364
+
365
+ # Filter out the lines that don't contain the word
366
+ selected_lines = []
367
+ for poem in poetry_lines:
368
+ lines = poem['lines']
369
+ for line in lines:
370
+ if word.lower() in line.lower():
371
+ selected_lines.append(line)
372
+
373
+ # Select num_lines lines from the retrieved poetry lines
374
+ selected_lines = selected_lines[:num_lines]
375
+
376
+ return selected_lines
377
+
378
+
379
+ def predict(term_col, poem_col):
380
+ pred_caption = generate_caption('tmp.jpg', caption_model)
381
+ # Extract the important term
382
+ important_term = extract_important_term(pred_caption)
383
+
384
+ # Generate poem using poetpy
385
+ poem_lines = generate_poem(important_term, num_lines=10)
386
+
387
+ # Display the poem
388
+
389
+ poem_col.markdown('#### Generated Poem:')
390
+ poem_col.markdown('<div class="poem-container">', unsafe_allow_html=True)
391
+ for line in poem_lines:
392
+ poem_col.markdown(f'<div class="poem-line" style="color: #FF4500; background-color: #ADD8E6; padding: 5px; margin-bottom: 5px; font-family: \'Palatino Linotype\', \'Book Antiqua\', Palatino, serif;">{line}</div>', unsafe_allow_html=True)
393
+ poem_col.markdown('</div>', unsafe_allow_html=True)
394
+
395
+
396
+
397
+ st.markdown('<h1 style="text-align:center; font-family:Comic Sans MS; width:fit-content; font-size:3em; color:green; text-shadow: 2px 2px 4px #000000;">AUTO POEM GENERATOR</h1>', unsafe_allow_html=True)
398
+ col1, col2 = st.columns(2)
399
+
400
+ # Image URL input
401
+ img_url = st.text_input(label='Enter Image URL')
402
+
403
+ # Image upload input
404
+ img_upload = st.file_uploader(label='Upload Image', type=['jpg', 'png', 'jpeg'])
405
+
406
+ # Process image and generate poem
407
+ if img_url:
408
+ img = Image.open(requests.get(img_url, stream=True).raw)
409
+ img = img.convert('RGB')
410
+ col1.image(img, caption="Input Image", use_column_width=True)
411
+ img.save('tmp.jpg')
412
+ predict(col1, col2)
413
+
414
+ st.markdown('<center style="opacity: 70%">OR</center>', unsafe_allow_html=True)
415
+
416
+ elif img_upload:
417
+ img = img_upload.read()
418
+ img = Image.open(io.BytesIO(img))
419
+ img = img.convert('RGB')
420
+ col1.image(img, caption="Input Image", use_column_width=True)
421
+ img.save('tmp.jpg')
422
+ predict(col1, col2)
423
+
424
+
425
+ # Remove temporary image file
426
+ if img_url or img_upload:
427
+ os.remove('tmp.jpg')
428
+
429
+
430
+
requirements.txt ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ numpy
2
+ pandas
3
+ pandas_stubs
4
+ Pillow
5
+ requests
6
+ streamlit
7
+ tensorflow
8
+ altair
9
+ poetpy
10
+ nltk
saved_models/image_captioning_coco_weights.h5 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1e84cba7f9b81e113d6cf938f1c03eff9be2f91932edf36ba1d43a14a63eeb23
3
+ size 214197308
saved_models/image_captioning_transformer_weights_2.h5 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e927884d1ad5adc141cdfffb429ba2aba1ad0a1e42e7d9d999972eaf3e5e81e8
3
+ size 201651096
saved_vocabulary/vocab_1.file ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4df22d5dd84bbb3421dfce39b4affd49ba2dc08739627ee9cf036ae17d326d28
3
+ size 860291
saved_vocabulary/vocab_coco.file ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:41e68329402249568d75664e814571ccfb8471da72894cffca32cb534a9ef1ea
3
+ size 1153949