joias / src /dataFunctions.py
letgonc's picture
Deploy inicial - TCC reconhecimento de joias
bf91a4a
Raw History Blame Contribute Delete
5.48 kB
# dataFunctions.py
# Adaptado para português brasileiro com BERTimbau
# Original: Alcalde-Llergo et al. (2025)
import os
import numpy as np
import config
# torch e transformers são usados apenas em getBERTimbauEmbeddings()
# (etapa de treino). O import fica dentro da função para não exigir
# essas dependências pesadas em produção (app de inferência).
def getData(filename):
"""Lê o captions.txt e retorna dicionário {imagem: legenda} e tamanho máximo."""
data = dict()
max_length = 0
with open(filename, 'r', encoding='utf-8') as f:
for line in f.read().split('\n'):
line = line.split()
if len(line) < 2:
continue
image = line[0]
caption = line[1:]
max_length = max(max_length, len(caption))
if image not in data:
data[image] = ' '.join(caption)
max_length += 2 # espaço para tokens START e STOP
return data, max_length
def getLexicon(data):
"""Extrai vocabulário único de todas as legendas."""
lex = set()
for key in data:
[lex.update(d.split()) for d in data[key].split()]
lex.update(config.START.split())
lex.update(config.STOP.split())
return lex
def getDataArrays(data, train_list):
"""Lê lista de imagens e retorna arrays de imagens e legendas com START/STOP."""
images_array = []
captions_array = []
with open(train_list, 'r', encoding='utf-8') as f:
for image in f.read().split('\n'):
image = image.strip()
if not image or image not in data:
continue
images_array.append(image)
captions_array.append(
f'{config.START} {data[image]} {config.STOP}'
)
return images_array, captions_array
def getTokenizers(lex):
"""Cria mapeamentos palavra → índice e índice → palavra."""
idxtoword = {}
wordtoidx = {}
idx = 1
for word in lex:
wordtoidx[word] = idx
idxtoword[idx] = word
idx += 1
return idxtoword, wordtoidx
def getTokensArrays(captions_array, wordtoidx):
"""Converte legendas em sequências de índices numéricos."""
token_captions_array = []
for caption in captions_array:
tokens = []
for word in caption.split():
if word in wordtoidx:
tokens.append(wordtoidx[word])
token_captions_array.append(tokens)
return token_captions_array
def getBERTimbauEmbeddings(lex):
"""
Gera embeddings para cada palavra do vocabulário usando BERTimbau.
BERTimbau é um modelo BERT treinado em português brasileiro
pelo NLP-USP (neuralmind/bert-base-portuguese-cased).
Substitui:
- SBW-vectors-300-min5.txt (espanhol, 300 dims)
- wiki-news-300d-1M.vec (inglês, 300 dims)
Retorna dicionário {palavra: vetor numpy 768 dims}
"""
import torch
from transformers import BertTokenizer, BertModel
print(f'Carregando BERTimbau: {config.EMBEDDING_NAME}')
# Carrega tokenizador e modelo BERTimbau do HuggingFace
tokenizer = BertTokenizer.from_pretrained(config.EMBEDDING_NAME)
model = BertModel.from_pretrained(config.EMBEDDING_NAME)
model.eval() # modo inferência — desativa dropout
embeddings = {}
palavras = list(lex)
print(f'Gerando embeddings para {len(palavras)} palavras...')
with torch.no_grad(): # sem gradiente — economiza memória
for palavra in palavras:
# Tokeniza a palavra individualmente
inputs = tokenizer(
palavra,
return_tensors='pt', # tensores PyTorch
truncation=True,
max_length=10
)
# Gera embedding via BERTimbau
outputs = model(**inputs)
# Média dos tokens como representação da palavra
# last_hidden_state: (1, n_tokens, 768)
vetor = outputs.last_hidden_state.mean(dim=1).squeeze()
embeddings[palavra] = vetor.numpy()
print(f'BERTimbau: {len(embeddings)} embeddings gerados (768 dims)')
return embeddings
def getEmbeddingMatrix(embeddings, vocab_size, wordtoidx):
"""
Monta a matriz de embeddings para inicializar a camada Embedding.
Dimensão: (vocab_size x EMBEDDING_SIZE)
"""
embedding_matrix = np.zeros((vocab_size, config.EMBEDDING_SIZE))
encontrados = 0
for word, i in wordtoidx.items():
vetor = embeddings.get(word)
if vetor is not None:
embedding_matrix[i] = vetor
encontrados += 1
print(f'Embedding matrix: {encontrados}/{len(wordtoidx)} palavras mapeadas')
return embedding_matrix
def getEmbeddings():
"""
Método original do autor — mantido para compatibilidade.
Lê arquivo de embeddings estáticos no formato word2vec.
"""
embeddings = {}
embeddings_path = os.path.join('data', config.EMBEDDING_NAME)
with open(embeddings_path, 'rb') as f:
for line in f:
values = line.split()
word = values[0]
coefs = np.asarray(values[1:], dtype='float32')
embeddings[word] = coefs
print(f'Encontrados {len(embeddings)} word vectors')
return embeddings