Pegue e faça: por que às vezes é útil pontuar para análise e apenas desenvolver

Desenvolvemos o Macroscop há quase uma década. E durante esse tempo, uma abordagem muito completa e séria para a criação de novas funções se desenvolveu no desenvolvimento de módulos inteligentes. Por um lado, isso é muito bom. Intenção séria chega perto com um produto de alta qualidade. Mas, ao mesmo tempo, o rigor pode limitar a lentidão e a inoperabilidade do processo.

Há alguns anos, quando recebemos solicitações de usuários para desenvolver algo novo (não incluído no plano mestre de desenvolvimento de produtos), tínhamos uma longa previsão, avaliando a versatilidade e a relevância da função entre uma ampla variedade de usuários. E muitas vezes eles recusaram ou avaliaram o tempo de implementação por muito tempo. Mas uma vez que recebemos uma solicitação para um grande projeto. No caso da implementação rápida e bem-sucedida das funções ausentes do usuário, as perspectivas e a escala da implementação do Macroscop eram muito boas. E começamos a tentar! Tivemos um prazo apertado, um usuário responsivo e útil e total liberdade de ação.



E ... tudo deu certo!

Criamos um novo recurso em pouco tempo. Além disso, ela era precisa e rápida. Todos ficaram satisfeitos: o usuário recebeu o cobiçado módulo intelectual, os desenvolvedores tiveram uma experiência interessante, a empresa - vendas.
Essa prática marcou o início de uma nova abordagem para o desenvolvimento de funções inteligentes no Macroscop: tornamo-nos cada vez mais fáceis de encontrar com nossos usuários. E dá seus resultados.

O mais importante é identificar a real necessidade do usuário e formular claramente a tarefa com ele. Quando se trata do rápido desenvolvimento de funções personalizadas (vamos chamá-las de funções rápidas a seguir), é imperativo especificar os requisitos: o que o usuário deseja ver no final, o que focar. Porque, condicionalmente, é preciso primeiro trabalhar com certeza, o outro para parecer legal. Quando assumimos uma função rápida, não estamos falando sobre o fato de que, no final, ela funcionará em qualquer condição com 100% de precisão. Comprometemo-nos a testar a ideia em si e tentar criar algo que funcione adequadamente e seja aceitável para uso em um objeto específico. E só então, se for bem-sucedido, refinamos e levamos a um produto universal com bom desempenho.

Quando os objetivos e prioridades são claros, assumimos o desenvolvimento. Em pouco tempo, desenvolvemos um protótipo que o usuário já pode avaliar. E nós o testamos. Se o que fizemos foi correlacionado com o que o usuário precisa e, em geral, ele gosta, e o método que usamos no desenvolvimento ainda não se esgotou e tem perspectivas de melhorar a função, vamos além. Se acabou completamente errado e completamente errado, encerramos o projeto. E como isso acontece em um estágio inicial, não perdemos quase nada.

Com essa abordagem, desenvolvedores e usuários devem ir o mais longe possível um do outro. Também é necessário que o usuário seja incluído no processo: é necessário testar cuidadosamente o protótipo em diferentes câmeras e em diferentes condições, experimentar configurações diferentes e pressionar botões diferentes, fornecer feedback exaustivo: o que é conveniente, o que não é conveniente, o que não funciona da maneira como avalia a precisão, quanto o servidor está carregando, etc.

Inicialmente, satisfazemos a necessidade de um cliente específico, mas mesmo antes de iniciar o trabalho, estimamos quão universal essa função pode se tornar no futuro, quantas pessoas ela pode ajudar na solução de seus problemas. E, no futuro, adaptamos a função rápida para que seja útil e aplicável no maior número possível de sistemas de vídeo.

Você se lembra de como tudo começou? (C)


A primeira função rápida para nós foi o módulo de contagem de filas . Em geral, tínhamos isso antes, mas as condições de aplicabilidade eram limitadas: o módulo funcionava apenas em uma projeção, quando a câmera olhava estritamente de cima para baixo. Uma vez fomos abordados por um usuário que precisava contar as pessoas em uma fila sob condições fundamentalmente diferentes - quando a câmera olha para a fila na diagonal (diretamente e um pouco acima).


Nessa perspectiva, o módulo Macroscop poderia contar


e nisso - aprendi

Ele gostava de Macroscop, mas não tinha a função desejada. O projeto foi muito promissor, e o usuário estava pronto para cooperar conosco de todas as formas, se apenas um módulo desse tipo aparecesse e o software pudesse ser instalado no objeto. Decidimos não perder a oportunidade e começamos a desenvolver.

Na última variação do módulo, a tarefa de contar pessoas foi resolvida por métodos clássicos de visão computacional, que impuseram sérias restrições às condições de uso. Mas, no âmbito da nova tarefa, o módulo teve que aprender a contar pessoas em condições fundamentalmente diferentes e muito mais difíceis.

O grupo de desenvolvimento de funções intelectuais foi dividido em 3 subgrupos, e cada um começou a tentar seu próprio método. Todos eles foram baseados no uso de redes neurais.
O primeiro, tentei transferir para o módulo para contar pessoas em filas para a infraestrutura do detector que desenvolvemos por falta de capacetes (veja o artigo sobre como tentamos usar as modernas tecnologias de redes neurais para encontrar capacetes na cabeça das pessoas ). Essa abordagem parecia muito lógica: o detector de capacetes em um determinado estágio do trabalho resolve um problema semelhante.

O segundo grupo tentou aplicar uma rede neural de regressão . Ela conta o número de pessoas na imagem, mas não seleciona objetos específicos, o que dificulta o controle. Ao treinar em uma rede neural de regressão, uma imagem é enviada e o número de pessoas presentes é indicado, e a rede neural fornece um número - quantas pessoas encontrou. Preenchendo a amostra com novas imagens, procuramos treiná-la para contar corretamente.

Infelizmente, rejeitamos os dois métodos, uma vez que a precisão do contador criado em sua base era baixa.

O terceiro grupo testou um detector de uso geral bastante conhecido, que pode detectar uma variedade de objetos em tempo real. Ele sabe como procurar mil tipos de objetos diferentes, mas não resolve o nosso problema com todos os seus recursos. Finalizamos este detector, treinamos em nossa extensa amostra e criamos um bom resultado - um contador de pessoas com precisão aceitável. Eles o aprimoraram com novas seleções e, finalmente, obtiveram um protótipo, que já não era uma vergonha para dar ao usuário um teste. E a avaliação dele foi ... positiva! Ele disse que, em geral, a solução já é competitiva , mas a precisão ainda não foi alta - apenas 60-70%.

A primeira versão do contador de filas foi criada principalmente usando clipes desse usuário. Resolvemos o problema - para trabalhar especificamente com ele - mas entendemos que se treinássemos a rede neural e fizéssemos um módulo para um projeto específico, não haveria mais escala. Portanto, um treinamento adicional foi realizado em uma amostra mais universal, o que levou a um aumento na precisão, mesmo sem melhorias internas globais. Então começamos a trabalhar na embalagem do módulo - melhoramos a interface, alteramos várias configurações, chamamos a atenção para a usabilidade e a lógica. Em paralelo, corrigimos vários bugs em nosso protótipo (a propósito, um deles acelerou inesperadamente o módulo em 7 vezes), descobrimos como reduzir o consumo da CPU e conectamos o trabalho na placa de vídeo. Como resultado, obtivemos um módulo objetivamente funcional e fácil de gerenciar que analisava rapidamente, produzia resultados precisos, sabia como trabalhar em uma placa de vídeo sem carregar o processador.
Nosso usuário ficou feliz! Ele foi colocar a nova versão em suas lojas e confirmou que, na prática, tudo funciona bem. Conseguimos atingir uma precisão de 85 a 90% (para situações em que as pessoas na fila não se sobrepõem completamente e podem ser distinguidas).

Obviamente, durante o processo de desenvolvimento, nem tudo correu bem e, por exemplo, entre o primeiro protótipo e a solução que agora está instalada no site, houve uma versão com falha que funcionou pior que a anterior. Mas, por sua experiência, percebemos o que procurar ao testar, aprendemos vários recursos das estruturas usadas. E, considerando isso, criamos um módulo final interessante e, com base nele, outra função rápida.



Final feliz


Agora, o aplicativo do módulo para contagem de pessoas na fila da nova versão está se expandindo para outras lojas deste usuário. E a versão final - entrou em produção e entrou na versão do Macroscop, que está sendo preparada para lançamento. A propósito, o usuário ficou tão satisfeito com o resultado e com a maneira geral de trabalhar que outra solicitação chegou - para fazer um detector de prateleira vazio . E nós pegamos de novo e fizemos de novo (mas essa é uma história completamente diferente).

Para resumir, comparemos: o desenvolvimento e o aprimoramento da versão antiga do módulo para contagem de pessoas na fila (há 4 anos) demoraram cerca de 8 meses . Criamos o novo módulo em 2 meses (o primeiro protótipo de trabalho foi entregue ao usuário em 2 a 3 semanas).

Até agora, isso é apenas um teste da caneta e apenas dentro da estrutura de uma direção - o desenvolvimento de funções intelectuais. Em geral, aderimos a uma abordagem mais rigorosa e completa do desenvolvimento de produtos - com planejamento, inúmeras validações de idéias, análise de demanda e testes detalhados. O que permanece inalterado é a prática de criar o Macroscop (seja o desenvolvimento de um kernel ou módulos de análise de vídeo) em estreita colaboração com os usuários.
Não há certeza de que a abordagem de funções rápidas deva ser aplicada continuamente e em todo o departamento, mas agora estamos obtendo uma experiência real de desenvolvimento rápido, e os usuários para os quais isso é feito são benefícios reais do produto.

De qualquer forma, para nós mesmos, criamos várias regras, cuja conformidade é metade do sucesso do desenvolvimento de funções rápidas:

  • Tente encontrar o usuário, mas não se esqueça de seus próprios objetivos: assuma projetos que podem ser dimensionados, invista em algo que será útil a longo prazo.
  • Chegue ao fundo das verdadeiras tarefas e necessidades do usuário, identifique prioridades.
  • Recrute o suporte ao usuário. Se ele estiver pronto para se comunicar ativamente, testar, fornecer feedback e fornecer os dados necessários (vídeo de um objeto real, por exemplo), então há todas as chances de se desenvolver bem e rapidamente.
  • Não tenha medo do fracasso e trate-o como um dos resultados possíveis.
  • Não tente desenvolver algo único do zero, mas use a experiência existente, se possível: no nosso caso, tente usar partes dos algoritmos de módulos já implementados. E mesmo que a solução resultante seja viável - dedique tempo à pesquisa e personalização.

Source: https://habr.com/ru/post/pt421733/


All Articles