O TensorFlow é a framework de machine learning de código aberto da Google que suporta tudo, desde reconhecimento de imagem até processamento de linguagem natural. Com a integração de capacidades de IA em cada vez mais aplicações, compreender redes neuronais tornou-se essencial para developers modernos. Este guia aborda a criação de redes neuronais práticas com TensorFlow, na perspetiva de um developer sénior.
Porquê TensorFlow
O TensorFlow destaca-se porque:
- Pronto para produção: Escala de um portátil a um centro de dados
- Ecossistema: Keras, TensorBoard, TFLite, TF.js
- Suporte de hardware: Aceleração por CPU, GPU, TPU
- Opções de deployment: Servidor, mobile, browser, dispositivos edge
- Comunidade: Documentação e exemplos extensos
Configuração
Instalação
# Instalação básica
pip install tensorflow
# Com suporte de GPU (requer CUDA)
pip install tensorflow[and-cuda]
# Para Macs com Apple Silicon
pip install tensorflow-macos tensorflow-metal
# Pacotes adicionais úteis
pip install pandas matplotlib scikit-learn
Verificar a Instalação
import tensorflow as tf
print(f"TensorFlow version: {tf.__version__}")
print(f"GPU available: {tf.config.list_physical_devices('GPU')}")
Configuração de GPU (Opcional)
Para GPUs NVIDIA:
# Instalar o toolkit CUDA (Ubuntu)
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-keyring_1.0-1_all.deb
sudo dpkg -i cuda-keyring_1.0-1_all.deb
sudo apt update
sudo apt install cuda-toolkit-12-0
# Verificar
nvidia-smi
Fundamentos de Redes Neuronais
Conceitos-chave
- Neurónios: Unidades básicas que aplicam pesos, bias e ativação
- Camadas: Conjuntos de neurónios
- Funções de ativação: Transformações não lineares (ReLU, sigmoid)
- Função de loss: Mede o erro de previsão
- Optimizer: Atualiza os pesos para minimizar a loss
- Epochs: Passagens completas pelos dados de treino
Estrutura de um Modelo Simples
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
# Modelo Sequential: camadas empilhadas linearmente
model = keras.Sequential([
layers.Dense(128, activation='relu', input_shape=(784,)),
layers.Dropout(0.2),
layers.Dense(64, activation='relu'),
layers.Dense(10, activation='softmax')
])
# Compile: configurar o treino
model.compile(
optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy']
)
# Summary
model.summary()
Classificação de Imagens (MNIST)
Carregar e Preparar Dados
import tensorflow as tf
from tensorflow import keras
import numpy as np
import matplotlib.pyplot as plt
# Carregar o dataset MNIST
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
# Normalizar valores de píxeis para 0-1
x_train = x_train.astype('float32') / 255.0
x_test = x_test.astype('float32') / 255.0
# Redimensionar para camadas densas: (28, 28) -> (784,)
x_train_flat = x_train.reshape(-1, 784)
x_test_flat = x_test.reshape(-1, 784)
print(f"Training samples: {len(x_train)}")
print(f"Test samples: {len(x_test)}")
print(f"Image shape: {x_train[0].shape}")
Construir e Treinar o Modelo
# Criar modelo
model = keras.Sequential([
layers.Dense(256, activation='relu', input_shape=(784,)),
layers.Dropout(0.3),
layers.Dense(128, activation='relu'),
layers.Dropout(0.3),
layers.Dense(10, activation='softmax')
])
model.compile(
optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy']
)
# Treinar
history = model.fit(
x_train_flat, y_train,
epochs=10,
batch_size=128,
validation_split=0.1,
verbose=1
)
# Avaliar
test_loss, test_accuracy = model.evaluate(x_test_flat, y_test)
print(f"Test accuracy: {test_accuracy:.4f}")
Representar o Histórico de Treino
plt.figure(figsize=(12, 4))
# Accuracy
plt.subplot(1, 2, 1)
plt.plot(history.history['accuracy'], label='Training')
plt.plot(history.history['val_accuracy'], label='Validation')
plt.title('Model Accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend()
# Loss
plt.subplot(1, 2, 2)
plt.plot(history.history['loss'], label='Training')
plt.plot(history.history['val_loss'], label='Validation')
plt.title('Model Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
plt.tight_layout()
plt.savefig('training_history.png')
plt.show()
Redes Neuronais Convolucionais (CNN)
Para dados de imagem, as CNN superam as redes densas:
# Redimensionar para CNN: adicionar dimensão de canal
x_train_cnn = x_train.reshape(-1, 28, 28, 1)
x_test_cnn = x_test.reshape(-1, 28, 28, 1)
# Construir CNN
cnn_model = keras.Sequential([
# Camadas convolucionais
layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activation='relu'),
# Camadas densas
layers.Flatten(),
layers.Dense(64, activation='relu'),
layers.Dropout(0.5),
layers.Dense(10, activation='softmax')
])
cnn_model.compile(
optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy']
)
cnn_model.fit(
x_train_cnn, y_train,
epochs=5,
batch_size=64,
validation_split=0.1
)
# As CNN atingem tipicamente 99%+ de accuracy no MNIST
cnn_model.evaluate(x_test_cnn, y_test)
Transfer Learning
Use modelos pré-treinados para melhores resultados com menos dados:
from tensorflow.keras.applications import MobileNetV2
from tensorflow.keras.preprocessing.image import ImageDataGenerator
# Carregar modelo pré-treinado (sem a camada de classificação do topo)
base_model = MobileNetV2(
weights='imagenet',
include_top=False,
input_shape=(224, 224, 3)
)
# Congelar os pesos do modelo base
base_model.trainable = False
# Adicionar head de classificação personalizada
model = keras.Sequential([
base_model,
layers.GlobalAveragePooling2D(),
layers.Dense(256, activation='relu'),
layers.Dropout(0.5),
layers.Dense(10, activation='softmax') # 10 classes
])
model.compile(
optimizer=keras.optimizers.Adam(learning_rate=0.001),
loss='categorical_crossentropy',
metrics=['accuracy']
)
# Data augmentation para treino
train_datagen = ImageDataGenerator(
rescale=1./255,
rotation_range=20,
width_shift_range=0.2,
height_shift_range=0.2,
horizontal_flip=True,
validation_split=0.2
)
# Carregar as suas próprias imagens
train_generator = train_datagen.flow_from_directory(
'data/train',
target_size=(224, 224),
batch_size=32,
class_mode='categorical',
subset='training'
)
validation_generator = train_datagen.flow_from_directory(
'data/train',
target_size=(224, 224),
batch_size=32,
class_mode='categorical',
subset='validation'
)
# Treinar
model.fit(
train_generator,
epochs=10,
validation_data=validation_generator
)
Guardar e Carregar Modelos
# Guardar o modelo completo
model.save('my_model.keras')
# Carregar modelo
loaded_model = keras.models.load_model('my_model.keras')
# Guardar apenas os weights
model.save_weights('my_model_weights.weights.h5')
# Carregar weights
model.load_weights('my_model_weights.weights.h5')
# Exportar para TensorFlow Serving
model.export('saved_model_dir')
# Converter para TensorFlow Lite (mobile/edge)
converter = tf.lite.TFLiteConverter.from_keras_model(model)
tflite_model = converter.convert()
with open('model.tflite', 'wb') as f:
f.write(tflite_model)
Fazer Previsões
# Previsão única
image = x_test[0:1] # Manter a dimensão do batch
prediction = model.predict(image)
predicted_class = np.argmax(prediction[0])
confidence = prediction[0][predicted_class]
print(f"Predicted: {predicted_class}, Confidence: {confidence:.2%}")
# Previsão em batch
predictions = model.predict(x_test[:100])
predicted_classes = np.argmax(predictions, axis=1)
# Avaliar previsões
from sklearn.metrics import classification_report, confusion_matrix
print(classification_report(y_test[:100], predicted_classes))
Ciclo de Treino Personalizado
Para maior controlo:
# Treino personalizado
model = keras.Sequential([
layers.Dense(128, activation='relu'),
layers.Dense(10, activation='softmax')
])
loss_fn = keras.losses.SparseCategoricalCrossentropy()
optimizer = keras.optimizers.Adam()
# Métricas de treino
train_loss = keras.metrics.Mean()
train_accuracy = keras.metrics.SparseCategoricalAccuracy()
@tf.function
def train_step(x, y):
with tf.GradientTape() as tape:
predictions = model(x, training=True)
loss = loss_fn(y, predictions)
gradients = tape.gradient(loss, model.trainable_variables)
optimizer.apply_gradients(zip(gradients, model.trainable_variables))
train_loss.update_state(loss)
train_accuracy.update_state(y, predictions)
# Ciclo de treino
epochs = 10
batch_size = 32
dataset = tf.data.Dataset.from_tensor_slices((x_train_flat, y_train))
dataset = dataset.shuffle(10000).batch(batch_size)
for epoch in range(epochs):
train_loss.reset_states()
train_accuracy.reset_states()
for x_batch, y_batch in dataset:
train_step(x_batch, y_batch)
print(f"Epoch {epoch + 1}: Loss = {train_loss.result():.4f}, "
f"Accuracy = {train_accuracy.result():.4f}")
TensorBoard para Visualização
from tensorflow.keras.callbacks import TensorBoard
import datetime
# Criar diretório de logs
log_dir = "logs/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
tensorboard_callback = TensorBoard(
log_dir=log_dir,
histogram_freq=1,
write_graph=True,
write_images=True
)
# Treinar com callback
model.fit(
x_train_flat, y_train,
epochs=10,
validation_split=0.1,
callbacks=[tensorboard_callback]
)
# Iniciar o TensorBoard
# tensorboard --logdir logs/
Dicas Práticas
Evitar Overfitting
# Early stopping
early_stop = keras.callbacks.EarlyStopping(
monitor='val_loss',
patience=3,
restore_best_weights=True
)
# Redução da learning rate
reduce_lr = keras.callbacks.ReduceLROnPlateau(
monitor='val_loss',
factor=0.2,
patience=2,
min_lr=0.0001
)
model.fit(
x_train, y_train,
epochs=100,
validation_split=0.2,
callbacks=[early_stop, reduce_lr]
)
Checkpoint do Modelo
checkpoint = keras.callbacks.ModelCheckpoint(
'best_model.keras',
monitor='val_accuracy',
save_best_only=True,
mode='max'
)
Principais Conclusões
- Comece pelo simples: Redes densas antes de CNN
- Normalize os inputs: Escale para 0-1 ou standardize
- Use validation split: Monitorize o overfitting
- Transfer learning: Modelos pré-treinados para tarefas de imagem
- Aceleração por GPU: Essencial para modelos maiores
- Guarde checkpoints: Não perca o progresso do treino
As redes neuronais são poderosas, mas exigem experimentação — comece com exemplos funcionais e itere a partir daí.