Guia Técnico para Criação e Manipulação de Tensores no PyTorch

Fundamentos do Tensor no PyTorch

O PyTorch é uma bilbioteca de aprendizado profundo que utiliza tensores como sua estrutura de dados primordial. Um tensor é, essencialmente, uma matriz multidimensional contendo elementos de um único tipo de dado. No ecossistema PyTorch, esses tensores são implementados como objetos de uma classe que encapsula não apenas os dados, mas também uma vasta gama de métodos para operações matemáticas e processamento computacional.

Métodos Fundamentais de Criação

Existem diversas maneiras de inicializar tensores, dependendo se você já possui os dados ou se deseja definir apenas a estrutura dimensional:

  • torch.tensor: Cria um tensor a partir de dados existentes (listas, arrays Numpy).
  • torch.Tensor: Frequentemente usado para criar tensores baseados em uma forma (shape) específica, embora seu uso para dados diretos seja menos recomendado que a versão em letra minúscula.
  • Classes específicas como torch.IntTensor ou torch.FloatTensor: Instanciam tensores de tipos predefinidos.
import torch
import numpy as np

# Inicialização a partir de estruturas de dados existentes
def exemplo_criacao_dados():
    # Criando um escalar (0 dimensões)
    escalar = torch.tensor(42)
    print(f"Escalar: {escalar}, Shape: {escalar.shape}, Dim: {len(escalar.shape)}")

    # Convertendo um array NumPy para Tensor
    array_base = np.array([[1.5, 2.8], [3.1, 4.9]])
    tensor_do_np = torch.tensor(array_base)
    print(f"Tensor via NumPy:\n{tensor_do_np}")

    # Criando a partir de uma lista Python (Float32 por padrão)
    lista_valores = [[1, 2], [3, 4]]
    tensor_lista = torch.tensor(lista_valores)
    print(f"Tensor via Lista:\n{tensor_lista}")

# Inicialização por formato e distribuições
def exemplo_criacao_formato():
    # Tensor baseado em distribuição normal (média 0, desvio padrão 1)
    # Formato: 3 linhas e 2 colunas
    dist_normal = torch.randn(3, 2)
    print(f"Distribuição Normal:\n{dist_normal}")

    # Tensor de alta dimensão (Ex: Lote de imagens: Batch, Canais, Altura, Largura)
    lote_imagens = torch.rand(16, 3, 64, 64)
    print(f"Shape do lote: {lote_imagens.shape}")

    # Criando tensores de tipos específicos com valores não inicializados
    tensor_inteiro = torch.IntTensor(2, 2)
    print(f"Tensor Int32:\n{tensor_inteiro}")

if __name__ == '__main__':
    exemplo_criacao_dados()
    exemplo_criacao_formato()

Sequências Numéricas e Reprodutibilidade

Para tarefas que exigem progressões aritméticas ou controle sobre a aleatoriedade, o PyTorch oferece ferramentas de geração linear e gerenciamento de sementes (seeds).

import torch

def gerar_sequencias():
    # Criação com intervalo e passo (start, end, step)
    # Gera valores de 1 a 9 com passo 2
    passo_a_passo = torch.arange(1, 10, 2)
    print(f"Arange: {passo_a_passo}")

    # Criação com número fixo de pontos em um intervalo
    # Gera 5 elementos entre 0 e 1
    espacamento_linear = torch.linspace(0, 1, 5)
    print(f"Linspace: {espacamento_linear}")

def controlar_aleatoriedade():
    # Definir semente para garantir resultados idênticos em execuções distintas
    torch.manual_seed(42)
    
    aleatorio_a = torch.randn(2, 2)
    print(f"Aleatório com Seed 42:\n{aleatorio_a}")
    print(f"Semente Atual: {torch.initial_seed()}")

if __name__ == '__main__':
    gerar_sequencias()
    controlar_aleatoriedade()

Tensores com Valores de Preenchimento Constante

É comum inicializar tensores preenchidos inteiramente com zeros, uns ou um valor específico, seja definidno o formato ou espelhando a estrutura de outro tensor existente.

import torch

def criar_preenchidos():
    # Tensores preenchidos com zero
    zeros_direto = torch.zeros(2, 4)
    
    # Tensores preenchidos com um
    uns_direto = torch.ones(3, 1)

    # Preenchimento com valor customizado
    customizado = torch.full([2, 2], 7.5)
    print(f"Tensor Full:\n{customizado}")

    # Uso da variante '_like' para copiar o formato de outro tensor
    base_tensor = torch.randn(2, 3)
    copia_zeros = torch.zeros_like(base_tensor)
    copia_full = torch.full_like(base_tensor, 99)
    
    print(f"Original Shape: {base_tensor.shape}")
    print(f"Zeros Like Shape: {copia_zeros.shape}")

if __name__ == '__main__':
    criar_preenchidos()

Conversão de Tipos de Dados (Casting)

A precisão dos dados (como float32 vs float64) impacta diretamente o consumo de memória e a performance computacional. O PyTorch permite converter tipos de forma simples.

import torch

def converter_tipos():
    # Inicializa um tensor de inteiros
    meu_tensor = torch.full([2, 2], 5)
    print(f"Tipo inicial: {meu_tensor.dtype}")

    # Conversão usando o método .type()
    tensor_float = meu_tensor.type(torch.FloatTensor)
    print(f"Tipo após .type(): {tensor_float.dtype}")

    # Conversão simplificada usando métodos auxiliares
    tensor_double = meu_tensor.double() # float64
    tensor_long = meu_tensor.long()     # int64
    tensor_short = meu_tensor.short()   # int16
    
    print(f"Conversão rápida para Double: {tensor_double.dtype}")
    print(f"Conversão rápida para Long: {tensor_long.dtype}")

if __name__ == '__main__':
    converter_tipos()

Tags: Pytorch tensores deep-learning machine-learning Python

Publicado em 8-3 09:41