Eu sei que existe uma possibilidade no Keras com o class_weights
dicionário de parâmetros no ajuste, mas não encontrei nenhum exemplo. Alguém seria tão gentil em fornecer um?
A propósito, nesse caso, a práxis apropriada é simplesmente ponderar a classe minoritária proporcionalmente à sua sub-representação?
classification
keras
weighted-data
Hendrik
fonte
fonte
Respostas:
Se você está falando sobre o caso regular, em que sua rede produz apenas uma saída, sua suposição está correta. Para forçar seu algoritmo a tratar todas as instâncias da classe 1 como 50 instâncias da classe 0, você deve:
Defina um dicionário com seus rótulos e seus pesos associados
Alimente o dicionário como um parâmetro:
EDIT: "tratar todas as instâncias da classe 1 como 50 instâncias da classe 0 " significa que na sua função de perda você atribui um valor mais alto a essas instâncias. Portanto, a perda se torna uma média ponderada, onde o peso de cada amostra é especificado por class_weight e sua classe correspondente.
Do Keras docs: class_weight : índices de classe de mapeamento de dicionário opcionais (números inteiros) para um valor de peso (flutuante), usado para ponderar a função de perda (apenas durante o treinamento).
fonte
Você pode simplesmente implementar o
class_weight
desklearn
:Vamos importar o módulo primeiro
Para calcular o peso da classe, faça o seguinte
Em terceiro e último lugar, adicione-o ao encaixe do modelo
Atenção : Editei este post e alterei o nome da variável de class_weight para class_weight s para não sobrescrever o módulo importado. Ajuste de acordo ao copiar o código dos comentários.
fonte
class_weight.compute_class_weight
produz uma matriz, preciso alterá-la para um ditado para trabalhar com Keras. Mais especificamente, após a etapa 2, useclass_weight_dict = dict(enumerate(class_weight))
y_train
é um(300096, 3)
array numpy. Assim, aclass_weight=
linha dá-me TypeError: Tipo unhashable: 'numpy.ndarray'y_ints = [y.argmax() for y in y_train]
.Eu uso esse tipo de regra para
class_weight
:math.log
suaviza os pesos para classes muito desequilibradas! Isso retorna:fonte
n_total_samples / n_class_samples
para cada aula.NOTA: Veja os comentários, esta resposta está desatualizada.
Para ponderar todas as classes igualmente, agora você pode simplesmente definir class_weight como "auto" da seguinte forma:
fonte
class_weight='auto'
na documentação do Keras nem no código-fonte. Você pode nos mostrar onde encontrou isso?class_weight
e ela não terá efeito. Esta resposta não está correta.class_weight é bom, mas como @Aalok disse que isso não funcionará se você for um tipo de codificação de classes com várias tags. Nesse caso, use sample_weight :
sample_weights é usado para fornecer um peso para cada amostra de treinamento . Isso significa que você deve passar uma matriz 1D com o mesmo número de elementos que suas amostras de treinamento (indicando o peso de cada uma dessas amostras).
class_weights é usado para fornecer um peso ou viés para cada classe de saída . Isso significa que você deve passar um peso para cada classe que você está tentando classificar.
sample_weight deve receber uma matriz numpy, pois sua forma será avaliada.
Consulte também esta resposta: https://stackoverflow.com/questions/48315094/using-sample-weight-in-keras-for-sequence-labelling
fonte
Adicionando à solução em https://github.com/keras-team/keras/issues/2115 . Se você precisar de mais do que ponderação de classe, em que deseja custos diferentes para falsos positivos e falsos negativos. Com a nova versão do keras agora você pode simplesmente substituir a respectiva função de perda, conforme indicado abaixo. Observe que
weights
é uma matriz quadrada.fonte
Encontrei o exemplo a seguir de codificação de pesos de classe na função de perda usando o conjunto de dados minist. Veja o link aqui: https://github.com/keras-team/keras/issues/2115
fonte
Isso funciona com um gerador ou padrão. Sua classe maior terá um peso 1, enquanto os outros terão valores maiores que 1 em relação à maior classe.
pesos de classe aceita uma entrada de tipo de dicionário
fonte