Pesos e vieses se tornaram uma das bibliotecas favoritas da comunidade de IA. A equipe fez um excelente trabalho criando uma plataforma onde o engenheiro de aprendizado de máquina pode sem esforço:
-
Rastreie seus experimentos
-
Visualize o processo de treinamento
-
Compartilhe os resultados com a equipe
-
Melhore o desempenho do modelo
Pessoalmente, comecei a usá -lo há alguns meses e rapidamente me tornei uma parte individual de todos os meus projetos. Este artigo resume minha experiência com a biblioteca e pretende ser um tutorial auto-preenchido de seus recursos mais úteis. Para conseguir isso, examinaremos como podemos integrar o wandb
Biblioteca em um novo projeto.
Devemos começar?
Pré -requisitos
Usaremos um modelo de aprendizado profundo padrão que executa o reconhecimento de imagem no conjunto de dados CIFAR10. O modelo realmente não afeta nossos experimentos, então pensei em mantê -lo o mais simples possível. O modelo será treinado no conjunto de dados do zero para explorar como podemos utilizar o wandb
biblioteca.
Aqui está o código Pytorch para o nosso modelo, juntamente com o processamento de dados:
import torch
import torch.nn as nn
import torch.nn.functional as F
import torchvision
import torchvision.transforms as transforms
transform = transforms.Compose(
(transforms.ToTensor(),
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))))
trainset = torchvision.datasets.CIFAR10(root='./data', train=True,
download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=4,
shuffle=True, num_workers=2)
testset = torchvision.datasets.CIFAR10(root='./data', train=False,
download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=4,
shuffle=False, num_workers=2)
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = nn.Conv2d(3, 6, 5)
self.pool = nn.MaxPool2d(2, 2)
self.conv2 = nn.Conv2d(6, 16, 5)
self.fc1 = nn.Linear(16 * 5 * 5, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
def forward(self, x):
x = self.pool(F.relu(self.conv1(x)))
x = self.pool(F.relu(self.conv2(x)))
x = x.view(-1, 16 * 5 * 5)
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return x
A primeira etapa é instalar a biblioteca e criar uma nova conta.
Instalação e inicialização
Se você ainda não o fez, precisará criar uma nova conta para poder usar pesos e preconceitos. A biblioteca é gratuita para uso pessoal, mas vem com um preço mensal para as equipes. Você pode visitar o site e inscreva -se.
Depois de fazer isso, você poderá instalá -lo usando pip
ou conda
. Após a instalação, você precisará se autenticar. Isso pode ser feito com o wandb login
comando. Você será solicitado a copiar uma chave de autorização para continuar.
$ conda install -c conda-forge wandb
$ wandb login
A biblioteca pode ser inicializada em nosso código com o init
Método que recebe um nome de projeto opcional e seu nome de usuário, entre outras coisas.
import wandb
wandb.init(project='test', entity='serkar')
Agora que estamos todos configurados, vamos tentar integrar a biblioteca ao nosso loop de treinamento.
Rastreamento do experimento
O principal uso do wandb
A biblioteca deve rastrear e visualizar os diferentes experimentos de aprendizado de máquina, o processo de treinamento, os hiperparâmetros e os modelos. Vamos ver alguns exemplos.
Rastrear métricas
A coisa incrível sobre a biblioteca de pesos e vieses (W&B) é como é fácil usar. Em muitos casos, é literalmente uma linha de código:
wandb.log({'epoch': epoch, 'loss': running_loss})
O .log()
O comando capturará todos os argumentos e os enviará para a instância da W&B. Isso nos permitirá acessar e rastreá -los na interface do usuário. Você pode encontrar o painel no site da W&B em seu projeto.
Em nossa aplicação, um loop de treinamento de amostra pode parecer abaixo:
for epoch in range(10):
running_loss = 0.0
for i, data in enumerate(trainloader, 0):
inputs, labels = data(0).to(device), data(1).to(device)
optimizer.zero_grad()
outputs = net(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
if i % 2000 == 1999:
print('(%d, %5d) loss: %.3f' %
(epoch + 1, i + 1, running_loss / 2000))
wandb.log({'epoch': epoch+1, 'loss': running_loss/2000})
running_loss = 0.0
print('Finished Training')
Você notou o wandb.log
linha? Dessa forma, podemos inspecionar o processo de treinamento em tempo real. O resultado será assim:
Muito incrível, certo?
Outro comando que também pode ser usado é o wandb.watch
que coletará automaticamente os gradientes do modelo e a topologia do modelo.
wandb.watch(net, criterion, log="all")
Além das métricas definidas, também podemos rastrear muitas outras coisas úteis, como nossos parâmetros treináveis.
Ou os gradientes:
Outro recurso que realmente me impressionou é o painel do sistema. Lá, podemos inspecionar nosso hardware e como os diferentes componentes se comportam durante o treinamento. Por exemplo, pode -se examinar a CPU, GPU, utilização da memória, uso de energia, temperaturas e muito mais.
Cada vez que executamos nosso script de treinamento, uma nova “corrida” é criada e anexada à história do projeto. Cada “execução” contém as informações registradas com diferentes metadados. É claro que podemos explorar todas as diferentes corridas em um único painel.
Rastrear hyperparameters
Além das métricas, a W&B tem outra funcionalidade legal que nos permite rastrear os hiperparâmetros de nosso treinamento. O wandb.config
O objeto é usado para salvar a configuração de treinamento, como hiperparâmetros. Mas não está limitado a eles. Podemos armazenar essencialmente todas as informações que queremos. Os exemplos incluem: nomes de dados, tipos de modelo e sinalizadores.
Uma configuração pode ser inicializada assim:
config = wandb.config
config.learning_rate = 0.01
config.momentum = 0.9
Para configurações complexas, também podemos usar um arquivo YAML ou um dicionário Python.
Todos esses valores podem ser usados para analisar os experimentos e reproduzir os resultados. No painel a seguir, podemos ver cinco “corridas” com seus hiperparâmetros. Observe que podemos usar os valores de configuração para agrupar, filtrar ou classificá -los.
Visualize o modelo
Se usarmos o acima mencionado watch
Comando, também podemos inspecionar a topologia do modelo no painel do modelo. No nosso caso, o modelo será assim:
Inspecione logs
O mesmo vale para os logs reais impressos em nosso console local:
Versão de dados e modelo
Além do rastreamento de experimentos, a W&B possui um sistema de versão interno. Os artefatos são a principal entidade para esse objetivo. Os artefatos permitem a versão do conjunto de dados, a versão modelo e o rastreamento de dependências.
Um artefato nada mais é do que uma pasta de dados de versão. Vamos examinar um exemplo usando nosso projeto. Para ver nosso conjunto de dados, tudo o que precisamos fazer é criar um artefato e fazer upload.
cifar10_artifact = wandb.Artifact("cifar10", type="dataset")
file_path = './data/cifar-10-batches-py'
cifar10_artifact.add_dir(file_path)
run.log_artifact(cifar10_artifact)
Você pode imaginar que algo semelhante pode ser feito para a versão do modelo ou as dependências. Vale ressaltar que, em vez de usar todo o conjunto de dados, podemos criar um artefato com uma referência externa do objeto como abaixo:
artifact.add_reference('s3://my-bucket/my_dataset)
Faça o download e usar um artefato já carregado em nosso código também é direto:
artifact = run.use_artifact('cifar10_artifact')
artifact_dir = artifact.download()
Ajuste hiperparâmetro com varreduras
Pesos e vieses varrem é uma ferramenta para automatizar a otimização e exploração do hiperparâmetro. Ele elimina a maior parte do código da caldeira e vem com visualizações super agradáveis. Vamos explorar como podemos utilizar varreduras em nossos projetos.
Em nosso caso de uso, queremos ajustar 4 parâmetros diferentes: o tamanho da última camada linear no modelo, o tamanho do lote, a taxa de aprendizado e o algoritmo de otimização. Para conseguir isso, primeiro precisamos criar uma configuração com as diferentes opções. Aqui está uma amostra de configuração:
sweep_config = {
'method': 'random',
'metric': {'goal': 'minimize', 'name': 'loss'},
'parameters': {
'batch_size': {
'distribution': 'q_log_uniform',
'max': math.log(256),
'min': math.log(32),
'q': 1
},
'epochs': {'value': 5},
'fc_layer_size': {'values': (128, 256, 512)},
'learning_rate': {'distribution': 'uniform',
'max': 0.1,
'min': 0},
'optimizer': {'values': ('adam', 'sgd')}
}
}
Primeiro, definimos o método de ajuste, que é a estratégia de pesquisa. Temos 3 opções: Random, pesquisa de grade e pesquisa de Bayes. A métrica é o objetivo final que deve ser minimizado. Finalmente, os parâmetros se referem aos hiperparâmetros a serem pesquisados por varreduras. Como você pode ver, ajustaremos o seguinte:
-
O tamanho do lote para estar no (log (32), log (256)) faixa. A seleção do tamanho do lote seguirá a distribuição uniforme de log quantizada. Outras opções também estão disponíveis.
-
O número de épocas sempre é igual a 5.
-
O tamanho da última camada linear é 128, 256 ou 512.
-
A taxa de aprendizado a estar no (0, 0.1) alcance seguindo a distribuição uniforme
-
O otimizador a ser SGD ou Adam.
As varreduras tentarão todas as combinações diferentes e calcularão a perda para cada uma. As varreduras podem ser inicializadas usando:
sweep_id = wandb.sweep(sweep_config, project="test")
O loop de treinamento deve ser transformado para ler a partir da configuração predefinida. Dê uma olhada no seguinte código:
def train(config=None):
with wandb.init(project='test', entity='serkar', config=config):
config = wandb.config
transform = transforms.Compose(
(transforms.ToTensor(),
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))))
trainset = torchvision.datasets.CIFAR10(root='./data', train=True,
download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=config.batch_size,
shuffle=True, num_workers=2)
testset = torchvision.datasets.CIFAR10(root='./data', train=False,
download=True, transform=transform)
net = Net(config.fc_layer_size)
net.to(device)
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=config.learning_rate)
if config.optimizer == "sgd":
optimizer = optim.SGD(net.parameters(),
lr=config.learning_rate, momentum=0.9)
elif optimizer == "adam":
optimizer = optim.Adam(net.parameters(),
lr=config.learning_rate)
wandb.watch(net, criterion, log="all")
for epoch in range(config.epochs):
running_loss = 0.0
for i, data in enumerate(trainloader, 0):
inputs, labels = data(0).to(device), data(1).to(device)
optimizer.zero_grad()
outputs = net(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
print('(%d, %5d) loss: %.3f' %
(epoch + 1, i + 1, running_loss / len(trainloader)))
wandb.log({'epoch': epoch + 1, 'loss': running_loss / len(trainloader)})
print('Finished Training')
Duas coisas para perceber aqui:
-
O loop de treinamento está sendo envolvido
with wandb.init(project='test', entity='serkar', config=config)
. Essa é outra maneira de vincular a biblioteca W&B ao nosso código. -
Lemos a configuração usando
config = wandb.config
E então passamos cada parâmetro no código de treinamento. Temos que garantir que os hiperparâmetros utilizados venham do arquivo de configuração para que as varreduras sejam executadas corretamente.
Finalmente, podemos executar o ajuste com o comando abaixo.
wandb.agent(sweep_id, function=train, count=5)
Isso instrui varreduras para executar a função do trem apenas 5 vezes escolhendo 5 combinações aleatórias de hiperparâmetros. Os resultados são ilustrados abaixo:
Observe que adquirimos os melhores resultados para o seguinte conjunto de hyperparameters:
-
Tamanho do lote = 55
-
Tamanho da camada linear = 256
-
Taxa de aprendizado = 0,02131
-
Otimizador = sgd
Usando essa combinação, a perda tornou -se igual a 0,003.
Outro gráfico muito legal é o seguinte:
Aqui examinamos quais parâmetros têm maior impacto na perda e como. Isso é chamado de gráfico de importância do hiperparameter. Indica quais hiperparâmetros foram os melhores preditores de nossas métricas. A importância do recurso é derivada usando um modelo florestal aleatório e a correlação usando um modelo linear.
Visualização de dados
Outro recurso que estou realmente gostando é a visualização de dados. W&B vamos definir uma tabela de dados e visualizá -los na plataforma. A tabela pode consistir em quase tudo: dados como imagens, texto ou áudio, gradientes, parâmetros treináveis, etc. Além da visualização, também podemos filtrar, classificar, grupo e, em geral, explorar os dados.
Para deixar isso claro, apresentaremos um exemplo simples. Vamos criar uma pequena tabela com todas as imagens do primeiro lote de nossos dados e seus rótulos. Criar uma tabela pode ser feita usando o wandb.Table
aula. Para sincronizar a tabela, teremos que registrá -la.
classes = ('plane', 'car', 'bird', 'cat',
'deer', 'dog', 'frog', 'horse', 'ship', 'truck')
columns=('image','label')
data = ()
for i, batch in enumerate(trainloader, 0):
inputs, labels = batch(0), batch(1)
for j, image in enumerate(inputs,0):
data.append((wandb.Image(image),classes(labels(j).item())))
break
table= wandb.Table(data=data, columns=columns)
run.log({"cifar10_images": table})
Observe que usamos o tipo de dados interno wandb.Image
para que possamos visualizar a imagem. Depois de executar o código acima, podemos inspecionar nossa tabela no painel.
Você pode imaginar que, usando a mesma lógica, podemos visualizar praticamente qualquer coisa.
Relatórios
Por fim, quero fechar este tutorial com um recurso direcionado mais para as equipes. Relatórios. Os relatórios permitem que os desenvolvedores dos EUA organizem as diferentes visualizações, comuniquem nossos resultados e documente nosso trabalho.
A W&B fornece um editor Wysiwyg com uma infinidade de recursos. Ele suporta markdown e látex para texto, trechos de código, além de uma variedade de outros gráficos. Os exemplos incluem: gráficos de linha, gráficos de barra, gráficos de dispersão e muito mais. A equipe está trabalhando duro para adicionar mais funcionalidades, como vídeos incorporados, HTML, áudio e muito mais.
Os relatórios podem ser compartilhados e editados por outras pessoas, permitindo a colaboração total entre nossos colegas.
Conclusão
E isso conclui nossa jornada na biblioteca de pesos e preconceitos. A W&B se tornou um dos meus favoritos pessoais e melhorou muito meu fluxo de trabalho. Eu recomendo que você experimente, se ainda não o fez. Mais detalhes que você pode encontrar em seus documentaçãoque está muito bem escrito. Muitos exemplos também são fornecidos em seus Repositório do GitHub.
Divirta -se brincando com isso. Informe -nos se você tiver alguma dúvida ou se deseja que cubram a W&B com mais detalhes no futuro. Como sempre, compartilhe este artigo se achar útil. Isso realmente importa para nós para continuar escrevendo conteúdo.
* Divulgação: Observe que alguns dos links acima podem ser links de afiliados e, sem nenhum custo adicional, ganharemos uma comissão se você decidir fazer uma compra depois de clicar.

Luis es un experto en Ciberseguridad, Computación en la Nube, Criptomonedas e Inteligencia Artificial. Con amplia experiencia en tecnología, su objetivo es compartir conocimientos prácticos para ayudar a los lectores a entender y aprovechar estas áreas digitales clave.