dduy193 commited on
Commit
0516286
β€’
1 Parent(s): e5d23d0

Upload folder using huggingface_hub

Browse files
This view is limited to 50 files because it contains too many changes. Β  See raw diff
Files changed (50) hide show
  1. .gitattributes +4 -35
  2. .gitignore +10 -0
  3. ML-MovieGenre.code-workspace +8 -0
  4. README.md +10 -8
  5. app.py +181 -0
  6. frozen_multimodal.ipynb +0 -0
  7. ml1m/content/dataset/genres.txt +18 -0
  8. ml1m/content/dataset/ml1m-images/1.jpg +0 -0
  9. ml1m/content/dataset/ml1m-images/10.jpg +0 -0
  10. ml1m/content/dataset/ml1m-images/100.jpg +0 -0
  11. ml1m/content/dataset/ml1m-images/1000.jpg +0 -0
  12. ml1m/content/dataset/ml1m-images/1003.jpg +0 -0
  13. ml1m/content/dataset/ml1m-images/1004.jpg +0 -0
  14. ml1m/content/dataset/ml1m-images/1005.jpg +0 -0
  15. ml1m/content/dataset/ml1m-images/1006.jpg +0 -0
  16. ml1m/content/dataset/ml1m-images/1007.jpg +0 -0
  17. ml1m/content/dataset/ml1m-images/1008.jpg +0 -0
  18. ml1m/content/dataset/ml1m-images/1009.jpg +0 -0
  19. ml1m/content/dataset/ml1m-images/101.jpg +0 -0
  20. ml1m/content/dataset/ml1m-images/1010.jpg +0 -0
  21. ml1m/content/dataset/ml1m-images/1011.jpg +0 -0
  22. ml1m/content/dataset/ml1m-images/1012.jpg +0 -0
  23. ml1m/content/dataset/ml1m-images/1013.jpg +0 -0
  24. ml1m/content/dataset/ml1m-images/1014.jpg +0 -0
  25. ml1m/content/dataset/ml1m-images/1015.jpg +0 -0
  26. ml1m/content/dataset/ml1m-images/1016.jpg +0 -0
  27. ml1m/content/dataset/ml1m-images/1017.jpg +0 -0
  28. ml1m/content/dataset/ml1m-images/1018.jpg +0 -0
  29. ml1m/content/dataset/ml1m-images/1019.jpg +0 -0
  30. ml1m/content/dataset/ml1m-images/102.jpg +0 -0
  31. ml1m/content/dataset/ml1m-images/1020.jpg +0 -0
  32. ml1m/content/dataset/ml1m-images/1021.jpg +0 -0
  33. ml1m/content/dataset/ml1m-images/1022.jpg +0 -0
  34. ml1m/content/dataset/ml1m-images/1023.jpg +0 -0
  35. ml1m/content/dataset/ml1m-images/1024.jpg +0 -0
  36. ml1m/content/dataset/ml1m-images/1025.jpg +0 -0
  37. ml1m/content/dataset/ml1m-images/1027.jpg +0 -0
  38. ml1m/content/dataset/ml1m-images/1028.jpg +0 -0
  39. ml1m/content/dataset/ml1m-images/1029.jpg +0 -0
  40. ml1m/content/dataset/ml1m-images/103.jpg +0 -0
  41. ml1m/content/dataset/ml1m-images/1030.jpg +0 -0
  42. ml1m/content/dataset/ml1m-images/1031.jpg +0 -0
  43. ml1m/content/dataset/ml1m-images/1032.jpg +0 -0
  44. ml1m/content/dataset/ml1m-images/1033.jpg +0 -0
  45. ml1m/content/dataset/ml1m-images/1034.jpg +0 -0
  46. ml1m/content/dataset/ml1m-images/1035.jpg +0 -0
  47. ml1m/content/dataset/ml1m-images/1036.jpg +0 -0
  48. ml1m/content/dataset/ml1m-images/1037.jpg +0 -0
  49. ml1m/content/dataset/ml1m-images/1038.jpg +0 -0
  50. ml1m/content/dataset/ml1m-images/104.jpg +0 -0
.gitattributes CHANGED
@@ -1,35 +1,4 @@
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
- *.tar filter=lfs diff=lfs merge=lfs -text
29
- *.tflite filter=lfs diff=lfs merge=lfs -text
30
- *.tgz filter=lfs diff=lfs merge=lfs -text
31
- *.wasm filter=lfs diff=lfs merge=lfs -text
32
- *.xz filter=lfs diff=lfs merge=lfs -text
33
- *.zip filter=lfs diff=lfs merge=lfs -text
34
- *.zst filter=lfs diff=lfs merge=lfs -text
35
- *tfevents* filter=lfs diff=lfs merge=lfs -text
 
1
+ # Auto detect text files and perform LF normalization
2
+ * text=auto
3
+ ml1m/content/dataset/ratings.dat filter=lfs diff=lfs merge=lfs -text
4
+ multimodel.pt filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
.gitignore ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ safetensors/target
2
+ safetensors/**/Cargo.lock
3
+ bindings/python/Cargo.lock
4
+ *.bin
5
+ *.h5
6
+ *.msgpack
7
+ *.pt
8
+ *.pdparams
9
+ *.safetensors
10
+ *.npz
ML-MovieGenre.code-workspace ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "folders": [
3
+ {
4
+ "path": "."
5
+ },
6
+ ],
7
+ "settings": {}
8
+ }
README.md CHANGED
@@ -1,12 +1,14 @@
1
  ---
2
- title: Movie-Genres-Multilabel MultiPoro
3
- emoji: πŸš€
4
- colorFrom: indigo
5
- colorTo: yellow
6
- sdk: gradio
7
- sdk_version: 4.12.0
8
  app_file: app.py
9
- pinned: false
 
10
  ---
 
 
 
 
11
 
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
1
  ---
2
+ title: Movie-Genres-Multilabel_MultiPoro
 
 
 
 
 
3
  app_file: app.py
4
+ sdk: gradio
5
+ sdk_version: 3.48.0
6
  ---
7
+ # Poro 2.0: Title-only Sentiment Analysis
8
+
9
+ ## Introduction
10
+ A simple title-only sentiment analysis model using a distilled version of BERT model. The model is trained on the MovieLens1M dataset and achieves a multi-label F1 score of 0.2733 on macro-average and 0.4443 on micro-average.
11
 
12
+ ## Authors
13
+ - Duy Dang - <dduy193.cs@gmail.com>
14
+ - Chien Nguyen - <duychien.work@gmail.com>
app.py ADDED
@@ -0,0 +1,181 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ # coding: utf-8
3
+
4
+ # In[1]:
5
+
6
+
7
+ import torch
8
+ import pandas as pd
9
+ import numpy as np
10
+ import os
11
+ import matplotlib.pyplot as plt
12
+ import gradio as gr
13
+ import warnings
14
+ import streamlit as st
15
+ from PIL import Image
16
+ from transformers import AutoTokenizer, AutoModelForSequenceClassification, DistilBertForSequenceClassification, AutoModelForSeq2SeqLM
17
+ from tqdm import tqdm
18
+ from torchvision import models
19
+ from torchvision.transforms import v2
20
+ from torch.utils.data import Dataset, DataLoader
21
+ from keras.preprocessing import image
22
+ from torchmetrics.classification import MultilabelF1Score
23
+ from sklearn.metrics import average_precision_score, ndcg_score
24
+
25
+
26
+ # In[2]:
27
+
28
+
29
+ warnings.filterwarnings("ignore")
30
+
31
+
32
+ # In[3]:
33
+
34
+
35
+ genres = ["Crime", "Thriller", "Fantasy", "Horror", "Sci-Fi", "Comedy", "Documentary", "Adventure", "Film-Noir", "Animation", "Romance", "Drama", "Western", "Musical", "Action", "Mystery", "War", "Children\'s"]
36
+ mapping = {}
37
+ for i in range(len(genres)):
38
+ mapping[i] = genres[i]
39
+ mapping
40
+
41
+
42
+ # In[4]:
43
+
44
+
45
+ tokenizer_gen = AutoTokenizer.from_pretrained("MBZUAI/LaMini-Flan-T5-248M")
46
+ model_gen = AutoModelForSeq2SeqLM.from_pretrained("MBZUAI/LaMini-Flan-T5-248M")
47
+
48
+ tokenizer1 = AutoTokenizer.from_pretrained("distilbert-base-uncased")
49
+ model1 = DistilBertForSequenceClassification .from_pretrained("distilbert-base-uncased", problem_type="multi_label_classification", num_labels=18)
50
+ model1.config.id2label = mapping
51
+
52
+ tokenizer2 = AutoTokenizer.from_pretrained("dduy193/plot-classification")
53
+ model2 = AutoModelForSequenceClassification.from_pretrained("dduy193/plot-classification")
54
+ model2.config.id2label = mapping
55
+
56
+ model3 = models.resnet101(pretrained=False)
57
+ model3.fc = torch.nn.Linear(2048, len(genres))
58
+
59
+ device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
60
+ model1.to(device)
61
+ model2.to(device)
62
+ model3.to(device)
63
+ model_gen.to(device)
64
+ device
65
+
66
+
67
+ # In[5]:
68
+
69
+
70
+ class Multimodal(torch.nn.Module):
71
+ def __init__(self, model1, model2, model3):
72
+ super().__init__()
73
+ self.model1 = model1
74
+ self.model2 = model2
75
+ self.model3 = model3
76
+ self.fc1 = torch.nn.Linear(18, 18)
77
+ self.fc2 = torch.nn.Linear(18, 18)
78
+ self.fc3 = torch.nn.Linear(18, 18)
79
+
80
+ def forward(self,
81
+ title_input_ids, title_attention_mask,
82
+ plot_input_ids, plot_attention_mask,
83
+ image_input):
84
+ title_output = self.model1(title_input_ids, title_attention_mask)
85
+ plot_output = self.model2(plot_input_ids, plot_attention_mask)
86
+ image_output = self.model3(image_input)
87
+
88
+ title_output = self.fc1(title_output.logits)
89
+ plot_output = self.fc2(plot_output.logits)
90
+ image_output = self.fc3(image_output)
91
+
92
+ output = torch.add(title_output, plot_output)
93
+ output = torch.add(output, image_output)
94
+ return output
95
+
96
+
97
+ # In[6]:
98
+
99
+
100
+ model = Multimodal(model1, model2, model3)
101
+ device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
102
+ model.to(device)
103
+ device
104
+
105
+
106
+ # **_PLEASE INSTALL THE MODEL CHECKPOINT FROM THE LINK IN README.txt_**
107
+
108
+ # In[7]:
109
+
110
+
111
+ model.load_state_dict(torch.load('multimodel.pt'))
112
+ model.eval()
113
+
114
+
115
+ # In[8]:
116
+
117
+
118
+ def generate_plot(title: str, model: AutoModelForSeq2SeqLM, tokenizer: AutoTokenizer, device) -> str:
119
+ quote = 'What is the story of the movie {}?'
120
+ model_gen.to(device)
121
+ model_gen.eval()
122
+
123
+ input_ids = tokenizer(quote.format(title), return_tensors='pt').input_ids.to(device)
124
+ output = model.generate(input_ids, max_length=256, do_sample=True, temperature=0.09)
125
+ return tokenizer.decode(output[0], skip_special_tokens=True)
126
+
127
+
128
+ # In[9]:
129
+
130
+
131
+ def inference(title, image,
132
+ tokenizer1=tokenizer1, tokenizer2=tokenizer2, tokenizer_gen=tokenizer_gen,
133
+ model_gen=model_gen, model=model,
134
+ genres=genres, device=device):
135
+ title_input = tokenizer1(title, return_tensors='pt', padding=True, truncation=True)
136
+ title_input_ids = title_input['input_ids'].to(device)
137
+ title_attention_mask = title_input['attention_mask'].to(device)
138
+
139
+ plot = generate_plot(title, model_gen, tokenizer_gen, device)
140
+ plot_input = tokenizer2(plot, return_tensors='pt', padding=True, truncation=True)
141
+ plot_input_ids = plot_input['input_ids'].to(device)
142
+ plot_attention_mask = plot_input['attention_mask'].to(device)
143
+
144
+ # If image is not uploaded
145
+ if image is None:
146
+ image_input = torch.zeros((1, 3, 224, 224)).to(device)
147
+
148
+ else:
149
+ image_input = image.resize((224, 224))
150
+ image_input = v2.ToTensor()(image_input)
151
+ image_input = image_input.unsqueeze(0)
152
+ image_input = image_input.to(device)
153
+
154
+ output = model(title_input_ids, title_attention_mask, plot_input_ids, plot_attention_mask, image_input)
155
+ output = torch.sigmoid(output)
156
+ output = output.cpu().detach().numpy()
157
+ output = np.where(output > 0.5, 1, 0)
158
+ output = output.squeeze()
159
+ output = np.where(output == 1)[0]
160
+ output = [genres[i] for i in output]
161
+ return output
162
+
163
+
164
+ # In[10]:
165
+
166
+
167
+ app = gr.Interface(fn=inference, inputs=["text", "pil"], outputs="text", title="Movie Genre Classification",
168
+ description="This model classifies the genre of a movie based on its title and poster.",
169
+ examples=[["The Matrix", "https://upload.wikimedia.org/wikipedia/en/c/c1/The_Matrix_Poster.jpg"],
170
+ ["The Dark Knight", "https://upload.wikimedia.org/wikipedia/en/1/1c/The_Dark_Knight_%282008_film%29.jpg"],
171
+ ["The Godfather", "https://upload.wikimedia.org/wikipedia/en/1/1c/Godfather_ver1.jpg"],
172
+ ["The Shawshank Redemption", "https://upload.wikimedia.org/wikipedia/en/8/81/ShawshankRedemptionMoviePoster.jpg"],
173
+ ["The Lord of the Rings: The Return of the King", "https://upload.wikimedia.org/wikipedia/en/2/23/The_Lord_of_the_Rings%2C_TROTK_%282003%29.jpg"],
174
+ ["The Godfather: Part II", "https://upload.wikimedia.org/wikipedia/en/0/03/Godfather_part_ii.jpg"]])
175
+
176
+
177
+ # In[11]:
178
+
179
+
180
+ app.launch(share=True)
181
+
frozen_multimodal.ipynb ADDED
The diff for this file is too large to render. See raw diff
 
ml1m/content/dataset/genres.txt ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Crime
2
+ Thriller
3
+ Fantasy
4
+ Horror
5
+ Sci-Fi
6
+ Comedy
7
+ Documentary
8
+ Adventure
9
+ Film-Noir
10
+ Animation
11
+ Romance
12
+ Drama
13
+ Western
14
+ Musical
15
+ Action
16
+ Mystery
17
+ War
18
+ Children's
ml1m/content/dataset/ml1m-images/1.jpg ADDED
ml1m/content/dataset/ml1m-images/10.jpg ADDED
ml1m/content/dataset/ml1m-images/100.jpg ADDED
ml1m/content/dataset/ml1m-images/1000.jpg ADDED
ml1m/content/dataset/ml1m-images/1003.jpg ADDED
ml1m/content/dataset/ml1m-images/1004.jpg ADDED
ml1m/content/dataset/ml1m-images/1005.jpg ADDED
ml1m/content/dataset/ml1m-images/1006.jpg ADDED
ml1m/content/dataset/ml1m-images/1007.jpg ADDED
ml1m/content/dataset/ml1m-images/1008.jpg ADDED
ml1m/content/dataset/ml1m-images/1009.jpg ADDED
ml1m/content/dataset/ml1m-images/101.jpg ADDED
ml1m/content/dataset/ml1m-images/1010.jpg ADDED
ml1m/content/dataset/ml1m-images/1011.jpg ADDED
ml1m/content/dataset/ml1m-images/1012.jpg ADDED
ml1m/content/dataset/ml1m-images/1013.jpg ADDED
ml1m/content/dataset/ml1m-images/1014.jpg ADDED
ml1m/content/dataset/ml1m-images/1015.jpg ADDED
ml1m/content/dataset/ml1m-images/1016.jpg ADDED
ml1m/content/dataset/ml1m-images/1017.jpg ADDED
ml1m/content/dataset/ml1m-images/1018.jpg ADDED
ml1m/content/dataset/ml1m-images/1019.jpg ADDED
ml1m/content/dataset/ml1m-images/102.jpg ADDED
ml1m/content/dataset/ml1m-images/1020.jpg ADDED
ml1m/content/dataset/ml1m-images/1021.jpg ADDED
ml1m/content/dataset/ml1m-images/1022.jpg ADDED
ml1m/content/dataset/ml1m-images/1023.jpg ADDED
ml1m/content/dataset/ml1m-images/1024.jpg ADDED
ml1m/content/dataset/ml1m-images/1025.jpg ADDED
ml1m/content/dataset/ml1m-images/1027.jpg ADDED
ml1m/content/dataset/ml1m-images/1028.jpg ADDED
ml1m/content/dataset/ml1m-images/1029.jpg ADDED
ml1m/content/dataset/ml1m-images/103.jpg ADDED
ml1m/content/dataset/ml1m-images/1030.jpg ADDED
ml1m/content/dataset/ml1m-images/1031.jpg ADDED
ml1m/content/dataset/ml1m-images/1032.jpg ADDED
ml1m/content/dataset/ml1m-images/1033.jpg ADDED
ml1m/content/dataset/ml1m-images/1034.jpg ADDED
ml1m/content/dataset/ml1m-images/1035.jpg ADDED
ml1m/content/dataset/ml1m-images/1036.jpg ADDED
ml1m/content/dataset/ml1m-images/1037.jpg ADDED
ml1m/content/dataset/ml1m-images/1038.jpg ADDED
ml1m/content/dataset/ml1m-images/104.jpg ADDED