У меня есть странная вещь, когда я делаю фиктивную модель в Keras. По причинам, которые сейчас не важны, я решил попытаться собрать набор весов, чтобы стать единичной матрицей. Мой код:
import tensorflow as tf
from tensorflow import keras
import numpy as np
tfe = tf.contrib.eager
tf.enable_eager_execution()
i4 = np.eye(4)
inds = np.random.randint(0,4,size=2000)
data = i4[inds]
model = keras.Sequential([keras.layers.Dense(4, kernel_regularizer=
keras.regularizers.l2(.001), kernel_initializer='zeros')])
model.compile(optimizer=tf.train.AdamOptimizer(.001), loss= 'mse', metrics = ['accuracy'])
model.fit(data,inds, epochs=50)
это сделало ужасно то, что должно быть очень простой задачей. Я изменил последнюю строку на
model.fit(data, data, epochs =50)
который, по моему мнению, в основном означает, что я питаю этикетки как один из горячих векторов. С этой линией тренировка сделала именно то, что я хотел, по этой очень простой задаче. Итак, мои вопросы:
Используемая вами модель пытается минимизировать среднеквадратичную ошибку. Таким образом, очевидно, что вторая строка - путь:
model.fit(data, data, epochs=50)
потому что для изучения матрицы идентичности мы должны иметь: x =y
, и, следовательно, данные являются как входами, так и выходами.
Почему это не работает:
model.fit(data, inds, epochs=50)
Ну, в этом случае ваш сетевой выход имеет размер 4 (плотный слой), но вы даете ему выходы размером 1 (индексы). Вы должны получить сообщение об ошибке...
Как это сделать без использования одного горячего вектора для выходных векторов:
Один из способов заключается в том, чтобы вместо этого использовать редкую категорическую потерю кроссенропии:
i4 = np.eye(4)
inds = np.random.randint(0,4,size=32)
data = i4[inds]
model = keras.Sequential([keras.layers.Dense(4, kernel_initializer='zeros', activation='softmax')])
model.compile(optimizer=tf.train.AdamOptimizer(.001), loss= 'sparse_categorical_crossentropy', metrics = ['accuracy'])
model.fit(data, inds, epochs=50)
и тогда вы увидите, что модель будет очень точно соответствовать inds
:
In [4]: np.argmax(model.predict(data), axis=1)
Out[4]:
array([3, 1, 1, 3, 0, 3, 2, 0, 2, 1, 0, 2, 0, 0, 1, 2, 3, 2, 3, 0, 3, 2,
1, 2, 3, 3, 3, 1, 0, 1, 2, 0])
In [5]: inds
Out[5]:
array([3, 1, 1, 3, 0, 3, 2, 0, 2, 1, 0, 2, 0, 0, 1, 2, 3, 2, 3, 0, 3, 2,
1, 2, 3, 3, 3, 1, 0, 1, 2, 0])
и точность поезда:
In [6]: np.mean(np.argmax(model.predict(data), axis=1) == inds)
Out[6]: 1.0
sparse
версия, как я упоминал в ответе, так что вам не нужно беспокоиться о преобразовании номеров меток в один горячий вектор, и это делается более эффективно внутри.