Download src/dataFunctions.py from letgonc/joias: direct link, hf CLI and curl.
- Browser
- Download file 5.48 kB
-
https://huggingface.co/spaces/letgonc/joias/resolve/main/src/dataFunctions.py
- Command line
-
hf download hf://spaces/letgonc/joias/src/dataFunctions.py
-
curl -L -o dataFunctions.py https://huggingface.co/spaces/letgonc/joias/resolve/main/src/dataFunctions.py
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 |