Você está construindo um modelo Keras. Se você não está aprendendo profundamente há tanto tempo, obter as ativações de saída e a função de custo corretamente pode envolver alguma memorização (ou pesquisa). Você pode estar tentando se lembrar das diretrizes gerais como assim:
Então, com meus gatos e cães, estou fazendo classificação de duas lessons, então tenho que usar a ativação sigmóide na camada de saída, à direita e, em seguida, é o cruzentropy binário para a função de custo…
Ou: Estou fazendo classificação no ImageNet, que é multi-classa, de modo que foi softmax para ativação e, em seguida, o custo deve ser o crossentrentropia categórico…
É bom memorizar coisas como essa, mas saber um pouco sobre as razões por trás de muitas vezes facilita as coisas. Então, perguntamos: Por que essas ativações de saída e funções de custo são juntas? E eles sempre precisam?
Em poucas palavras
Simplificando, escolhemos ativações que tornam a rede prever o que queremos prever. A função de custo é então determinada pelo modelo.
Isso ocorre porque as redes neurais são normalmente otimizadas usando Versão máximae dependendo da distribuição que assumimos para as unidades de saída, a máxima verossimilhança produz diferentes objetivos de otimização. Todos esses objetivos minimizam a entropia cruzada (pragmaticamente: incompatibilidade) entre a distribuição verdadeira e a distribuição prevista.
Vamos começar com o mais simples, o caso linear.
Regressão
Para os botânicos entre nós, aqui está uma rede tremendous simples para prever a largura sépica a partir da duração do sépal:
A suposição do nosso modelo aqui é que a largura do sépal é normalmente distribuída, dada o comprimento do sépal. Na maioria das vezes, estamos tentando prever o meio de uma distribuição gaussiana condicional:
(p (y | mathbf {x} = n (y; mathbf {w}^t mathbf {h} + b) )
Nesse caso, a função de custo que minimiza a entropia cruzada (equivalentemente: otimiza a máxima verossimilhança) é Erro ao quadrado médio. E é exatamente isso que estamos usando como uma função de custo acima.
Como alternativa, podemos desejar prever a mediana dessa distribuição condicional. Nesse caso, alteraríamos a função de custo para usar o erro absoluto médio:
mannequin %>% compile(
optimizer = "adam",
loss = "mean_absolute_error"
)
Agora vamos seguir em frente além da linearidade.
Classificação binária
Somos observadores entusiasmados de pássaros e queremos que um pedido nos notifique quando há um pássaro em nosso jardim – não quando os vizinhos desembarcaram seu avião. Assim, treinaremos uma rede para distinguir entre duas lessons: pássaros e aviões.
# Utilizing the CIFAR-10 dataset that conveniently comes with Keras.
cifar10 <- dataset_cifar10()
x_train <- cifar10$prepare$x / 255
y_train <- cifar10$prepare$y
is_bird <- cifar10$prepare$y == 2
x_bird <- x_train(is_bird, , ,)
y_bird <- rep(0, 5000)
is_plane <- cifar10$prepare$y == 0
x_plane <- x_train(is_plane, , ,)
y_plane <- rep(1, 5000)
x <- abind::abind(x_bird, x_plane, alongside = 1)
y <- c(y_bird, y_plane)
mannequin <- keras_model_sequential() %>%
layer_conv_2d(
filter = 8,
kernel_size = c(3, 3),
padding = "identical",
input_shape = c(32, 32, 3),
activation = "relu"
) %>%
layer_max_pooling_2d(pool_size = c(2, 2)) %>%
layer_conv_2d(
filter = 8,
kernel_size = c(3, 3),
padding = "identical",
activation = "relu"
) %>%
layer_max_pooling_2d(pool_size = c(2, 2)) %>%
layer_flatten() %>%
layer_dense(items = 32, activation = "relu") %>%
layer_dense(items = 1, activation = "sigmoid")
mannequin %>% compile(
optimizer = "adam",
loss = "binary_crossentropy",
metrics = "accuracy"
)
mannequin %>% match(
x = x,
y = y,
epochs = 50
)
Embora normalmente falemos sobre “classificação binária”, a maneira como o resultado é geralmente modelado é como um Variável aleatória de Bernoullicondicionado aos dados de entrada. Então:
(P (y = 1 | mathbf {x}) = p, 0 leq p leq1 )
Uma variável aleatória de Bernoulli assume valores entre (0 ) e (1 ). Então é isso que nossa rede deve produzir. Uma idéia pode ser apenas recorte todos os valores de ( mathbf {w}^t mathbf {h} + b ) fora desse intervalo. Mas se fizermos isso, o gradiente nessas regiões será (0 ): A rede não pode aprender.
Uma maneira melhor é esmagar o intervalo de entrada completo no intervalo (0,1), usando a logística sigmóide função
( sigma (x) = frac {1} {1 + e^{(-x)}} )

Como você pode ver, a função sigmóide satura quando sua entrada fica muito grande ou muito pequena. Isso é problemático? Depende. No remaining, o que nos preocupamos é se a função de custo satura. Devemos escolher um erro quadrado médio aqui, como na tarefa de regressão acima, é isso que poderia acontecer.
No entanto, se seguirmos o princípio geral da máxima probabilidade/entropia cruzada, a perda será
(- log p (y | mathbf {x}) )
onde o (registro) desfaz o (exp ) no sigmóide.
Em Keras, a função de perda correspondente é binary_crossentropy
. Para um único merchandise, a perda será
- (- log (p) ) Quando a verdade do chão é 1
- (- log (1-p) ) Quando a verdade do chão é 0
Aqui, você pode ver que, quando, para um exemplo particular person, a rede prevê a classe errada e é altamente confiante sobre isso, este exemplo contribui muito fortemente para a perda.

O que acontece quando distinguimos entre mais de duas lessons?
Classificação de várias lessons
O CIFAR-10 tem 10 lessons; Então agora queremos decidir qual das 10 lessons de objetos está presente na imagem.
Aqui, primeiro é o código: não há muitas diferenças para o acima, mas observe as alterações na função de ativação e custo.
cifar10 <- dataset_cifar10()
x_train <- cifar10$prepare$x / 255
y_train <- cifar10$prepare$y
mannequin <- keras_model_sequential() %>%
layer_conv_2d(
filter = 8,
kernel_size = c(3, 3),
padding = "identical",
input_shape = c(32, 32, 3),
activation = "relu"
) %>%
layer_max_pooling_2d(pool_size = c(2, 2)) %>%
layer_conv_2d(
filter = 8,
kernel_size = c(3, 3),
padding = "identical",
activation = "relu"
) %>%
layer_max_pooling_2d(pool_size = c(2, 2)) %>%
layer_flatten() %>%
layer_dense(items = 32, activation = "relu") %>%
layer_dense(items = 10, activation = "softmax")
mannequin %>% compile(
optimizer = "adam",
loss = "sparse_categorical_crossentropy",
metrics = "accuracy"
)
mannequin %>% match(
x = x_train,
y = y_train,
epochs = 50
)
Então agora temos softmax combinado com crossentropia categórica. Por que?
Novamente, queremos uma distribuição de probabilidade válida: as probabilidades para todos os eventos disjuntistas devem somar para 1.
O CIFAR-10 tem um objeto por imagem; Portanto, os eventos são disjuntos. Depois, temos uma distribuição multinomial de um único ganho (popularmente conhecido como “Multinoulli”, principalmente devido ao Murphy’s Aprendizado de máquina(Murphy 2012)) que podem ser modelados pela ativação do softmax:
(softmax ( mathbf {z}) _ i = frac {e^{z_i}} { sum_j {e^{z_j}}} )
Assim como o sigmóide, o softmax pode saturar. Nesse caso, isso acontecerá quando diferenças Entre os resultados se tornam muito grandes. Também como no sigmóide, um (registro) Na função de custo, desfaz o (exp ) Isso é responsável pela saturação:
(log softmax ( mathbf {z}) _ i = z_i – log sum_j {e^{z_j}} )
Aqui (z_i ) é a classe que estamos estimando a probabilidade – vemos que sua contribuição para a perda é linear e, portanto, nunca pode saturar.
Em Keras, a função de perda que faz isso por nós é chamada categorical_crossentropy
. Usamos Sparse_categorical_crossententropy no código que é o mesmo que categorical_crossentropy
mas não precisa de conversão de rótulos inteiros em vetores de um quente.
Vamos dar uma olhada no que o Softmax faz. Suponha que essas sejam as saídas brutas de nossas 10 unidades de saída:

Agora é assim que a distribuição de probabilidade normalizada se parece depois de tomar o softmax:

Você vê onde o O vencedor leva tudo no título vem? Este é um ponto importante a ser lembrado: as funções de ativação não estão lá apenas para produzir certas distribuições desejadas; Eles também podem mudar as relações entre os valores.
Conclusão
Começamos este submit aludindo às heurísticas comuns, como “para classificação de várias lessons, usamos a ativação da Softmax, combinada com o Categórico Crossentropy como função de perda”. Felizmente, conseguimos mostrar por que essas heurísticas fazem sentido.
No entanto, sabendo esse pano de fundo, você também pode inferir quando essas regras não se aplicam. Por exemplo, digamos que você deseja detectar vários objetos em uma imagem. Nesse caso, o vencedor-takes-tudo A estratégia não é a mais útil, pois não queremos exagerar as diferenças entre os candidatos. Então aqui, nós usaríamos sigmóide Em todas as unidades de saída, para determinar uma probabilidade de presença por objeto.
Goodfellow, Ian, Yoshua Bengio e Aaron Courville. 2016. Aprendizado profundo. MIT Press.
Murphy, Kevin. 2012. Aprendizado de máquina: uma perspectiva probabilística. MIT Press.