Разница между tf.keras Tensorflow.слои.Плотный и факел Пайторча.nn.Линейный?

#tensorflow #pytorch

Вопрос:

У меня есть быстрый (и, возможно, глупый) вопрос о том, как Tensorflow определяет свой линейный слой. В PyTorch линейный (или плотный) слой определяется как y = x A^T b, где A и b-матрица веса и вектор смещения для линейного слоя (см. Здесь).

Однако я не могу точно найти эквивалентное уравнение для тензорного потока! Это то же самое, что и PyTorch, или это просто y = x A b ?

Заранее благодарю вас!

Ответ №1:

Если мы установим активацию None в плотном слое в keras API, то они технически эквивалентны.

Тензорный поток

 tf.keras.layers.Dense(..., activation=None) 
 

Согласно доктору, здесь больше исследований.

активация: Функция активации для использования. Если вы ничего не укажете, активация не будет применена (т. е. «линейная» активация: a(x) = x).

И в src Пайторча.

 torch.nn.Linear
 

На данный момент они равны. Линейное преобразование входящих данных: y = x*W^T b . Смотрите следующую более конкретную эквивалентную реализацию этих двух. В PyTorch , мы делаем

 class Network(torch.nn.Module):
    def __init__(self):
        super(Network, self).__init__()
        self.fc1 = torch.nn.Linear(5, 30)
    def forward(self, state):
        return self.fc1(state)
 

или,

 trd = torch.nn.Linear(in_features = 3, out_features = 30)
y = trd(torch.ones(5, 3))
print(y.size())
# torch.Size([5, 30])
 

Его эквивалентная tf реализация была бы

 model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Dense(30, input_shape=(5,), activation=None)) 
 

или,

 tfd = tf.keras.layers.Dense(30, input_shape=(3,), activation=None)
x = tfd(tf.ones(shape=(5, 3)))
print(x.shape)
# (5, 30)
 

Комментарии:

1. То, что я имею в виду с точки зрения различий, относится исключительно к линейной алгебре операции. А не просто форма выходного тензора. Например, кажется, что плотный слой Tensorflow равен либо y = xA b, либо y = Ax b, а линейный слой PyTorch равен y = xA^T b. Хотя они имеют одинаковую форму, их производные отличаются.

2. О, я понимаю. Название вопроса смутило меня. Похоже, вы хотели знать, как они рассчитываются. Ответ Алекса должен вас устраивать.

3. Да, я мог бы сформулировать это немного лучше. Но, несмотря на это, мне просто нужно было прояснить саму Линейную алгебру и то, как эти слои различаются между Линейными. Производная является одним из примеров того, как они отличаются ( поскольку это разные линейные операции альграбры ). Я высказал «предположение» о том, что такое плотный слой TF и совпадает ли он. Итак, я мог бы отредактировать название, если другие люди подумают, что это поможет с разъяснением! Тем не менее, спасибо за объяснение плотного слоя TF! 😀

Ответ №2:

tf.keras.layers.Dense определяется здесь в исходном коде tensorflow:

https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/keras/layers/core.py#L1081

Если вы будете следовать ссылкам в его call функции, это приведет вас к определению используемой здесь операции, которая действительно представляет собой матричное умножение входных данных и весов плюс вектор смещения, как и ожидалось:

https://github.com/tensorflow/tensorflow/blob/a68c6117a1a53431e739752bd2ab8654dbe2534a/tensorflow/python/keras/layers/ops/core.py#L74

 outputs = gen_math_ops.MatMul(a=inputs, b=kernel)
...
outputs = nn_ops.bias_add(outputs, bias)

 

Комментарии:

1. Итак, определение kernel переменной-это матрица веса, но противоположного измерения матрицы веса PyTorch? Итак, допустим, у меня есть входные функции размера пакета N и выходные функции B. Размерность kernel будет [A, B], тогда как в случае PyTorch это будет [B, A] (потому что к нему применяется транспонирование?)

2. Да, они хранят веса немного по-разному (W. T против W), но результат все равно тот же. Представление Пайторча ближе к обозначениям в учебниках. Вы можете быстро проверить это, распечатав форму линейных/плотных весов в torch и tf.

3. В строке 1192 первой ссылки на исходный код TF выше веса в инициализируются с shape=[last_dim, self.units] помощью (N_feats, N_out), а в PyTorch (ссылка на исходный код) веса инициализируются с Parameter(torch.Tensor(out_features, in_features)) помощью (N_out, N_feats)

4. Хорошо, поэтому для линейного слоя ввода x формы (N_samp, N_feats) выводом для TF будет matmul(x, A) b, где A (N_feats, N_out) и b (N_out,), а для PyTorch это matmul(x, A^T) b, где A сейчас (N_out, N_feats) и b (N_out,). Хорошо, похоже, что 2 библиотеки определяют свои линейные слои по-разному! Спасибо @Alex!