Tuesday 8 August 2017

Fast Moving Average C ++


Como desenvolver um melhor firmware mais rápido Um curso de um dia para pessoas que precisam desenvolver firmware embutido de alta qualidade em horários cada vez mais curtos. Desculpe - o registro para todas as classes está encerrado. Aulas públicas na Dinamarca Roskilde, Dinamarca - 24 de outubro de 2016 - Brochura e informações de localização estão aqui. Aarhus, Dinamarca - 26 de outubro de 2016 - Brochura e informações de localização estão aqui. Os melhores equipamentos da classe oferecem produtos embutidos com 0,1 insetos por mil linhas de código. Eles consistentemente batiam o cronograma, sem horas extras exageradas. Isso soa como sua equipe Se não, que medidas você está tomando para melhorar os resultados de suas equipes. Esperar que as coisas melhorem não mudará nada. QuotTrying Harderquot nunca funciona (como Harry Roberts provou em Quality Is Personal). Infelizmente, poucos grupos de firmware mantêm métricas, mas aqueles que fazem uma diminuição média de 40 na programação e uma melhoria de ordem de magnitude nas taxas de insetos depois de implementar as idéias da classe Jack Ganssles Better Firmware Faster. As informações de registro estão aqui. Resumo do curso Este curso de um dia irá ensinar-lhe práticas e comprovadas maneiras de desenvolver um melhor firmware mais rápido. É para o desenvolvedor que está buscando honestamente novas idéias, mas quem quer cortar o fluff acadêmico de metodologias formais e encontrar melhores maneiras de trabalhar agora. O foco é exclusivo em sistemas incorporados, onde o firmware só pode ser entendido no contexto do hardware. Você aprenderá novas maneiras de vincular o hardware e o software, destruir os erros, gerenciar restrições em tempo real, cumprir prazos impossíveis e muito, muito mais. O curso é direcionado para desenvolvedores envolvidos na criação de produtos agora que devem encontrar maneiras de trabalhar de forma mais eficiente. Assume algum conhecimento de C. Cada participante receberá 0,7 Unidades de Educação Continuada. Comentários dos participantes O seu treinamento teve um grande impacto no nosso trabalho e nossa equipe é muito mais disciplinada e produtiva do que nunca. Acabamos de voltar de uma feira onde mostramos um produto para o qual aplicamos suas idéias e 1) não houve falhas embaraçosas como os anos anteriores, 2) cada recurso entregue foi concluído e depurado em vez de meio trabalhando e 3) resposta do cliente Era tipicamente em qual lugar este produto foi toda a minha vida. Brad Nelson, Skip-Line, Inc. Muito obrigado pelo seu tempo e pelo excelente seminário. Eu tirei mais longe do que eu poderia ter imaginado. Seminário Adam Roman Jacks, as Melhores Ideias para o Desenvolvimento de Firmware Melhor Fasterquot tem que ser o mais interessante e agradável que eu já tenha feito e isso está dizendo algo como eu já estive em poucos durante minha carreira ao longo dos anos. Josh Hurvitz, tecnologia espacial, droga, você estava bem e eu falo por todos os meninos. Eu acho que já estive em cerca de 100 seminários nos últimos dois anos, e eu me aborreceram a cada momento, mas este foi ótimo, estou impressionado com o quanto era bom e divertido. Soeren Panduro, APCC Obrigado por uma lição valiosa, pragmática e informativa no design de sistemas embarcados. Todos os participantes achavam que valia a pena o tempo deles. Craig DeFilippo, Pitney Bowes Eu só queria agradecer-lhe novamente pela excelente aula na semana passada. Sem exceções, todos os comentários dos participantes foram extremamente positivos. Estamos ansiosos para incorporar muitas sugestões e observações para tornar o nosso trabalho aqui mais eficiente e de melhor qualidade. Carol Batman, INDesign LLC. Muito obrigado por um excelente seminário. Nós realmente gostamos disso. Já estávamos a usar algumas das ideias que você nos deu. J. Sarget, CSC Obrigado pelo terrível seminário aqui na ALSTOM ontem Recebeu críticas de uma multidão bastante difícil. Cheryl Saks, ALSTOM Jack, faz 6 meses desde que você veio aqui. Este último projeto foi enviado dentro de uma semana de previsão, com muito mais recursos do que o esperado. O cliente está emocionado e meu chefe também. Obrigado F. Henry, CACI Muito obrigado por uma ótima classe Agora meus colegas de trabalho pensam que eu sou o guru Dana Woodring, Northrop Grumman Eu recomendaria seu seminário para outros programadores. Ed Chehovin, US Navy Seu apresentador é Jack Ganssle, o arquiteto de sistemas embutidos mais famoso. Ele escreveu mais de 1000 artigos e seis livros sobre sistemas embarcados. Jack ensina conferências e negócios a nível internacional. Ele fundou três empresas de eletrônicos, incluindo um dos maiores provedores de ferramentas embutidas, e foi membro da equipe de Super Problem Resolution da NASA, um pequeno painel de especialistas formado para assessorar a NASA na sequência da perda de Columbias. Sua extensa experiência de desenvolvimento de produtos forjou sua abordagem única para construir um firmware melhor rápido. Jack ajudou centenas de empresas e milhares de desenvolvedores a melhorar seu firmware e entregar consistentemente melhores produtos no horário e no orçamento. Algumas empresas que enviaram pessoas para esta classe Por que tomar este curso Você está satisfeito com a forma como sua empresa desenvolve produtos embutidos Se a resposta for quotyesquot, provavelmente você já está usando os conceitos desta classe. Se, no entanto, você é como a maioria das pessoas nesta indústria, você percebe que há muito espaço para melhorias. Essas situações parecem familiares Os prazos vão e vão, mas o produto ainda não é enviado. Você nunca conhece o status de um projeto. É quase quotdonequot, mas novos problemas aparecem diariamente empurrando o lançamento final cada vez mais longe. Marketing macacos com os recursos, mesmo que você esteja no meio do código de escrita. O rascunho de featurismquot faz com que os produtos projetem um alvo em movimento. Bugs pesam todo o esforço de desenvolvimento, consumindo vastos recursos. Os erros pós-lançamento continuam a perseguir a equipe de desenvolvimento, criando dores de cabeça de suporte sem fim. A maioria das organizações cai em uma aceitação fatalista desses tipos de problemas, nunca percebendo que uma série de métodos bem conhecidos podem eliminar grande parte da agonia do desenvolvimento de produtos. O triadquot quottwisted - equilibrando três forças concorrentes A engenharia é uma das poucas profissões aprendidas principalmente no trabalho. Os colégios preparam as pessoas com uma boa base teórica, mas as habilidades necessárias para agendar, gerenciar e trabalhar diariamente em direção a um produto final provêm da orientação geral, casual por colegas de trabalho. Por que não treinamos desenvolvedores na arte de fazer projetos Qual é o seu recurso mais dispendioso dos recursos É o único recurso que você tem para obter produtos no mercado: o tempo dos desenvolvedores. Sem dúvida, você substitui e atualiza ferramentas, compiladores e similares de tempos em tempos. O que você está fazendo para atualizar suas habilidades ou as habilidades de seus engenheiros Com um pouco de prática, você pode reduzir as taxas de insetos - e acelerar enormemente a liberação do produto. Neste curso, você aprenderá a obter seus produtos no mercado com mais rapidez, com menos defeitos. A apresentação e as recomendações são práticas, imediatamente úteis e bem focadas no desenvolvimento do sistema integrado - esta não é outra metodologia de software nobre e, no entanto, descartada. Essas rotinas de tempo de execução CC são executadas em um usec ou uma semana. Essa função de triplo está em todo o mapa, de 6 a 15 ms. Você aprenderá a escrever código em tempo real de forma proativa, antecipando problemas de temporização antes da depuração. Esboço do curso C, C ou Java O código de reutilização nos beneficiará Como tomar uma decisão de forma quantitativa. Como criar um cronograma preciso, que inclui uma distribuição de probabilidade. E, como negociar um cronograma para atender às necessidades reais do chefe. Como infundir todo o esforço de desenvolvimento com um foco de qualidade. A melhor maneira de gerenciar o rastreamento de recursos. E, há uma boa maneira de minimizar o rastejo. Pilhas e pilhas - recursos que você pode controlar. Superando os maiores impulsionadores de produtividade. Gerenciando erros para fornecer código de classe mundial. velozes. Inspeções rápidas de código que mantêm a programação em andamento. Maneiras legais para encontrar falhas no software. A arte de projetar código previsível em tempo real. Prevenção de debilidades no desempenho do sistema. Reentrância - eliminando falhas erráticas. Compreender como os sinais de alta velocidade afetam o desenvolvimento do firmware. Adicionando um loop de feed-back ao seu processo de desenvolvimento. Usando postmortem para acelerar a entrega do produto. Um plano de sete passos para o sucesso do firmware. Informação de registro Tudo isso, além de um folheto de 100 páginas e 0,7 unidades de educação continuada, para 695 por pessoa. Cadastre-se com um mês de antecedência e receba um desconto de 50,00. Grupos de 3 ou mais que pagam pagam apenas 595 por pessoa. O formulário de inscrição pode ser encontrado na última página da brochura. Use uma dessas três formas fáceis de pagar: Por Cheque: Faça cheques a pagar ao Grupo Ganssle e envie um email junto com o seu formulário de inscrição no The Ganssle Group, 3520 Lawndale Rd. East, Reisterstown, MD 21136 Por VisaMasterCardAmex: Basta preencher o formulário de inscrição que pode ser encontrado na última página da brochura (aqui aulas da Dinamarca e Minneapolis) e envie-nos um e-mail para nós. Ou, ligue para a sua inscrição para (410) 504-6660. Os pagamentos são devidos duas semanas antes do início do curso. Os cancelamentos escritos são completamente reembolsáveis, menos uma taxa de processamento de 50, se feita mais de 14 dias antes do curso. Os cancelamentos feitos dentro de 14 dias não são reembolsáveis, mas são 100 transferíveis para qualquer outro curso que oferecemos. Do você precisa eliminar erros em seu firmware Reduzir horários O meu seminário Better Firmware mais rápido de um dia ensinará seu time a operar em um mundo Nível de classe, produzindo código com muito menos erros em menos tempo. É rápido, divertido e cobre os problemas únicos enfrentados por desenvolvedores incorporados. Sua informação sobre como esta aula, ensinada em suas instalações, melhorará de forma mensurável a eficácia da sua equipe. Ganhe um Thunderboard da Silicon Labs - Entre no concurso aqui. Anuncie conosco Alcance 130K desenvolvedores incorporados por mês. Mais informações aqui. The Ganssle Group - infoganssle - copyright TGG, todos os direitos reservados. Informações de contato aqui. Interessado em anunciar conosco Mais informações aqui. Usando redes neurais para reconhecer os dígitos manuscritos Perceptrons Os neurônios sigmoides A arquitetura das redes neurais Uma rede simples para classificar os dígitos manuscritos Aprendendo com descida de gradiente Implementando nossa rede para classificar dígitos Para o aprendizado profundo Como funciona o algoritmo de backpropagação Quente Up: uma abordagem rápida baseada em matriz para computar a saída de uma rede neural. As duas premissas que precisamos sobre a função de custo O produto Hadamard, s odot t As quatro equações fundamentais por trás da pós-propagação Prova das quatro equações fundamentais (opcional) O algoritmo de backpropagation O código para backpropagation Em que sentido é a backpropagation um algoritmo rápido Backpropagation: o grande quadro Melhorando a forma como as redes neurais aprendem A função de custo de entropia cruzada Overtuagem e regularização Inicialização de peso Reconhecimento de manuscrito revisitado: o código Como escolher um hiper-parâmetros de redes neurais Outro Techniqu Es uma prova visual de que as redes neurais podem calcular qualquer função Duas ressalvas Universalidade com uma entrada e uma saída Muitas variáveis ​​de entrada Extension além dos neurônios sigmóides Reparando as funções do passo Conclusão Por que as redes neurais profundas são difíceis de treinar O problema do gradiente desaparecendo O que está causando gradiente desaparecendo Problema Gradientes instáveis ​​em redes neurais profundas Gradientes instáveis ​​em redes mais complexas Outros obstáculos para o aprendizado profundo Aprendizado profundo Introduzindo redes convolutivas Redes neurais convolutivas na prática O código para nossas redes convolutivas Avanço recente no reconhecimento de imagens Outras abordagens para redes neurais profundas Sobre o futuro dos neurais Redes Apêndice: Existe um algoritmo simples para a inteligência Obrigado a todos os apoiantes que fizeram o livro possível, especialmente graças a Pavel Dudrenov. Agradeço também a todos os contribuintes para o Hall of Fame do Bugfinder. Aprendizagem profunda. Livro de rascunho em preparação, por Yoshua Bengio, Ian Goodfellow e Aaron Courville No último capítulo, vimos como as redes neurais podem aprender seus pesos e desvios usando o algoritmo de descida gradiente. No entanto, houve uma lacuna na nossa explicação: não discutimos como calcular o gradiente da função de custo. Isso é uma lacuna neste capítulo. Eu explico um algoritmo rápido para calcular tais gradientes, um algoritmo conhecido como backpropagation. O algoritmo de backpropagation foi originalmente introduzido na década de 1970, mas sua importância não foi totalmente apreciada até um famoso artigo de 1986 de David Rumelhart. Geoffrey Hinton. E Ronald Williams. Esse artigo descreve várias redes neurais onde a backpropagation funciona muito mais rápido do que as abordagens anteriores de aprendizado, possibilitando a utilização de redes neurais para resolver problemas que antes eram insolúveis. Hoje, o algoritmo de backpropagation é o campo de trabalho das redes neurais. Este capítulo está mais envolvido matematicamente do que o resto do livro. Se você não está louco por matemática, pode ser tentado a ignorar o capítulo e a tratar a pirataria como uma caixa preta cujos detalhes você está disposto a ignorar. Por que tomar o tempo para estudar esses detalhes O motivo, é claro, é a compreensão. No coração da pós-propagação é uma expressão para a derivada parcial parcial C parcial w da função de custo C em relação a qualquer peso w (ou viés b) na rede. A expressão nos diz o quão rápido o custo muda quando mudamos os pesos e os preconceitos. E enquanto a expressão é um pouco complexa, ela também tem uma beleza, com cada elemento com uma interpretação natural e intuitiva. E, portanto, a multiplicação não é apenas um algoritmo rápido para aprender. Na verdade, nos dá informações detalhadas sobre como mudar os pesos e os preconceitos altera o comportamento geral da rede. Vale a pena estudar em detalhes. Com isso dito, se você quiser esconder o capítulo, ou pular diretamente para o próximo capítulo, está bem. Ive escreveu o resto do livro para ser acessível, mesmo se você tratar backpropagation como uma caixa preta. Há, claro, pontos mais tarde, no livro em que me recordo dos resultados deste capítulo. Mas, nesses pontos, você ainda pode entender as principais conclusões, mesmo que você não siga todo o raciocínio. Antes de discutir backpropagation, vamos aquecer com um algoritmo baseado em matriz rápido para calcular a saída de uma rede neural. Na verdade, já vimos este algoritmo brevemente no final do último capítulo. Mas descrevi-o rapidamente, então vale a pena revisar em detalhes. Em particular, esta é uma boa maneira de ficar confortável com a notação usada na backpropagation, em um contexto familiar. Comece com uma notação que nos permite referir pesos na rede de forma inequívoca. Bem, use wl para denotar o peso para a conexão do neurônio k na camada (l-1) para o neurônio j na camada l. Assim, por exemplo, o diagrama abaixo mostra o peso em uma conexão do quarto neurônio na segunda camada para o segundo neurônio na terceira camada de uma rede: Esta notação é incômoda no início, e é preciso algum trabalho para dominar. Mas com um pouco de esforço, você achará que a notação torna-se fácil e natural. Uma peculiaridade da notação é o pedido dos índices j e k. Você pode pensar que faz mais sentido usar j para se referir ao neurônio de entrada e k ao neurônio de saída, não vice-versa, como é realmente feito. Vou explicar o motivo desse quirk abaixo. Usamos uma notação semelhante para os vieses e ativações das redes. Explicitamente, usamos blj para a polarização do neurônio j na camada l. E usamos alj para a ativação do neurônio j na camada l. O diagrama a seguir mostra exemplos dessas notações em uso: com estas anotações, a ativação aj do neurônio j na camada l está relacionada às ativações na camada (l-1) pela equação (compare Equation (4) begin frac Nonumberend e discussão circundante no último capítulo) comece a seguir sigmaleft (sumk wak blj à direita), termine a etiqueta onde a soma supera todos os neurônios k na camada (l-1). Para reescrever esta expressão de forma matriz, definimos uma matriz de peso wl para cada camada, l. As entradas da matriz de peso são apenas os pesos que se conectam à camada l dos neurônios, ou seja, a entrada na linha j e a coluna k é wl. Da mesma forma, para cada camada l, definimos um vetor de polarização. Bl. Você provavelmente pode adivinhar como isso funciona - os componentes do vetor de polarização são apenas os valores blj, um componente para cada neurônio na camada l. E, finalmente, definimos um vetor de ativação cujos componentes são as ativações alj. O último ingrediente que precisamos reescrever (23) começa um j sigmaleft (sumk w a k blj right) nonumberend em uma forma de matriz é a idéia de vectorizar uma função como sigma. Nós conhecemos a vectorização brevemente no último capítulo, mas para recapitular, a idéia é que queremos aplicar uma função como sigma para cada elemento em um vetor v. Usamos o sigma da notação óbvia (v) para denotar esse tipo de aplicação elementar De uma função. Ou seja, os componentes do sigma (v) são apenas sigma (v) j sigma (vj). Como exemplo, se tivermos a função f (x) x2, então a forma vectorizada de f tem o efeito começar Fleft (início esquerdo 2 3 fim direita direita) esquerda começo f (2) f (3) fim direita esquerda início 4 9 Final direito, tag end that is, o vectorizado f apenas quadrados cada elemento do vetor. Com essas notações em mente, Equation (23) começa um j sigmaleft (sumk w a k blj right) nonumberend pode ser reescrito na forma vectorizada bonita e compacta, comece um sigma (wl a bl). Tag end Esta expressão nos dá uma maneira muito mais global de pensar sobre como as ativações em uma camada se relacionam com ativações na camada anterior: apenas aplicamos a matriz de peso às ativações, depois adicionamos o vetor de polarização e, finalmente, aplicamos a função sigma A propósito, essa é a expressão que motiva o quirk na notação wl mencionada anteriormente. Se usássemos j para indexar o neurônio de entrada e k para indexar o neurônio de saída, então, é necessário substituir a matriz de peso na Equação (25) iniciar uma sigma (wl a bl) não numerável pela transposição da matriz de peso. Essa é uma pequena mudança, mas irritante, e a matança perde a simplicidade fácil de dizer (e pensar) aplicar a matriz de peso às ativações. Essa visão global geralmente é mais fácil e mais sucinta (e envolve menos índices) do que a visão neurônio-por-neurônio que temos levado até agora. Pense nisso como uma maneira de escapar do inferno índice, enquanto permanece preciso sobre o que está acontecendo. A expressão também é útil na prática, porque a maioria das bibliotecas de matriz fornece maneiras rápidas de implementar a multiplicação de matriz, a adição de vetores e a vectorização. Na verdade, o código no último capítulo fez uso implícito desta expressão para calcular o comportamento da rede. Ao usar Equation (25), comece um sigma (wl a bl) nonumberend para calcular al, calculamos a quantidade intermediária zl equiv wl a bl ao longo do caminho. Esta quantidade revela-se útil o suficiente para valer a pena nomear: chamamos zl a entrada ponderada para os neurônios na camada l. Bem, faça um uso considerável da entrada ponderada zl mais tarde no capítulo. A equação (25) começa um sigma (wl a bl) não-numerário às vezes é escrito em termos de entrada ponderada, como al sigma (zl). Também vale a pena notar que zl tem componentes zlj sumk wl a kblj, isto é, zlj é apenas a entrada ponderada para a função de ativação do neurônio j na camada l. O objetivo da backpropagation é calcular as derivadas parciais parcial C parcial w e parcial C parcial b da função de custo C em relação a qualquer peso w ou bias b na rede. Para a reversão do trabalho, precisamos fazer duas premissas principais sobre a forma da função de custo. Antes de afirmar esses pressupostos, porém, é útil ter um exemplo de função de custo em mente. Bem use a função de custo quadrático do último capítulo (c. f. Equação (6) comece C (w, b) equiv fracumenx y (x) - a2 nonumberend). Na notação da última seção, o custo quadrático tem a forma de começar C frac somax (x) - aL (x) 2, fim da etiqueta onde: n é o número total de exemplos de treinamento a soma é superior a exemplos de treinamento individual, xyy (X) é a saída desejada correspondente L indica o número de camadas na rede e aL aL (x) é o vetor de ativações produzidas a partir da rede quando x é entrada. Ok, então, quais os pressupostos que precisamos fazer sobre nossa função de custo, C, para que a pós-propagação possa ser aplicada. O primeiro pressuposto que precisamos é que a função de custo pode ser escrita como uma C cisão média Cx sobre funções de custo Cx para indivíduo Exemplos de treinamento, x. Este é o caso da função de custo quadrático, onde o custo de um único exemplo de treinamento é Cx fractura-aL 2. Essa suposição também será válida para todas as outras funções de custo bem encontradas neste livro. A razão pela qual precisamos desta suposição é porque o que a backpropagação realmente nos permite fazer é calcular as derivadas parciais parcial Cx parcial w e parcial Cx parcial b para um único exemplo de treinamento. Em seguida, recuperamos parciais C parcial w e parcial C parcial b pela média dos exemplos de treino. Na verdade, com esta suposição em mente, bem, suponha que o exemplo de treinamento x tenha sido corrigido e solte o subíndice x, escrevendo o custo Cx como C. Bem, eventualmente, colocou o x de volta, mas, por enquanto, é um incômodo de notação melhor Deixado implícito. O segundo pressuposto que fazemos sobre o custo é que ele pode ser escrito como uma função das saídas da rede neural: por exemplo, a função de custo quadrático satisfaz esse requisito, já que o custo quadrático para um único exemplo de treinamento x pode ser escrito como Comece C frac i-aL2 frac sumj (yj-aLj) 2, tag end e, portanto, é uma função das ativações de saída. Claro, esta função de custo também depende da saída desejada y, e você pode se perguntar por que não estavam em relação ao custo também como função de y. Lembre-se, no entanto, de que o exemplo de treinamento de entrada x é fixo e, portanto, a saída y é também um parâmetro fixo. Em particular, não é algo que possamos modificar, alterando os pesos e os preconceitos de qualquer forma, ou seja, não é algo que a rede neural aprende. E então faz sentido considerar C como uma função das ativações de saída aL sozinho, com y apenas um parâmetro que ajuda a definir essa função. O algoritmo de backpropagation é baseado em operações algébricas lineares comuns - coisas como adição de vetores, multiplicando um vetor por uma matriz e assim por diante. Mas uma das operações é um pouco menos comum. Em particular, suponha que s e t sejam dois vetores da mesma dimensão. Então usamos s odot t para denotar o produto elementwise dos dois vetores. Assim, os componentes de s odot t são justos (s odot t) j sj tj. Por exemplo, comece com o começo esquerdo 1 2 final direito odot leftbegin 3 4end direita esquerda começam 1 3 2 4 final direita esquerda começam 3 8 final direito. Tag end Este tipo de multiplicação elementar às vezes é chamado de produto Hadamard ou produto Schur. Bem, consulte o produto Hadamard. As boas bibliotecas de matriz geralmente fornecem implementações rápidas do produto Hadamard, e isso é útil ao implementar backpropagation. Backpropagation é sobre a compreensão de como a mudança de pesos e vies em uma rede altera a função de custo. Em última análise, isso significa calcular as derivadas parciais parcialmente parcial parcial wl e parcial parcial C blj. Mas para computar aqueles, primeiro introduzimos uma quantidade intermediária, deltalj, que chamamos de erro no neurônio j na camada l. Backpropagation nos dará um procedimento para calcular o erro deltalj, e então irá relacionar deltalj a parcial parcial C wl e parcial parcial Blj. Para entender como o erro é definido, imagine que existe um demônio em nossa rede neural: o demônio fica no neurônio j na camada l. À medida que a entrada para o neurônio entra, o demônio toca com a operação dos neurônios. Ele adiciona uma pequena alteração Delta zlj à entrada ponderada dos neurônios, de modo que em vez de produzir sigma (zlj), o neurônio em vez disso emite sigma (zljDelta zlj). Essa mudança se propaga através de camadas posteriores na rede, causando finalmente que o custo total seja alterado por uma quantia frac Delta zlj. Agora, esse demônio é um bom demônio e está tentando ajudá-lo a melhorar o custo, ou seja, eles estão tentando encontrar um Delta zlj que reduz o custo. Suponha que a fração tenha um grande valor (positivo ou negativo). Então, o demônio pode diminuir o custo um pouco, escolhendo Delta zlj para ter o sinal oposto para frac. Em contrapartida, se frac é perto de zero, então o demônio não pode melhorar significativamente o custo, perturbando a entrada ponderada zlj. Na medida em que o demônio pode contar, o neurônio já está bastante próximo do ótimo. Este é apenas o caso de pequenas mudanças Delta zlj, é claro. Bem, suponha que o demônio é constrangido a fazer pequenas mudanças. E então há um sentido heurístico em que a fração é uma medida do erro no neurônio. Motivado por esta história, definimos o erro deltalj do neurônio j na camada l por começar deltalj equiv frac. Fim de etiqueta De acordo com nossas convenções usuais, usamos deltal para denotar o vetor de erros associados à camada l. Backpropagation nos dará uma maneira de computar deltal para cada camada e, em seguida, relacionando esses erros com as quantidades de interesse real, parcialmente parcial parcial wl e parcial parcial Blj. Você pode se perguntar por que o demônio está mudando a entrada ponderada zlj. Certamente, seria mais natural imaginar o demônio mudando a ativação de saída alj, com o resultado de que estamos usando frac como medida de erro. Na verdade, se você fizer isso, as coisas funcionam de forma semelhante à discussão abaixo. Mas acabou por tornar a apresentação de backpropagation um pouco mais algébricamente complicada. Então, fique bem com a fração deltalj como nossa medida de erro. Em problemas de classificação como o MNIST, o termo erro às vezes é usado para significar a taxa de falha de classificação. Por exemplo. Se a rede neural classificar corretamente 96,0 por cento dos dígitos, o erro é 4,0 por cento. Obviamente, isso tem um significado bastante diferente de nossos vetores delta. Na prática, você não deve ter problemas para dizer qual o significado pretendido em qualquer uso. Plano de ataque: Backpropagation é baseado em torno de quatro equações fundamentais. Juntas, essas equações nos dão uma maneira de computar tanto o erro deltal quanto o gradiente da função de custo. Indique as quatro equações abaixo. Seja avisado, porém: você não deve esperar para assimilar instantaneamente as equações. Tal expectativa levará ao desapontamento. De fato, as equações de backpropagation são tão ricas que as entender bem exige tempo e paciência consideráveis ​​à medida que aprofunda cada vez mais as equações. A boa notícia é que tal paciência é reembolsada muitas vezes. E então, a discussão nesta seção é apenas um começo, ajudando você no caminho para uma compreensão completa das equações. Heres uma prévia das formas bem aprofundar mais profundamente nas equações mais tarde no capítulo: Eu vou dar uma pequena prova das equações. O que ajuda a explicar por que eles são verdadeiros, bem, reafirmar as equações em forma algorítmica como pseudocódigo e ver como o pseudocódigo pode ser implementado como real, executando o código Python e, na seção final do capítulo. Bem, desenvolva uma imagem intuitiva do que as equações de backpropagation significam, e como alguém pode descobri-las a partir do zero. Ao longo do caminho, retorna repetidamente às quatro equações fundamentais, e ao aprofundar a sua compreensão, essas equações parecerão confortáveis ​​e, talvez, até bonitas e naturais. Uma equação para o erro na camada de saída, deltaL: os componentes do deltaL são dados pelo começo deltaLj frac sigma (zLj). Tag end Esta é uma expressão muito natural. O primeiro termo no direito, parcial C parcial aLj, apenas mede quão rápido o custo está mudando como uma função da ativação da saída j. Se, por exemplo, C não depende muito de um neurônio de saída particular, j, então deltaLj será pequeno, o que é o que espera. O segundo termo à direita, sigma (zLj), mede quão rápido a função de ativação sigma está mudando em zLj. Observe que tudo em (BP1) começa deltaLj frac sigma (zLj) nonumberend é facilmente calculado. Em particular, calculamos o zLj ao computar o comportamento da rede, e é apenas uma pequena sobrecarga adicional para calcular sigma (zLj). A forma exata de parcial parcial de ALj, naturalmente, dependerá da forma da função de custo. No entanto, desde que a função de custo seja conhecida, deve haver pouca dificuldade em computar C parcial parcial aLj. Por exemplo, se estivessem usando a função de custo quadrático, então C frac sumj (yj-aLj) 2 e, portanto, parcial C parcial aLj (ajL-yj), o que obviamente é facilmente computável. Equation (BP1) begin deltaLj frac sigma (zLj) nonumberend é uma expressão de componente para deltaL. É uma expressão perfeitamente boa, mas não a forma baseada em matriz que queremos para a pós-propagação. No entanto, é fácil reescrever a equação em uma forma baseada em matriz, como começar deltaL nablaa C odot sigma (zL). Tag end Aqui, nablaa C é definido como um vetor cujos componentes são as derivadas parciais parcial C parcial aLj. Você pode pensar em nablaa C como expressando a taxa de mudança de C em relação às ativações de saída. É fácil ver que Equations (BP1a) começam deltaL nablaa C odot sigma (zL) nonumberend e (BP1) começam deltaLj frac sigma (zLj) non-numberend são equivalentes, e por essa razão, a partir de agora, o uso do poço (BP1) começa deltaLj frac sigma (ZLj) non-numberend indiferentemente para se referir a ambas as equações. Como exemplo, no caso do custo quadrático, temos nablaa C (aL-y), e, portanto, a forma totalmente baseada em matriz de (BP1) começa deltaLj frac sigma (zLj) nonumberend torna-se começar deltaL (aL-y) odot Sigma (zL). Tag end Como você pode ver, tudo nesta expressão tem uma forma de vetor agradável e é facilmente calculado usando uma biblioteca, como Numpy. Uma equação para o erro deltal em termos do erro na próxima camada, delta: Em particular, começar deltal ((w) T delta) odot sigma (zl), marcar a extremidade em que (w) T é a transposição da matriz de peso w Para a camada (l1). Esta equação parece complicada, mas cada elemento tem uma boa interpretação. Suponhamos que conheçamos o erro delta na camada l1. Quando aplicamos a matriz de peso de transposição, (w) T, podemos pensar intuitivamente nisso como movendo o erro para trás através da rede, dando-nos algum tipo de medida do erro na saída da camada l. Em seguida, pegamos o produto Hadamard odot sigma (zl). Isso move o erro para trás através da função de ativação na camada l, dando-nos o erro deltal na entrada ponderada para a camada l. Ao combinar (BP2) começar deltal ((w) T delta) odot sigma (zl) nonumberend com (BP1) begin deltaLj frac sigma (zLj) nonumberend podemos calcular o erro deltal para qualquer camada na rede. Começamos usando (BP1) begin deltaLj frac sigma (zLj) nonumberend para calcular deltaL, então aplique Equation (BP2) begin deltal ((w) T delta) odot sigma (zl) nonumberend para calcular delta, então Equation (BP2) começa Deltal ((w) T delta) odot sigma (zl) nonumberend novamente para calcular delta, e assim por diante, todo o caminho de volta pela rede. Uma equação para a taxa de alteração do custo em relação a qualquer viés na rede: Em particular: begin fraction deltalj. Tag end Isso é, o erro deltalj é exatamente igual à taxa de alteração parcialmente parcial Blj. This is great news, since (BP1) begin deltaLj frac sigma(zLj) nonumberend and (BP2) begin deltal ((w )T delta ) odot sigma(zl) nonumberend have already told us how to compute deltalj. We can rewrite (BP3) begin frac deltalj nonumberend in shorthand as begin frac delta, tag end where it is understood that delta is being evaluated at the same neuron as the bias b. An equation for the rate of change of the cost with respect to any weight in the network: In particular: begin frac a k deltalj. tag end This tells us how to compute the partial derivatives partial C partial wl in terms of the quantities deltal and a , which we already know how to compute. The equation can be rewritten in a less index-heavy notation as begin frac a delta , tag end where its understood that a is the activation of the neuron input to the weight w, and delta is the error of the neuron output from the weight w. Zooming in to look at just the weight w, and the two neurons connected by that weight, we can depict this as: A nice consequence of Equation (32) begin frac a delta nonumberend is that when the activation a is small, a approx 0, the gradient term partial C partial w will also tend to be small. In this case, well say the weight learns slowly . meaning that its not changing much during gradient descent. In other words, one consequence of (BP4) begin frac a k deltalj nonumberend is that weights output from low-activation neurons learn slowly. There are other insights along these lines which can be obtained from (BP1) begin deltaLj frac sigma(zLj) nonumberend - (BP4) begin frac a k deltalj nonumberend . Lets start by looking at the output layer. Consider the term sigma(zLj) in (BP1) begin deltaLj frac sigma(zLj) nonumberend . Recall from the graph of the sigmoid function in the last chapter that the sigma function becomes very flat when sigma(zLj) is approximately 0 or 1. When this occurs we will have sigma(zLj) approx 0. And so the lesson is that a weight in the final layer will learn slowly if the output neuron is either low activation (approx 0) or high activation (approx 1). In this case its common to say the output neuron has saturated and, as a result, the weight has stopped learning (or is learning slowly). Similar remarks hold also for the biases of output neuron. We can obtain similar insights for earlier layers. In particular, note the sigma(zl) term in (BP2) begin deltal ((w )T delta ) odot sigma(zl) nonumberend . This means that deltalj is likely to get small if the neuron is near saturation. And this, in turn, means that any weights input to a saturated neuron will learn slowly This reasoning wont hold if T delta has large enough entries to compensate for the smallness of sigma(zlj). But Im speaking of the general tendency. Summing up, weve learnt that a weight will learn slowly if either the input neuron is low-activation, or if the output neuron has saturated, i. e. is either high - or low-activation. None of these observations is too greatly surprising. Still, they help improve our mental model of whats going on as a neural network learns. Furthermore, we can turn this type of reasoning around. The four fundamental equations turn out to hold for any activation function, not just the standard sigmoid function (thats because, as well see in a moment, the proofs dont use any special properties of sigma). And so we can use these equations to design activation functions which have particular desired learning properties. As an example to give you the idea, suppose we were to choose a (non-sigmoid) activation function sigma so that sigma is always positive, and never gets close to zero. That would prevent the slow-down of learning that occurs when ordinary sigmoid neurons saturate. Later in the book well see examples where this kind of modification is made to the activation function. Keeping the four equations (BP1) begin deltaLj frac sigma(zLj) nonumberend - (BP4) begin frac a k deltalj nonumberend in mind can help explain why such modifications are tried, and what impact they can have. Alternate presentation of the equations of backpropagation: Ive stated the equations of backpropagation (notably (BP1) begin deltaLj frac sigma(zLj) nonumberend and (BP2) begin deltal ((w )T delta ) odot sigma(zl) nonumberend ) using the Hadamard product. This presentation may be disconcerting if youre unused to the Hadamard product. Theres an alternative approach, based on conventional matrix multiplication, which some readers may find enlightening. (1) Show that (BP1) begin deltaLj frac sigma(zLj) nonumberend may be rewritten as begin deltaL Sigma(zL) nablaa C, tag end where Sigma(zL) is a square matrix whose diagonal entries are the values sigma(zLj), and whose off-diagonal entries are zero. Note that this matrix acts on nablaa C by conventional matrix multiplication. (2) Show that (BP2) begin deltal ((w )T delta ) odot sigma(zl) nonumberend may be rewritten as begin deltal Sigma(zl) (w )T delta . tag end (3) By combining observations (1) and (2) show that begin deltal Sigma(zl) (w )T ldots Sigma(z ) (wL)T Sigma(zL) nablaa C tag end For readers comfortable with matrix multiplication this equation may be easier to understand than (BP1) begin deltaLj frac sigma(zLj) nonumberend and (BP2) begin deltal ((w )T delta ) odot sigma(zl) nonumberend . The reason Ive focused on (BP1) begin deltaLj frac sigma(zLj) nonumberend and (BP2) begin deltal ((w )T delta ) odot sigma(zl) nonumberend is because that approach turns out to be faster to implement numerically. Well now prove the four fundamental equations (BP1) begin deltaLj frac sigma(zLj) nonumberend - (BP4) begin frac a k deltalj nonumberend . All four are consequences of the chain rule from multivariable calculus. If youre comfortable with the chain rule, then I strongly encourage you to attempt the derivation yourself before reading on. Lets begin with Equation (BP1) begin deltaLj frac sigma(zLj) nonumberend . which gives an expression for the output error, deltaL. To prove this equation, recall that by definition begin deltaLj frac . tag end Applying the chain rule, we can re-express the partial derivative above in terms of partial derivatives with respect to the output activations, begin deltaLj sumk frac frac , tag end where the sum is over all neurons k in the output layer. Of course, the output activation aLk of the k neuron depends only on the weighted input zLj for the j neuron when k j. And so partial aLk partial zLj vanishes when k neq j. As a result we can simplify the previous equation to begin deltaLj frac frac . tag end Recalling that aLj sigma(zLj) the second term on the right can be written as sigma(zLj), and the equation becomes begin deltaLj frac sigma(zLj), tag end which is just (BP1) begin deltaLj frac sigma(zLj) nonumberend . in component form. Next, well prove (BP2) begin deltal ((w )T delta ) odot sigma(zl) nonumberend . which gives an equation for the error deltal in terms of the error in the next layer, delta . To do this, we want to rewrite deltalj partial C partial zlj in terms of delta k partial C partial z k. We can do this using the chain rule, begin deltalj frac tag sumk frac k frac k tag sumk frac k delta k, tag end where in the last line we have interchanged the two terms on the right-hand side, and substituted the definition of delta k. To evaluate the first term on the last line, note that begin z k sumj w alj b k sumj w sigma(zlj) b k. tag end Differentiating, we obtain begin frac k w sigma(zlj). tag end Substituting back into (42) begin sumk frac k delta k nonumberend we obtain begin deltalj sumk w delta k sigma(zlj). tag end This is just (BP2) begin deltal ((w )T delta ) odot sigma(zl) nonumberend written in component form. The final two equations we want to prove are (BP3) begin frac deltalj nonumberend and (BP4) begin frac a k deltalj nonumberend . These also follow from the chain rule, in a manner similar to the proofs of the two equations above. I leave them to you as an exercise. That completes the proof of the four fundamental equations of backpropagation. The proof may seem complicated. But its really just the outcome of carefully applying the chain rule. A little less succinctly, we can think of backpropagation as a way of computing the gradient of the cost function by systematically applying the chain rule from multi-variable calculus. Thats all there really is to backpropagation - the rest is details. The backpropagation equations provide us with a way of computing the gradient of the cost function. Lets explicitly write this out in the form of an algorithm: Input x: Set the corresponding activation a for the input layer. Feedforward: For each l 2, 3, ldots, L compute z wl a bl and a sigma(z ). Output error deltaL: Compute the vector delta nablaa C odot sigma(zL). Backpropagate the error: For each l L-1, L-2, ldots, 2 compute delta ((w )T delta ) odot sigma(z ). Examining the algorithm you can see why its called back propagation. We compute the error vectors deltal backward, starting from the final layer. It may seem peculiar that were going through the network backward. But if you think about the proof of backpropagation, the backward movement is a consequence of the fact that the cost is a function of outputs from the network. To understand how the cost varies with earlier weights and biases we need to repeatedly apply the chain rule, working backward through the layers to obtain usable expressions. Backpropagation with a single modified neuron Suppose we modify a single neuron in a feedforward network so that the output from the neuron is given by f(sumj wj xj b), where f is some function other than the sigmoid. How should we modify the backpropagation algorithm in this case Backpropagation with linear neurons Suppose we replace the usual non-linear sigma function with sigma(z) z throughout the network. Rewrite the backpropagation algorithm for this case. As Ive described it above, the backpropagation algorithm computes the gradient of the cost function for a single training example, C Cx. In practice, its common to combine backpropagation with a learning algorithm such as stochastic gradient descent, in which we compute the gradient for many training examples. In particular, given a mini-batch of m training examples, the following algorithm applies a gradient descent learning step based on that mini-batch: Input a set of training examples For each training example x: Set the corresponding input activation a , and perform the following steps: Output error delta : Compute the vector delta nablaa Cx odot sigma(z ). Backpropagate the error: For each l L-1, L-2, ldots, 2 compute delta ((w )T delta ) odot sigma(z ). Gradient descent: For each l L, L-1, ldots, 2 update the weights according to the rule wl rightarrow wl-frac sumx delta (a )T, and the biases according to the rule bl rightarrow bl-frac sumx delta . Of course, to implement stochastic gradient descent in practice you also need an outer loop generating mini-batches of training examples, and an outer loop stepping through multiple epochs of training. Ive omitted those for simplicity. Having understood backpropagation in the abstract, we can now understand the code used in the last chapter to implement backpropagation. Recall from that chapter that the code was contained in the updateminibatch and backprop methods of the Network class. The code for these methods is a direct translation of the algorithm described above. In particular, the updateminibatch method updates the Network s weights and biases by computing the gradient for the current minibatch of training examples: Most of the work is done by the line deltanablab, deltanablaw self. backprop(x, y) which uses the backprop method to figure out the partial derivatives partial Cx partial blj and partial Cx partial wl . The backprop method follows the algorithm in the last section closely. There is one small change - we use a slightly different approach to indexing the layers. This change is made to take advantage of a feature of Python, namely the use of negative list indices to count backward from the end of a list, so, e. g. l-3 is the third last entry in a list l . The code for backprop is below, together with a few helper functions, which are used to compute the sigma function, the derivative sigma, and the derivative of the cost function. With these inclusions you should be able to understand the code in a self-contained way. If somethings tripping you up, you may find it helpful to consult the original description (and complete listing) of the code. Fully matrix-based approach to backpropagation over a mini-batch Our implementation of stochastic gradient descent loops over training examples in a mini-batch. Its possible to modify the backpropagation algorithm so that it computes the gradients for all training examples in a mini-batch simultaneously. The idea is that instead of beginning with a single input vector, x, we can begin with a matrix X x1 x2 ldots xm whose columns are the vectors in the mini-batch. We forward-propagate by multiplying by the weight matrices, adding a suitable matrix for the bias terms, and applying the sigmoid function everywhere. We backpropagate along similar lines. Explicitly write out pseudocode for this approach to the backpropagation algorithm. Modify network. py so that it uses this fully matrix-based approach. The advantage of this approach is that it takes full advantage of modern libraries for linear algebra. As a result it can be quite a bit faster than looping over the mini-batch. (On my laptop, for example, the speedup is about a factor of two when run on MNIST classification problems like those we considered in the last chapter.) In practice, all serious libraries for backpropagation use this fully matrix-based approach or some variant. In what sense is backpropagation a fast algorithm To answer this question, lets consider another approach to computing the gradient. Imagine its the early days of neural networks research. Maybe its the 1950s or 1960s, and youre the first person in the world to think of using gradient descent to learn But to make the idea work you need a way of computing the gradient of the cost function. You think back to your knowledge of calculus, and decide to see if you can use the chain rule to compute the gradient. But after playing around a bit, the algebra looks complicated, and you get discouraged. So you try to find another approach. You decide to regard the cost as a function of the weights C C(w) alone (well get back to the biases in a moment). You number the weights w1, w2, ldots, and want to compute partial C partial wj for some particular weight wj. An obvious way of doing that is to use the approximation begin frac approx frac , tag end where epsilon 0 is a small positive number, and ej is the unit vector in the j direction. In other words, we can estimate partial C partial wj by computing the cost C for two slightly different values of wj, and then applying Equation (46) begin frac approx frac nonumberend . The same idea will let us compute the partial derivatives partial C partial b with respect to the biases. This approach looks very promising. Its simple conceptually, and extremely easy to implement, using just a few lines of code. Certainly, it looks much more promising than the idea of using the chain rule to compute the gradient Unfortunately, while this approach appears promising, when you implement the code it turns out to be extremely slow. To understand why, imagine we have a million weights in our network. Then for each distinct weight wj we need to compute C(wepsilon ej) in order to compute partial C partial wj. That means that to compute the gradient we need to compute the cost function a million different times, requiring a million forward passes through the network (per training example). We need to compute C(w) as well, so thats a total of a million and one passes through the network. Whats clever about backpropagation is that it enables us to simultaneously compute all the partial derivatives partial C partial wj using just one forward pass through the network, followed by one backward pass through the network. Roughly speaking, the computational cost of the backward pass is about the same as the forward pass This should be plausible, but it requires some analysis to make a careful statement. Its plausible because the dominant computational cost in the forward pass is multiplying by the weight matrices, while in the backward pass its multiplying by the transposes of the weight matrices. These operations obviously have similar computational cost. And so the total cost of backpropagation is roughly the same as making just two forward passes through the network. Compare that to the million and one forward passes we needed for the approach based on (46) begin frac approx frac nonumberend . And so even though backpropagation appears superficially more complex than the approach based on (46) begin frac approx frac nonumberend . its actually much, much faster. This speedup was first fully appreciated in 1986, and it greatly expanded the range of problems that neural networks could solve. That, in turn, caused a rush of people using neural networks. Of course, backpropagation is not a panacea. Even in the late 1980s people ran up against limits, especially when attempting to use backpropagation to train deep neural networks, i. e. networks with many hidden layers. Later in the book well see how modern computers and some clever new ideas now make it possible to use backpropagation to train such deep neural networks. As Ive explained it, backpropagation presents two mysteries. First, whats the algorithm really doing Weve developed a picture of the error being backpropagated from the output. But can we go any deeper, and build up more intuition about what is going on when we do all these matrix and vector multiplications The second mystery is how someone could ever have discovered backpropagation in the first place Its one thing to follow the steps in an algorithm, or even to follow the proof that the algorithm works. But that doesnt mean you understand the problem so well that you could have discovered the algorithm in the first place. Is there a plausible line of reasoning that could have led you to discover the backpropagation algorithm In this section Ill address both these mysteries. To improve our intuition about what the algorithm is doing, lets imagine that weve made a small change Delta wl to some weight in the network, wl : That change in weight will cause a change in the output activation from the corresponding neuron: That, in turn, will cause a change in all the activations in the next layer: Those changes will in turn cause changes in the next layer, and then the next, and so on all the way through to causing a change in the final layer, and then in the cost function: The change Delta C in the cost is related to the change Delta wl in the weight by the equation begin Delta C approx frac Delta wl . tag end This suggests that a possible approach to computing frac is to carefully track how a small change in wl propagates to cause a small change in C. If we can do that, being careful to express everything along the way in terms of easily computable quantities, then we should be able to compute partial C partial wl . Lets try to carry this out. The change Delta wl causes a small change Delta a j in the activation of the j neuron in the l layer. This change is given by begin Delta alj approx frac Delta wl . tag end The change in activation Delta al will cause changes in all the activations in the next layer, i. e. the (l1) layer. Well concentrate on the way just a single one of those activations is affected, say a q, In fact, itll cause the following change: begin Delta a q approx frac q Delta alj. tag end Substituting in the expression from Equation (48) begin Delta alj approx frac Delta wl nonumberend . we get: begin Delta a q approx frac q frac Delta wl . tag end Of course, the change Delta a q will, in turn, cause changes in the activations in the next layer. In fact, we can imagine a path all the way through the network from wl to C, with each change in activation causing a change in the next activation, and, finally, a change in the cost at the output. If the path goes through activations alj, a q, ldots, a n, aLm then the resulting expression is begin Delta C approx frac frac n frac n p ldots frac q frac Delta wl , tag end that is, weve picked up a partial a partial a type term for each additional neuron weve passed through, as well as the partial Cpartial aLm term at the end. This represents the change in C due to changes in the activations along this particular path through the network. Of course, theres many paths by which a change in wl can propagate to affect the cost, and weve been considering just a single path. To compute the total change in C it is plausible that we should sum over all the possible paths between the weight and the final cost, i. e. begin Delta C approx sum frac frac n frac n p ldots frac q frac Delta wl , tag end where weve summed over all possible choices for the intermediate neurons along the path. Comparing with (47) begin Delta C approx frac Delta wl nonumberend we see that begin frac sum frac frac n frac n p ldots frac q frac . tag end Now, Equation (53) begin frac sum frac frac n frac n p ldots frac q frac nonumberend looks complicated. However, it has a nice intuitive interpretation. Were computing the rate of change of C with respect to a weight in the network. What the equation tells us is that every edge between two neurons in the network is associated with a rate factor which is just the partial derivative of one neurons activation with respect to the other neurons activation. The edge from the first weight to the first neuron has a rate factor partial a j partial wl . The rate factor for a path is just the product of the rate factors along the path. And the total rate of change partial C partial wl is just the sum of the rate factors of all paths from the initial weight to the final cost. This procedure is illustrated here, for a single path: What Ive been providing up to now is a heuristic argument, a way of thinking about whats going on when you perturb a weight in a network. Let me sketch out a line of thinking you could use to further develop this argument. First, you could derive explicit expressions for all the individual partial derivatives in Equation (53) begin frac sum frac frac n frac n p ldots frac q frac nonumberend . Thats easy to do with a bit of calculus. Having done that, you could then try to figure out how to write all the sums over indices as matrix multiplications. This turns out to be tedious, and requires some persistence, but not extraordinary insight. After doing all this, and then simplifying as much as possible, what you discover is that you end up with exactly the backpropagation algorithm And so you can think of the backpropagation algorithm as providing a way of computing the sum over the rate factor for all these paths. Or, to put it slightly differently, the backpropagation algorithm is a clever way of keeping track of small perturbations to the weights (and biases) as they propagate through the network, reach the output, and then affect the cost. Now, Im not going to work through all this here. Its messy and requires considerable care to work through all the details. If youre up for a challenge, you may enjoy attempting it. And even if not, I hope this line of thinking gives you some insight into what backpropagation is accomplishing. What about the other mystery - how backpropagation could have been discovered in the first place In fact, if you follow the approach I just sketched you will discover a proof of backpropagation. Unfortunately, the proof is quite a bit longer and more complicated than the one I described earlier in this chapter. So how was that short (but more mysterious) proof discovered What you find when you write out all the details of the long proof is that, after the fact, there are several obvious simplifications staring you in the face. You make those simplifications, get a shorter proof, and write that out. And then several more obvious simplifications jump out at you. So you repeat again. The result after a few iterations is the proof we saw earlier There is one clever step required. In Equation (53) begin frac sum frac frac n frac n p ldots frac q frac nonumberend the intermediate variables are activations like aq . The clever idea is to switch to using weighted inputs, like z q, as the intermediate variables. If you dont have this idea, and instead continue using the activations a q, the proof you obtain turns out to be slightly more complex than the proof given earlier in the chapter. - short, but somewhat obscure, because all the signposts to its construction have been removed I am, of course, asking you to trust me on this, but there really is no great mystery to the origin of the earlier proof. Its just a lot of hard work simplifying the proof Ive sketched in this section. In academic work, please cite this book as: Michael A. Nielsen, Neural Networks and Deep Learning, Determination Press, 2015 This work is licensed under a Creative Commons Attribution-NonCommercial 3.0 Unported License. This means youre free to copy, share, and build on this book, but not to sell it. If youre interested in commercial use, please contact me. Last update: Sun Jan 1 16:00:21 2017

No comments:

Post a Comment