vinimoreira commited on
Commit
137c76e
·
verified ·
1 Parent(s): e4a5e85
Files changed (1) hide show
  1. app.py +0 -157
app.py DELETED
@@ -1,157 +0,0 @@
1
- import gradio as gr
2
- import pandas as pd
3
- import numpy as np
4
- import torch
5
- import joblib
6
- import json
7
- import os
8
- import traceback
9
- from transformers import AutoTokenizer, AutoModel
10
- from torch import nn
11
-
12
- # --- 1. DEFINIÇÃO DA ARQUITETURA DO MODELO ---
13
- # Colocamos a classe aqui para que a aplicação seja autocontida.
14
- class RegressionTransformer(nn.Module):
15
- def __init__(self, model_name='neuralmind/bert-base-portuguese-cased'):
16
- super(RegressionTransformer, self).__init__()
17
- self.bert = AutoModel.from_pretrained(model_name)
18
- self.regressor = nn.Sequential(
19
- nn.Dropout(p=0.2),
20
- nn.Linear(self.bert.config.hidden_size, 128),
21
- nn.ReLU(),
22
- nn.Dropout(p=0.2),
23
- nn.Linear(128, 1)
24
- )
25
- def forward(self, input_ids, attention_mask):
26
- outputs = self.bert(input_ids=input_ids, attention_mask=attention_mask)
27
- pooled_output = outputs.pooler_output
28
- return self.regressor(pooled_output)
29
-
30
- # --- 2. CARREGAMENTO DOS ARTEFATOS GLOBAIS ---
31
- # Esta seção é executada uma vez quando a aplicação inicia no Hugging Face Spaces.
32
- print("Carregando artefatos do modelo...")
33
- device = torch.device("cpu")
34
- CACHE_DIR = "./huggingface_cache"
35
-
36
- try:
37
- # Carrega o tokenizador
38
- TOKENIZER_NAME = 'neuralmind/bert-base-portuguese-cased'
39
- tokenizer = AutoTokenizer.from_pretrained(TOKENIZER_NAME, cache_dir=CACHE_DIR)
40
- print("Tokenizador carregado.")
41
-
42
- # Carrega o modelo treinado
43
- MODEL_PATH = './modelo/best_model_state.pth'
44
- model = RegressionTransformer(model_name=TOKENIZER_NAME)
45
- model.load_state_dict(torch.load(MODEL_PATH, map_location=device))
46
- model.to(device)
47
- model.eval()
48
- print("Modelo carregado.")
49
-
50
- # Carrega a lista de features que o modelo espera
51
- FEATURES_PATH = './modelo/model_features.json'
52
- with open(FEATURES_PATH, 'r') as f:
53
- features_dict = json.load(f)
54
- model_features = features_dict['numeric'] + features_dict['categorical']
55
- print("Features do modelo carregadas.")
56
-
57
- except Exception as e:
58
- print("!!!!!! ERRO FATAL AO CARREGAR ARTEFATOS !!!!!!")
59
- traceback.print_exc()
60
- raise e
61
-
62
- # --- 3. FUNÇÃO DE LÓGICA / PREVISÃO ---
63
- # Esta função contém a "inteligência" do back-end.
64
- def predict_price(make, model_name, year, odometer, trim, body, transmission, color, interior):
65
- try:
66
- print(f"Recebida nova predição: {make}, {model_name}, {year}, {odometer}km")
67
-
68
- # Converte os inputs da interface em um DataFrame de uma linha
69
- input_data_dict = {
70
- 'make': make, 'model': model_name, 'year': int(year), 'odometer': float(odometer),
71
- 'trim': trim, 'body': body, 'transmission': transmission,
72
- 'color': color, 'interior': interior
73
- }
74
- input_df = pd.DataFrame([input_data_dict])
75
-
76
- # Aplica a mesma engenharia de features do treinamento
77
- ano_referencia = 2024
78
- input_df['age'] = ano_referencia - input_df['year']
79
- input_df['sale_month'] = 0 # Placeholder
80
- input_df['sale_dayofweek'] = 0 # Placeholder
81
- input_df['sale_dayofyear'] = 0
82
- input_df['make_popularity'] = 0
83
- input_df['model_popularity'] = 0
84
- input_df['km_per_year'] = 0
85
-
86
- # Cria a "frase" textual
87
- def criar_representacao_textual(row):
88
- partes = [f"{coluna}[{str(row[coluna])}]" for coluna in model_features if coluna in row]
89
- return " | ".join(partes)
90
- text_input = input_df.apply(criar_representacao_textual, axis=1).iloc[0]
91
-
92
- # Tokeniza e prepara os tensores
93
- encoded_text = tokenizer.encode_plus(
94
- text_input, max_length=128, return_tensors='pt',
95
- padding='max_length', truncation=True
96
- )
97
- input_ids = encoded_text['input_ids'].to(device)
98
- attention_mask = encoded_text['attention_mask'].to(device)
99
-
100
- # Faz a inferência
101
- with torch.no_grad():
102
- prediction_log = model(input_ids, attention_mask)
103
-
104
- # Pós-processa o resultado
105
- predicted_price = np.expm1(prediction_log.cpu().numpy()[0][0])
106
-
107
- # Formata a string de saída para o usuário
108
- return f"R$ {predicted_price:,.2f}".replace(",", "X").replace(".", ",").replace("X", ".")
109
-
110
- except Exception as e:
111
- print("!!!!!! ERRO DURANTE A PREVISÃO !!!!!!")
112
- traceback.print_exc()
113
- return "Ocorreu um erro. Verifique os logs."
114
-
115
- # --- 4. DEFINIÇÃO DA INTERFACE COM GRADIO ---
116
- # Esta seção define a aparência do "front-end".
117
- with gr.Blocks(theme=gr.themes.Soft(), css="footer {display: none !important}") as demo:
118
- gr.Markdown("# 🚗 FipeFinder AI: Previsão de Preços de Carros Usados")
119
- gr.Markdown("Preencha as características do veículo para receber uma estimativa de preço de mercado baseada em nosso modelo de IA. Este projeto demonstra um pipeline completo de Machine Learning, desde a análise de dados e treinamento de um modelo Transformer até o deploy de uma aplicação interativa.")
120
-
121
- with gr.Row():
122
- with gr.Column(scale=1):
123
- make_input = gr.Dropdown(label="Marca", choices=["Ford", "Chevrolet", "Honda", "Toyota", "Nissan", "Hyundai", "Kia", "BMW", "Mercedes-Benz", "Volkswagen"])
124
- model_input = gr.Textbox(label="Modelo", placeholder="Ex: Ka, Onix, Civic, Corolla...")
125
- year_input = gr.Slider(label="Ano do Modelo", minimum=2000, maximum=2024, step=1, value=2015)
126
-
127
- with gr.Column(scale=1):
128
- odo_input = gr.Number(label="Quilometragem (km)", value=80000)
129
- trim_input = gr.Textbox(label="Versão", placeholder="Ex: SE 1.0, LTZ, EXL...")
130
- body_input = gr.Dropdown(label="Carroceria", choices=["Sedan", "SUV", "Hatchback", "Pickup", "Minivan", "Coupe", "Wagon"])
131
-
132
- with gr.Column(scale=1):
133
- trans_input = gr.Radio(label="Transmissão", choices=["automatic", "manual"], value="automatic")
134
- color_input = gr.Textbox(label="Cor Externa", placeholder="Ex: preto, branco, prata...")
135
- interior_input = gr.Textbox(label="Cor Interior", placeholder="Ex: preto, cinza, bege...")
136
-
137
- predict_btn = gr.Button("Estimar Preço", variant="primary")
138
- output_price = gr.Label(label="Preço Estimado")
139
-
140
- predict_btn.click(
141
- fn=predict_price,
142
- inputs=[make_input, model_input, year_input, odo_input, trim_input, body_input, trans_input, color_input, interior_input],
143
- outputs=output_price
144
- )
145
-
146
- gr.Examples(
147
- examples=[
148
- ["Ford", "Focus", 2013, 75000.0, "SE 2.0", "Hatchback", "automatic", "prata", "preto"],
149
- ["Chevrolet", "Onix", 2018, 90000.0, "LT 1.0", "Hatchback", "manual", "branco", "cinza"],
150
- ["Toyota", "Corolla", 2020, 40000.0, "XEi", "Sedan", "automatic", "preto", "preto"],
151
- ],
152
- inputs=[make_input, model_input, year_input, odo_input, trim_input, body_input, trans_input, color_input, interior_input]
153
- )
154
-
155
- # --- Lançamento da Interface ---
156
- if __name__ == "__main__":
157
- demo.launch()