Учитывая карту функций, например:
features = np.array([
[1, 2, 3, 4],
[2, 4, 4, 3],
[3, 2, 1, 4],
], dtype=np.float64)
, отражающую batch_size
из
batch_size = features.shape[0]
и
k = features.shape[1]
У одного есть реализация приведенных выше формул в Tensorflow может быть выражено (прототипировано) как:
dim = (batch_size, features.shape[1])
def zero(i):
arr = np.ones(dim)
arr[i] = 0
return arr
mapper = [zero(i) for i in range(batch_size)]
elems = (features, mapper)
m = (1 / (batch_size - 1)) * tf.map_fn(lambda x: tf.math.reduce_sum(x[0] * x[1], axis=0), elems, dtype=tf.float64)
pairs = tf.map_fn(lambda x: tf.concat(x, axis=0) , tf.stack([features, m], 1), dtype=tf.float64)
compactness_loss = (1 / (batch_size * k)) * tf.map_fn(lambda x: tf.math.reduce_euclidean_norm(x), pairs, dtype=tf.float64)
with tf.Session() as sess:
print("loss value output is: ", compactness_loss.eval())
Что дает:
loss value output is: [0.64549722 0.79056942 0.64549722]
Однако для пакета требуется единичная мера, поэтому необходимо ее уменьшить; суммированием всех значений.
Требуемая функция потери компактности à la Tensorflow:
def compactness_loss(actual, features):
features = Flatten()(features)
k = 7 * 7 * 512
dim = (batch_size, k)
def zero(i):
z = tf.zeros((1, dim[1]), dtype=tf.dtypes.float32)
o = tf.ones((1, dim[1]), dtype=tf.dtypes.float32)
arr = []
for k in range(dim[0]):
arr.append(o if k != i else z)
res = tf.concat(arr, axis=0)
return res
masks = [zero(i) for i in range(batch_size)]
m = (1 / (batch_size - 1)) * tf.map_fn(
# row-wise summation
lambda mask: tf.math.reduce_sum(features * mask, axis=0),
masks,
dtype=tf.float32,
)
dists = features - m
sqrd_dists = tf.pow(dists, 2)
red_dists = tf.math.reduce_sum(sqrd_dists, axis=1)
compact_loss = (1 / (batch_size * k)) * tf.math.reduce_sum(red_dists)
return compact_loss
Конечно, Flatten()
можно было бы переместить обратно в модель для удобства, а k
может быть получено непосредственно из карты функций; это отвечает на ваш вопрос. У вас могут возникнуть проблемы с определением ожидаемых значений для модели - карты характеристик из VGG16 (или любой другой архитектуры), обученные, например, для imagenet
?
В документе говорится:
В нашей формулировке (показанной на рисунке 2 (e)), начиная с предварительно обученной глубокой модели, мы фиксируем начальные функции (gs) и изучаем (gl) и (h c). На основе выходных данных подсети классификации (h c) оцениваются две потери: потеря компактности и потеря информативности. Эти две потери, представленные в следующих разделах, используются для оценки качества изученной глубинной функции. Мы используем предоставленный одноклассный набор данных для расчета потери компактности. Внешний многоклассовый эталонный набор данных используется для оценки потери информативности. Как показано на рисунке 3, веса gl и h c узнаются в предлагаемом методе посредством обратного распространения из составных потерь. После схождения обучения система, показанная в настройке на рисунке 2 (d), используется для выполнения классификации, где полученная модель используется в качестве предварительно обученной модели.
затем просматривается магистраль «Framework» здесь плюс:
Ale xNet двоичный и VGG16 двоичный (базовый) . Двоичная CNN обучается с использованием образцов Imag eNet и образцов изображений одного класса в качестве двух классов с использованием архитектур Ale xNet и VGG16 соответственно. Тестирование выполняется с использованием классификаторов k-ближайшего соседа, SVM одного класса [43], Isolation Forest [3] и Gaussian Mixture Model [3].
Заставляет меня задаться вопросом, не разумно ли было бы add предложил плотные слои для сетей Secondary
и Reference
для вывода одного класса (сигмоид) или даже для вывода двоичного класса (с использованием Softmax) и с использованием mean_squared_error
в качестве так называемой потери компактности и binary_cross_entropy
как потеря дескриптивности.