Upload 6 files
Browse files- .gitignore +46 -0
- app.py +132 -0
- get_data.py +24 -0
- preprocess_images.py +158 -0
- requirements.txt +68 -0
- setup.py +10 -0
.gitignore
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Byte-compiled / optimized / DLL files
|
2 |
+
__pycache__/
|
3 |
+
*.py[cod]
|
4 |
+
*$py.class
|
5 |
+
|
6 |
+
# Distribution / packaging
|
7 |
+
.Python
|
8 |
+
build/
|
9 |
+
develop-eggs/
|
10 |
+
dist/
|
11 |
+
*.egg-info/
|
12 |
+
*.egg
|
13 |
+
|
14 |
+
# Flask stuff:
|
15 |
+
instance/
|
16 |
+
.webassets-cache
|
17 |
+
|
18 |
+
data/
|
19 |
+
|
20 |
+
# Jupyter Notebook
|
21 |
+
.ipynb_checkpoints
|
22 |
+
|
23 |
+
# IPython
|
24 |
+
profile_default/
|
25 |
+
ipython_config.py
|
26 |
+
|
27 |
+
# pyenv
|
28 |
+
.python-version
|
29 |
+
|
30 |
+
# pipenv
|
31 |
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
32 |
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
33 |
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
34 |
+
# install all needed dependencies.
|
35 |
+
#Pipfile.lock
|
36 |
+
|
37 |
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
38 |
+
__pypackages__/
|
39 |
+
|
40 |
+
# Environments
|
41 |
+
.env/
|
42 |
+
|
43 |
+
2008.02693.pdf
|
44 |
+
images/original_demo.avi
|
45 |
+
images/better_quality_demo.gif
|
46 |
+
|
app.py
ADDED
@@ -0,0 +1,132 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from transformers import Blip2ForConditionalGeneration
|
2 |
+
from transformers import Blip2Processor
|
3 |
+
from peft import PeftModel
|
4 |
+
import streamlit as st
|
5 |
+
from PIL import Image
|
6 |
+
#import torch
|
7 |
+
import os
|
8 |
+
|
9 |
+
preprocess_ckp = "Salesforce/blip2-opt-2.7b" #Checkpoint path used for perprocess image
|
10 |
+
base_model_ckp = "./model/blip2-opt-2.7b-fp16-sharded" #Base model checkpoint path
|
11 |
+
peft_model_ckp = "./model/blip2_peft" #PEFT model checkpoint path
|
12 |
+
sample_img_path = "./sample_images"
|
13 |
+
|
14 |
+
map_sampleid_name = {
|
15 |
+
'dress' : '00fe223d-9d1f-4bd3-a556-7ece9d28e6fb.jpeg',
|
16 |
+
'earrings': '0b3862ae-f89e-419c-bc1e-57418abd4180.jpeg',
|
17 |
+
'sweater': '0c21ba7b-ceb6-4136-94a4-1d4394499986.jpeg',
|
18 |
+
'sunglasses': '0e44ec10-e53b-473a-a77f-ac8828bb5e01.jpeg',
|
19 |
+
'shoe': '4cd37d6d-e7ea-4c6e-aab2-af700e480bc1.jpeg',
|
20 |
+
'hat': '69aeb517-c66c-47b8-af7d-bdf1fde57ed0.jpeg',
|
21 |
+
'heels':'447abc42-6ac7-4458-a514-bdcd570b1cd1.jpeg',
|
22 |
+
'socks': 'd188836c-b734-4031-98e5-423d5ff1239d.jpeg',
|
23 |
+
'tee': 'e2d8637a-5478-429d-a2a8-3d5859dbc64d.jpeg',
|
24 |
+
'bracelet': 'e78518ac-0f54-4483-a233-fad6511f0b86.jpeg'
|
25 |
+
}
|
26 |
+
|
27 |
+
def init_model(init_model_required):
|
28 |
+
|
29 |
+
if init_model_required:
|
30 |
+
|
31 |
+
#Preprocess input
|
32 |
+
processor = Blip2Processor.from_pretrained(preprocess_ckp)
|
33 |
+
|
34 |
+
#Model
|
35 |
+
#Inferance on GPU device. Will give error in CPU system, as "load_in_8bit" is an setting of bitsandbytes library and only works for GPU
|
36 |
+
#model = Blip2ForConditionalGeneration.from_pretrained(base_model_ckp, load_in_8bit = True, device_map = "auto")
|
37 |
+
|
38 |
+
#Inferance on CPU device
|
39 |
+
model = Blip2ForConditionalGeneration.from_pretrained(base_model_ckp)
|
40 |
+
|
41 |
+
model = PeftModel.from_pretrained(model, peft_model_ckp)
|
42 |
+
|
43 |
+
init_model_required = False
|
44 |
+
|
45 |
+
return processor, model, init_model_required
|
46 |
+
|
47 |
+
#def main():
|
48 |
+
|
49 |
+
st.header("Automate Fashion Image Captioning using BLIP-2")
|
50 |
+
st.caption("The fashion industry is worth trillions of dollars. The goal of any company/seller is to help customer tofind the right product from a huge corpus of products that they are searching for.")
|
51 |
+
st.caption("So, when customer find the right product they are mostly going to add the item to their cart and which help in company revenue.")
|
52 |
+
st.caption("Accurate and enchanting descriptions of clothes on shopping websites can help customers without fashion knowledge to better understand the features (attributes, style, functionality, etc.) of the items and increase online sales by enticing more customers.")
|
53 |
+
st.caption("Also, most of the time when any customer visits shopping websites, they are looking for a certain style or type of clothes that wish to purchase, they search for the item by providing a description of the item and the system finds the relevant items that match the search query by computing the similarity score between the query and the item caption.")
|
54 |
+
st.caption("Given the clothes image provide a short caption that describes the item. In general, in image captioning datasets (e.g., COCO, Fliker), the descriptions of fashion items have three unique features, which makes the automatic generation of captions a challenging task. First, fashion captioning needs to describe the attributes of an item, while image captioning generally narrates the objects and their relations in the image.")
|
55 |
+
st.caption("Solution: Used Bootstrapping Language-Image Pre-training with Frozen Image Encoders and Large Language Models [(BLIP-2)](https://huggingface.co/Salesforce/blip2-opt-2.7b) by Salesforce. The original model size was too large. It was quite challenging to fit and fine-tune the model on the 16GB GPU.")
|
56 |
+
st.caption("So, for this project have downloaded the pre-trained model [ybelkada/blip2-opt-2.7b-fp16-sharded](https://huggingface.co/ybelkada/blip2-opt-2.7b-fp16-sharded). This model uses OPT-2.7b LLM model with reduced precision to float16.")
|
57 |
+
|
58 |
+
st.caption("For more detail: [Github link](https://github.com/SmithaUpadhyaya/fashion_image_caption)") #write
|
59 |
+
|
60 |
+
#Select few sample images for the catagory of cloths
|
61 |
+
with st.form("app", clear_on_submit = True):
|
62 |
+
|
63 |
+
st.caption("Select image:")
|
64 |
+
|
65 |
+
option = 'None'
|
66 |
+
option = st.selectbox('From sample', ('None', 'dress', 'earrings', 'sweater', 'sunglasses', 'shoe', 'hat', 'heels', 'socks', 'tee', 'bracelet'), index = 0)
|
67 |
+
|
68 |
+
st.text("Or")
|
69 |
+
|
70 |
+
file_name = None
|
71 |
+
file_name = st.file_uploader(label = "Upload an image", accept_multiple_files = False)
|
72 |
+
|
73 |
+
|
74 |
+
btn_click = st.form_submit_button('Generate')
|
75 |
+
st.caption("Application deployed on CPU basic with 16GB RAM")
|
76 |
+
|
77 |
+
if btn_click:
|
78 |
+
|
79 |
+
image = None
|
80 |
+
if file_name is not None:
|
81 |
+
|
82 |
+
image = Image.open(file_name)
|
83 |
+
|
84 |
+
elif option is not 'None':
|
85 |
+
|
86 |
+
file_name = os.path.join(sample_img_path, map_sampleid_name[option])
|
87 |
+
image = Image.open(file_name)
|
88 |
+
|
89 |
+
if image is not None:
|
90 |
+
|
91 |
+
image_col, caption_text = st.columns(2)
|
92 |
+
image_col.header("Image")
|
93 |
+
caption_text.header("Generated Caption")
|
94 |
+
image_col.image(image.resize((252,252)), use_column_width = True)
|
95 |
+
caption_text.text("")
|
96 |
+
|
97 |
+
if 'init_model_required' not in st.session_state:
|
98 |
+
with st.spinner('Initializing model...'):
|
99 |
+
|
100 |
+
init_model_required = True
|
101 |
+
processor, model, init_model_required = init_model(init_model_required)
|
102 |
+
|
103 |
+
#Save session init model in session state
|
104 |
+
if 'init_model_required' not in st.session_state:
|
105 |
+
st.session_state.init_model_required = init_model_required
|
106 |
+
st.session_state.processor = processor
|
107 |
+
st.session_state.model = model
|
108 |
+
else:
|
109 |
+
processor = st.session_state.processor
|
110 |
+
model = st.session_state.model
|
111 |
+
|
112 |
+
with st.spinner('Generating Caption...'):
|
113 |
+
|
114 |
+
#Preprocess the image
|
115 |
+
#Inferance on GPU. When used this on GPU will get errors like: "slow_conv2d_cpu" not implemented for 'Half'" , " Input type (float) and bias type (struct c10::Half)"
|
116 |
+
#inputs = processor(images = image, return_tensors = "pt").to('cuda', torch.float16)
|
117 |
+
|
118 |
+
#Inferance on CPU
|
119 |
+
inputs = processor(images = image, return_tensors = "pt")
|
120 |
+
|
121 |
+
pixel_values = inputs.pixel_values
|
122 |
+
|
123 |
+
#Predict the caption for the imahe
|
124 |
+
generated_ids = model.generate(pixel_values = pixel_values, max_length = 10)
|
125 |
+
generated_caption = processor.batch_decode(generated_ids, skip_special_tokens = True)[0]
|
126 |
+
|
127 |
+
#Output the predict text
|
128 |
+
caption_text.text(generated_caption)
|
129 |
+
|
130 |
+
|
131 |
+
#if __name__ == "__main__":
|
132 |
+
# main()
|
get_data.py
ADDED
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import src.process_json_data as pj
|
2 |
+
import argparse
|
3 |
+
|
4 |
+
"""
|
5 |
+
Script to download the image from imageurl and convert json file to .parquet file
|
6 |
+
"""
|
7 |
+
|
8 |
+
if __name__ == '__main__':
|
9 |
+
|
10 |
+
ap = argparse.ArgumentParser()
|
11 |
+
ap.add_argument("-n", "--noofrecords", required = True, type=int, help = "Number of records to read from json file")
|
12 |
+
args = vars(ap.parse_args())
|
13 |
+
|
14 |
+
read_records = args["noofrecords"]
|
15 |
+
|
16 |
+
numbers_records = pj.read_data(read_records)
|
17 |
+
|
18 |
+
if numbers_records == 0:
|
19 |
+
|
20 |
+
print('No records to process found')
|
21 |
+
|
22 |
+
else:
|
23 |
+
|
24 |
+
print(f'Sucessfully processed: {numbers_records} of raw data and saved at "{pj.processed_data}" file')
|
preprocess_images.py
ADDED
@@ -0,0 +1,158 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from multiprocessing import cpu_count
|
2 |
+
from multiprocessing import Pool
|
3 |
+
import src.process_image as pi
|
4 |
+
import pyarrow.parquet as pq
|
5 |
+
from tqdm import tqdm
|
6 |
+
import pandas as pd
|
7 |
+
import argparse
|
8 |
+
import math
|
9 |
+
import gc
|
10 |
+
import os
|
11 |
+
|
12 |
+
"""
|
13 |
+
########################## Script to Pre-process image files by converting them to numpy array and save numpy arrays to hdf5 format #####################
|
14 |
+
Working on limtted RAM resource, so convert 18k images into numpy array and them to hdf5 always caused "OutofMemory" error. Also convert 18k too long time.
|
15 |
+
Faced memory issue to load entire the .parquet file as well.
|
16 |
+
|
17 |
+
Solution took:
|
18 |
+
-> Load .parquet file:
|
19 |
+
Read data from parquet file in batch of N. N batch of records are sent to process.
|
20 |
+
-> Process image to numpy:
|
21 |
+
Create Shared Memory based on the batch size and the space need for an image. So shared memory size will be = N * image_size
|
22 |
+
Used Shared Memory that can now store N image at a time. Any more then that Shared Memory was not created and will give OutOfMemory error.
|
23 |
+
Image size was too large, so convert image to numpy will also be large.
|
24 |
+
While experiment found 300 batch size was ideal
|
25 |
+
We created shared memory only once and after each batch of N we clean up the shared memory to store next batch process data
|
26 |
+
-> Create pool of process, each process write to shared memory.
|
27 |
+
-> End of each batch N data we created a .hdf5. So by end of the script we will have (Num_Records/N) .hdf5 files
|
28 |
+
-> Now we combine each .hdf5 into single .hdf5
|
29 |
+
"""
|
30 |
+
###################################################################################################
|
31 |
+
|
32 |
+
#Since we do not know the number of batch it will generted for any give dataset file. We shall created a generator to loop thrught and show a progress
|
33 |
+
def generator():
|
34 |
+
while True:
|
35 |
+
yield
|
36 |
+
|
37 |
+
if __name__ == "__main__":
|
38 |
+
|
39 |
+
# construct the argument parser and parse the arguments
|
40 |
+
ap = argparse.ArgumentParser()
|
41 |
+
#ap.add_argument("-i", "--images", required = True, type = str, help = "base path to directory containing of images")
|
42 |
+
ap.add_argument("-d", "--proc_data", required = False, type = str, default = '\data\\processed\\test_data.parquet' ,help = "filename with path, of dataset who's images need to be converted to numpy array")
|
43 |
+
ap.add_argument("-p", "--procs", type = int, default = -1, help = "# of processes to spin up")
|
44 |
+
#ap.add_argument("-r", "--datarng", type = str, default = '0:100', help = "range of records to process")
|
45 |
+
ap.add_argument("-b", "--batch_size", type = int, default = 250, help = "chunk/batch size to read data from file")
|
46 |
+
ap.add_argument("-a", "--action_type", type = int, default = 1, help = "action script will perform. 1-> convert image to numpy and combine files. 2-> combine the files. 3-> convert image to numpy")
|
47 |
+
args = vars(ap.parse_args())
|
48 |
+
|
49 |
+
# determine the number of concurrent processes to launch when
|
50 |
+
# distributing the load across the system, then create the list
|
51 |
+
# of process IDs
|
52 |
+
NUM_WORKERS = args["procs"] if args["procs"] > 0 else cpu_count()
|
53 |
+
|
54 |
+
#IMAGE_BASE_FOLDER = args["images"] #data\\images. Since we run in parallel process, We can not init this variable for each process. So defined it global
|
55 |
+
DATA_TO_PROCESS = args["proc_data"] #data\\processed\\test_data.parquet
|
56 |
+
|
57 |
+
BATCH_SIZE = args["batch_size"] #Batch size
|
58 |
+
|
59 |
+
ACTION_TYPE = args["action_type"]
|
60 |
+
shared_memory_created = False
|
61 |
+
|
62 |
+
try:
|
63 |
+
|
64 |
+
if (ACTION_TYPE == 1) or (ACTION_TYPE == 3):
|
65 |
+
|
66 |
+
print(f'[INFO]: Process to read the {DATA_TO_PROCESS}, convert images to numpy array and store. Started...')
|
67 |
+
|
68 |
+
# When working with large valid(1902 records)/train(18k records) fail to allocate resource for shared memory.
|
69 |
+
# Gave "[WinError 1450] Insufficient system resources exist to complete the requested service"
|
70 |
+
# To over come the issue decided to split the records range and then merge those records i.e pass/read the data in batch
|
71 |
+
|
72 |
+
"""
|
73 |
+
# Code that read range from input argument, then read the entire dataset and then slide the range.
|
74 |
+
# But in this approach first entire file records is loaded, which take memory space and the script fail to allocate shared memory space.
|
75 |
+
# Method 1:
|
76 |
+
RANGE = args["datarng"]
|
77 |
+
start = int(RANGE.split(':')[0])
|
78 |
+
end = int(RANGE.split(':')[1])
|
79 |
+
|
80 |
+
data = pd.read_parquet(DATA_TO_PROCESS)
|
81 |
+
|
82 |
+
if (start > 0) and (end > 0) and (start < end):
|
83 |
+
data = data[start:end]
|
84 |
+
"""
|
85 |
+
#Method 2: Read the data in batch using parquet
|
86 |
+
parquet_file = pq.ParquetFile(DATA_TO_PROCESS)
|
87 |
+
number_of_records = parquet_file.metadata.num_rows
|
88 |
+
start = 0
|
89 |
+
end = 0
|
90 |
+
number_of_batch = math.ceil(number_of_records/BATCH_SIZE)
|
91 |
+
|
92 |
+
with tqdm(total = number_of_batch) as pbar:
|
93 |
+
|
94 |
+
for i in parquet_file.iter_batches(batch_size = BATCH_SIZE):
|
95 |
+
|
96 |
+
end +=BATCH_SIZE
|
97 |
+
RANGE = str(start) + ':' + str(end)
|
98 |
+
data = i.to_pandas()
|
99 |
+
print(f'[INFO]: Process data range {RANGE} started.')
|
100 |
+
|
101 |
+
img_shm, img_id_shm = pi.create_shared_memory_nparray(data.shape[0], shared_memory_created)
|
102 |
+
shared_memory_created = True
|
103 |
+
print('[INFO]: Sucessfully created shared memory resource.')
|
104 |
+
|
105 |
+
process_args = list(zip(range(0, data.shape[0]), data['id'], data['image_name'], [data.shape[0]] * data.shape[0]))
|
106 |
+
|
107 |
+
print('[INFO]: Starting Pool process...')
|
108 |
+
with Pool(NUM_WORKERS) as pror_pool:
|
109 |
+
|
110 |
+
#tqdm with pool not helpfull
|
111 |
+
#for _ in tqdm(pror_pool.map(pi.process_images, process_args), total = data.shape[0]):
|
112 |
+
# pass
|
113 |
+
pror_pool.map(pi.process_images, process_args)
|
114 |
+
|
115 |
+
print('[INFO]: Started saving data to hdf5 format...')
|
116 |
+
hdf5_filename, filename = os.path.split(DATA_TO_PROCESS)
|
117 |
+
|
118 |
+
hdf5_filename = os.path.join(hdf5_filename, filename.split('.')[0] + '_' + RANGE.replace(':','_') + '.h5')
|
119 |
+
pi.save_to_hdf(hdf5_filename, data.shape[0])
|
120 |
+
|
121 |
+
print(f'[INFO]: Process data range {RANGE} completed.')
|
122 |
+
start = end
|
123 |
+
del [data]
|
124 |
+
pbar.update(1)
|
125 |
+
|
126 |
+
|
127 |
+
print('[INFO]: Process to convert images to numpy array and store in seperate files. Completed.')
|
128 |
+
|
129 |
+
if (ACTION_TYPE == 1) or (ACTION_TYPE == 2):
|
130 |
+
|
131 |
+
print('[INFO]: Combine multiple hdf5 files into one started...')
|
132 |
+
|
133 |
+
path, name = os.path.split(DATA_TO_PROCESS)
|
134 |
+
name = name.split('.')[0]
|
135 |
+
pi.combine_multiple_hdf(name, path)
|
136 |
+
|
137 |
+
|
138 |
+
except Exception as e:
|
139 |
+
|
140 |
+
print(f'Error Occured: {e}')
|
141 |
+
|
142 |
+
finally:
|
143 |
+
|
144 |
+
if shared_memory_created:
|
145 |
+
pi.release_shared_memory()
|
146 |
+
|
147 |
+
gc.collect()
|
148 |
+
|
149 |
+
print('[INFO]: Script execution completed.')
|
150 |
+
|
151 |
+
############################################################333
|
152 |
+
#Sample code
|
153 |
+
#python preprocess_images.py -d data\processed\test_data.parquet
|
154 |
+
#python preprocess_images.py -d data\processed\validate_data.parquet -r 0:100
|
155 |
+
#python preprocess_images.py -d data\processed\validate_data.parquet
|
156 |
+
#python preprocess_images.py -d data\processed\validate_data.parquet -b 300
|
157 |
+
#python preprocess_images.py -d data\processed\train_data.parquet -b 300 -a 2
|
158 |
+
|
requirements.txt
ADDED
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# local package
|
2 |
+
-e .
|
3 |
+
|
4 |
+
#Python Version 3.7.9
|
5 |
+
# external requirements
|
6 |
+
|
7 |
+
#General Library
|
8 |
+
pandas==1.3.5
|
9 |
+
numpy==1.20
|
10 |
+
tqdm
|
11 |
+
|
12 |
+
pyarrow==8.0.0 #Required to work with parquet file type. These is one engine that is used for parquet file
|
13 |
+
fastparquet==0.8.1 #Required to work with parquet file type. This is also one engine that is used for parquet file
|
14 |
+
|
15 |
+
#Download the image from web using imageurl
|
16 |
+
requests==2.28.2
|
17 |
+
|
18 |
+
#Not required since in the end worked with jpeg file only.
|
19 |
+
#Since found that hdf5 was large and taking much time to read image data from hdf5, compare to jpeg file for each image
|
20 |
+
#h5py==3.8.0 #Read and Save numpy data in hdf5.
|
21 |
+
|
22 |
+
#Library for EDA
|
23 |
+
ipywidgets
|
24 |
+
opencv-python==4.5.4.60
|
25 |
+
matplotlib==3.5.3
|
26 |
+
seaborn==0.12.2
|
27 |
+
WordCloud
|
28 |
+
|
29 |
+
#Pre-process text library
|
30 |
+
#pycontractions #Does not work with py3.9. So copied the code from there github
|
31 |
+
nltk==3.8.1
|
32 |
+
|
33 |
+
#Model Library
|
34 |
+
scikit-learn
|
35 |
+
#tensorflow==2.11.0 #Final model BLIP2 does not have TF compatible in HuggingFace. So went with Pytorch
|
36 |
+
|
37 |
+
#Library required for BLIP2 model and VisionEncoderDecoder model
|
38 |
+
rouge_score==0.1.2
|
39 |
+
accelerate==0.20.3
|
40 |
+
transformers==4.30.2 #Help: https://huggingface.co/docs/transformers/v4.20.1/en/installation#installation
|
41 |
+
datasets==2.13.0 #Huggingface dataset, Help: https://huggingface.co/docs/datasets/installation
|
42 |
+
evaluate==0.4.0 #Huggingface evaluate library, Help: https://huggingface.co/docs/evaluate/index
|
43 |
+
peft==0.4.0# #0.4.0 was dev version. In case version is not release. Install using pip install -q git+https://github.com/huggingface/peft.git
|
44 |
+
bitsandbytes==0.39.0
|
45 |
+
pytorch==2.0.0
|
46 |
+
|
47 |
+
#Deploy
|
48 |
+
streamlit==1.16.0
|
49 |
+
|
50 |
+
#Step 1 Create a Virtual enviroment with VSCode inside project folder
|
51 |
+
#py -<<python_version>> -m venv <<your_environment_name>>
|
52 |
+
|
53 |
+
#Step 2 Activate the Virtual Environment by calling Activate.bat
|
54 |
+
#\<<your_environment_name>>\Scripts\Activate.bat
|
55 |
+
|
56 |
+
#Step 3: Select this Environment as Interpreatr in VScode
|
57 |
+
#-> Ctrl+Shift+P
|
58 |
+
#-> Select from drop down or type : "Python: Select Interpreter"
|
59 |
+
#-> Select "Enter interpreter path..."
|
60 |
+
#-> Select "Find.." and browse to folder and select" \Scripts\python.exe" in the new environment folder that we created.
|
61 |
+
|
62 |
+
#Step 4: [Optional]: Upgrade pip in your_enviroment
|
63 |
+
#-> Open the Terminal
|
64 |
+
#-> Terminal should show <<your_environment_name>> in the command line. If not execute Step 2 again
|
65 |
+
#-> pip install pip --upgrade
|
66 |
+
|
67 |
+
#Step 5: Install the requirement dll
|
68 |
+
#pip install -r requirements.txt
|
setup.py
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from setuptools import find_packages, setup
|
2 |
+
|
3 |
+
setup(
|
4 |
+
name = 'Fashion_Image_Captioning',
|
5 |
+
packages = find_packages(),
|
6 |
+
version = '2.1.2',
|
7 |
+
description='Fashion Image Captioning trained using HuggingFace Transfromer Library, PEFT, LoRA',
|
8 |
+
author = 'USmitha',
|
9 |
+
license = 'MIT',
|
10 |
+
)
|