Camada única
Para inicializar os pesos de uma única camada, use uma função de torch.nn.init
. Por exemplo:
conv1 = torch.nn.Conv2d(...)
torch.nn.init.xavier_uniform(conv1.weight)
Como alternativa, você pode modificar os parâmetros gravando em conv1.weight.data
(que é a torch.Tensor
). Exemplo:
conv1.weight.data.fill_(0.01)
O mesmo se aplica a vieses:
conv1.bias.data.fill_(0.01)
nn.Sequential
ou costume nn.Module
Passe uma função de inicialização para torch.nn.Module.apply
. Ele irá inicializar os pesos em todo nn.Module
recursivamente.
aplicar ( fn ): Aplica - se fn
recursivamente a cada submódulo (conforme retornado por .children()
), bem como a si mesmo. O uso típico inclui a inicialização dos parâmetros de um modelo (consulte também torch-nn-init).
Exemplo:
def init_weights(m):
if type(m) == nn.Linear:
torch.nn.init.xavier_uniform(m.weight)
m.bias.data.fill_(0.01)
net = nn.Sequential(nn.Linear(2, 2), nn.Linear(2, 2))
net.apply(init_weights)
reset_parameters
método no código-fonte de muitos módulos. Devo substituir o método de inicialização de peso?Comparamos diferentes modos de inicialização de peso usando a mesma arquitetura de rede neural (NN).
Todos os zeros ou uns
Se você seguir o princípio da navalha de Occam , pode pensar que definir todos os pesos como 0 ou 1 seria a melhor solução. Este não é o caso.
Com todo peso igual, todos os neurônios em cada camada estão produzindo a mesma saída. Isso torna difícil decidir quais pesos ajustar.
Inicialização Uniforme
Uma distribuição uniforme tem a mesma probabilidade de escolher qualquer número de um conjunto de números.
Vamos ver o quão bem a rede neural treina usando uma inicialização de peso uniforme, onde
low=0.0
ehigh=1.0
.A seguir, veremos outra maneira (além do código da classe Net) para inicializar os pesos de uma rede. Para definir pesos fora da definição do modelo, podemos:
Regra geral para definir pesos
A regra geral para definir os pesos em uma rede neural é defini-los como próximos a zero sem serem muito pequenos.
abaixo, comparamos o desempenho de NN, pesos inicializados com distribuição uniforme [-0,5,0,5) versus aquele cujo peso é inicializado usando a regra geral
distribuição normal para inicializar os pesos
abaixo, mostramos o desempenho de dois NN, um inicializado usando distribuição uniforme e o outro usando distribuição normal
fonte
Para inicializar camadas, você normalmente não precisa fazer nada.
PyTorch fará isso por você. Se você pensar bem, isso faz muito sentido. Por que devemos inicializar camadas, quando PyTorch pode fazer isso seguindo as últimas tendências.
Verifique, por exemplo, a camada Linear .
No
__init__
método, ele chamará a função init de Kaiming He .O semelhante é para outros tipos de camadas. Por
conv2d
exemplo, verifique aqui .Observação: o ganho da inicialização adequada é a velocidade de treinamento mais rápida. Se o seu problema merece inicialização especial, você pode fazê-lo posteriormente.
fonte
xavier_uniform
inicialização para os pesos (com vieses inicializados em 0), em vez de usar a inicialização padrão, minha precisão de validação após 30 épocas de RMSprop aumentaram de 82% para 86%. Também obtive 86% de precisão de validação ao usar o modelo VGG16 integrado do Pytorch (não pré-treinado), então acho que o implementei corretamente. (Eu usei uma taxa de aprendizado de 0,00001.)fonte
Desculpe pelo atraso, espero que minha resposta ajude.
Para inicializar pesos com um
normal distribution
uso:Ou para usar uma
constant distribution
escrita:Ou para usar um
uniform distribution
:Você pode verificar outros métodos para inicializar tensores aqui
fonte
Se você quiser alguma flexibilidade extra, também pode definir os pesos manualmente .
Digamos que você tenha a opinião de todos:
E você quer fazer uma camada densa sem viés (para que possamos visualizar):
Defina todos os pesos para 0,5 (ou qualquer outra coisa):
Os pesos:
Todos os seus pesos agora são 0,5. Passe os dados por:
Lembre-se de que cada neurônio recebe 8 entradas, todas com peso 0,5 e valor 1 (e sem viés), portanto, soma 4 para cada.
fonte
Iterar sobre os parâmetros
Se você não puder usar,
apply
por exemplo, se o modelo não implementarSequential
diretamente:O mesmo para todos
Dependendo da forma
Você pode tentar
torch.nn.init.constant_(x, len(x.shape))
verificar se eles foram inicializados corretamente:fonte
Se você vir um aviso de suspensão de uso (@ Fábio Perez) ...
fonte
Porque eu não tive reputação suficiente até agora, não posso adicionar um comentário em
Mas gostaria de salientar que na verdade sabemos que algumas suposições no artigo de Kaiming He , Investigando profundamente os retificadores: superando o desempenho de nível humano na classificação ImageNet , não são adequadas, embora pareça que o método de inicialização deliberadamente projetado faz sucesso na prática .
Por exemplo, dentro da subseção de Caso de propagação para trás , eles assumem que $ w_l $ e $ \ delta y_l $ são independentes um do outro. Mas como todos nós sabemos, tome o mapa de pontuação $ \ delta y ^ L_i $ como uma instância, muitas vezes é $ y_i-softmax (y ^ L_i) = y_i-softmax (w ^ L_ix ^ L_i) $ se usarmos um típico objetivo da função de perda de entropia cruzada.
Portanto, acho que a verdadeira razão subjacente pela qual a inicialização de Ele funciona bem ainda está para ser desvendada. Porque todo mundo testemunhou seu poder em impulsionar o treinamento de aprendizagem profunda.
fonte