Como adicionar uma nova categoria a um modelo de aprendizado profundo?

15

Digamos que eu tenha transferido o aprendizado em uma rede pré-treinada para reconhecer 10 objetos. Como adicionar um décimo primeiro item que a rede possa classificar sem perder as 10 categorias que eu já treinei nem as informações do modelo pré-treinado original? Um amigo me disse que uma pesquisa ativa está em andamento neste campo, mas não consigo encontrar trabalhos relevantes ou um nome pelo qual procurar?

Obrigado.

nnrales
fonte
Se você treina com muito mais classe, então existe? isso pode ajudar? Por exemplo, digamos que você saiba que não haverá mais que 1000 aulas. Você treina desde o início o seu classificador com 1000 aulas nas 10 que você tem atualmente e, quando você tem mais aulas, apenas o treina ... Isso pode ser uma boa solução? Há documentos sobre essa abordagem?
Michael Michael

Respostas:

13

Se esse é apenas um caso único, você pode simplesmente treinar novamente a rede neural. Se você frequentemente precisa adicionar novas classes, é uma má idéia. O que você deseja fazer nesses casos é chamado de recuperação de imagem baseada em conteúdo (CBIR), ou simplesmente recuperação de imagem ou pesquisa visual. Vou explicar os dois casos na minha resposta abaixo.

Caso único

Se isso acontecer apenas uma vez - você esqueceu a 11ª classe ou seu cliente mudou de idéia - mas isso não acontecerá novamente , então você pode simplesmente um 11º nó de saída para a última camada. Inicialize os pesos neste nó aleatoriamente, mas use os pesos que você já possui para as outras saídas. Depois, apenas treine-o como de costume. Pode ser útil consertar alguns pesos, ou seja, não treiná-los.

Um caso extremo seria treinar apenas os novos pesos e deixar todos os outros fixos. Mas não tenho certeza se isso funcionará tão bem - pode valer a pena tentar.

Recuperação de imagem baseada em conteúdo

Considere o seguinte exemplo: você está trabalhando para uma loja de CDs, que deseja que seus clientes possam tirar uma foto de uma capa de álbum, e o aplicativo mostra o CD que eles digitalizaram em sua loja online. Nesse caso, você teria que treinar novamente a rede para cada CD novo que eles tiverem na loja. Podem ser 5 novos CDs por dia, portanto, treinar a rede dessa maneira não é adequado.

A solução é treinar uma rede, que mapeia a imagem em um espaço de recurso. Cada imagem será representada por um descritor, que é, por exemplo, um vetor de 256 dimensões. Você pode "classificar" uma imagem calculando esse descritor e comparando-o ao seu banco de dados de descritores (ou seja, os descritores de todos os CDs que você possui em sua loja). O descritor mais próximo no banco de dados vence.

Como você treina uma rede neural para aprender esse vetor descritor? Esse é um campo ativo de pesquisa. Você pode encontrar trabalhos recentes pesquisando palavras-chave como "recuperação de imagem" ou "aprendizado de métricas".

No momento, as pessoas geralmente usam uma rede pré-treinada, por exemplo, o VGG-16, cortam as camadas do FC e usam o convolucional final como seu vetor descritor. Você pode treinar ainda mais essa rede, por exemplo, usando uma rede siamesa com perda de trigêmeos.

hbaderts
fonte
Eu estive estudando o aprendizado de uma só vez. Você acha que isso pode me ajudar?
nnrales
Eu realmente não sei sobre o aprendizado de uma só vez. Mas o one-shot papéis profundo aprendizado achei olhar bastante semelhante à abordagem CBIR, por isso definitivamente poderia ser útil para você
hbaderts
2

Sua topologia de rede pode parecer diferente, mas no final, sua rede pré-treinada possui uma camada, que lida com o reconhecimento de 10 classes originais. O truque mais fácil (e funcional) para introduzir a 11ª, 12ª e a nona classe, é usar todas as camadas anteriores à última como concedida e adicionar uma camada adicional (em um novo modelo ou em paralelo) que também ficará em cima de todas as camadas, exceto a última, será semelhante à camada de 10 classes (que provavelmente é um matmul de camada densa e uma matriz de forma [len(dense layer), 10]com viés opcional).

Sua nova camada seria uma camada matmul com forma [len(dense layer), len(new classes)].

Sem acesso aos dados originais de treinamento, você teria duas opções:

  1. Congele todos os pesos nas camadas originais, permitindo que o "novo" modelo otimize apenas novos pesos. Isso fornecerá exatamente o mesmo poder preditivo para as 10 classes originais e poderá dar um bom desempenho para as novas.
  2. Treine toda a rede de uma só vez (propagando o erro de novas classes), o que pode estar funcionando para novas classes, mas você terá uma solução original ineficaz para 10 classes (já que os pesos serão alterados para as classes mais baixas e a camada final) não será atualizado para corresponder a essas alterações).

Embora você tenha acesso aos dados originais do treinamento, é possível adicionar facilmente nova classe à rede original e treiná-la novamente para oferecer suporte a 11 classes prontas para uso.

chewpakabra
fonte
2

Isso pode ser feito facilmente.

Primeiro, crie um modelo com essas 10 classes e salve o modelo como base_model.

Carregue o base_model e também defina um novo modelo chamado new_model as-

new_model = Sequential()

Em seguida, adicione as camadas do base_model ao new_model -

# getting all the layers except the last two layers
for layer in base_model.layers[:-2]: #just exclude the last two layers from base_model
    new_model.add(layer)

Agora, torne as camadas do novo modelo não treináveis, pois você não deseja que seu modelo seja treinado novamente.

# prevent the already trained layers from being trained again
for layer in new_model.layers:
    layer.trainable = False

Agora, quando você transfere o aprendizado, quando você remove as últimas camadas, o modelo esquece as 10 classes, por isso precisamos reter os pesos do base_model para o new_model -

weights_training = base_model.layers[-2].get_weights()
new_model.layers[-2].set_weights(weights_training) 

Agora adicione uma camada densa no final e apenas treinaremos essa camada densa neste exemplo.

new_model.add(Dense(CLASSES, name = 'new_Dense', activation = 'softmax'))

Agora treine o modelo e espero que ele dê a saída certa para todas as 11 classes.

Aprendizado feliz.

Subham Tiwari
fonte