Closed vitalwarley closed 10 months ago
Permiti que o modelo usasse todo o dataset a cada época e o deixei treinando por 20 épocas na RIG2. Resultados abaixo são insatisfatórios, eu penso.
Havia inserido uma camada dentro da sequência de classificação
self.classification = nn.Sequential(
torch.nn.BatchNorm1d(256),
torch.nn.ReLU(),
# add linear, bn1d, relu
torch.nn.Linear(256, 128),
torch.nn.BatchNorm1d(128),
torch.nn.ReLU(),
torch.nn.Linear(128, 11), # number of kin relations
)
todavia os resultados não melhoraram
O treinamento foi na RIG2, com bs=60, epochs=20, onde cada época vê o dataset. Enquanto escrevo isso, lembro que os dados de treino não são aleatórios. Vou modificar e retreinar.
Melhorou, mas piorou logo depois.
Após a call de sexta, foi identificado os alguns problemas
nn.CrossEntropyLoss
espera os logits mesmo -- penso que eu tinha tido essa dúvida, e acabei lendo a doc para decidir. non_kin
-- atualmente a classe pode ser qualquer uma para qualquer par, isso é, apenas 11 classes são possíveis.Após resolver (2e89a1eb826041be7457b51588963e2b2358a9dd) esse segundo item, os resultados foram "piores" -- faz sentido, dado que a tarefa ficou mais difícil. Vale ressaltar que o dataset é bem desbalanceado, onde, por exemplo, há 10k amostras para o tipo de parentesco fs
, mas menos de 1k para gmgs
. Considerando todos os pares e tipos de relacionamentos, temos ainda cerca de 50k non-kin
.
Vou tentar novamente, mas filtrando os quatro pares mais frequentes.
Em 12 épocas, a acurácia estagnou em <0.447. Usei apenas as classes: fs, ms, md, fd. Nem non-kin
usei -- sem querer. Isso mostra que a tarefa é complexa demais e/ou o modelo é incapaz de aprender os padrões.
Em 12 épocas, a acurácia estagnou em <0.447. Usei apenas as classes: fs, ms, md, fd. Nem
non-kin
usei -- sem querer. Isso mostra que a tarefa é complexa demais e/ou o modelo é incapaz de aprender os padrões.
Esse resultado está enviesado porque faltou modificar a saída do modelo.
Após corrigir o viés acima, isso é, ajustar a saída da rede para o número de classes corretamente, eu repliquei o treinamento de identificação das classes fs, ms, md, fd. Abaixo o resultado
Pensei que havia pares non-kin
no set de treino, mas não há. Apenas nos sets de validação e teste.
Pensei que havia pares
non-kin
no set de treino, mas não há. Apenas nos sets de validação e teste.
A razão para tal está na seção III do artigo
In our supervised contrastive learning framework, negative samples are collected by combining positive samples from different families. Typically, the contrastive loss makes samples belonging to the same family close to each other in the feature space, while samples belonging to different families are separated from each other. The hyper-parameter τ is used to control the degree of punishment for hard samples, and the smaller the value of τ , the greater the degree of punishment for hard samples.
Durante o treinamento, x1
e x2
são batches contendo as imagens do indivíduo 1 e 2, respectivamente. Os autores concatenam os batches duas vezes e formam os tensores x1x2
e x2x1
. Em seguida, computa-se a similaridade entre todos pares em x1x2
, como exemplificado abaixo. A soma do exponencial da matriz de similaridades ao longo das colunas (exceto nas diagonais) forma o denominador.
Posteriormente obtém-se a similaridade entre os tensores x1x2
e x2x1
. ~Dado que o batch contém diferentes famílias, isso é, há apenas uma família por par, essa similaridade é basicamente de pares negativos.~ O exponencial dos elementos (similaridades) de cada matriz consiste do numerador da fórmula.
A ideia geral, ao meu ver, é que a divisão convirja para de 1 a partir da esquerda tal que o negativo do log se aproxime de 0 pela direita. As similaridades para minimizar maximizar estão no numerador, logo seu valor deve tender a 0 (e.g., e^(-1/beta) < 0.0001, para beta = 0.08) 1. Similarmente, as similaridades para maximizar estão no denomidador; apesar de lá também haver similaridades para minimizar, o exponencial da similaridade dos pares positivos (1 coluna em cada linha, logo 1 de n) são bem maiores que zero (e.g., e^(1/beta) > 10000, para beta = 0.08), enquanto que o exponencial da similaridade dos pares negativos (n - 1 elementos) tende zero. Dessa forma, a soma dos exponenciais é dominada pelos pares positivos, o que maximiza o denominador.
Agora a questão é: como inserir informações sobre a diferença de idade (e gênero, possivelmente) nessa perda?
Na verdade, o numerador deve também ser maximizado. x1x2
e x2x1
contém apenas pares positivos. Considere x1 = (a1, b1, c1), x2 = (a2, b2, c2). Temos, então
x1x2 x2x1 similaridade
0 a1 a2 1
1 b1 b2 1
2 c1 c2 1
3 a2 a1 1
4 b2 b1 1
5 c2 c1 1
Isso reflete a equação 1 do artigo.
Considerando isso, o numerador deve crescer o máximo possível. Abaixo um gráfico exemplificando o processo
Esse outro gráfico mostra o que conseguimos ao variar beta
Será realizada em futuras estratégias ainda, possivelmente.
Deixei um treinamento rodando de ontem para hoje e obtive os resultados abaixo. Esse treinamento devia ter ido até a época 160, mas parou na 107, porque os pares de treino acabaram. A razão é que os autores originais fizeram assim. No treinamento para verificação de parentesco, por exemplo, parece que cada par é visto apenas uma vez pelo modelo. Talvez para nosso classo possamos mudar?
Minhas mudanças foram pontuais nos códigos originais
Mantive todo o resto, como SGD com lr=1e-4 e momento = 0.9.