CMC*_*kai 3 python keras tensorflow pytorch
我看到这个问题:Implementing custom loss function in keras with condition我需要做同样的事情,但代码似乎需要循环。
我有一个自定义numpy函数,可以计算与平均向量的平均欧几里得距离。我根据论文https://arxiv.org/pdf/1801.05365.pdf写了这篇文章:
import numpy as np
def mean_euclid_distance_from_mean_vector(n_vectors):
dists = []
for (i, v) in enumerate(n_vectors):
n_vectors_rest = n_vectors[np.arange(len(n_vectors)) != i]
print("rest of vectors: ")
print(n_vectors_rest)
# calculate mean vector
mean_rest = n_vectors_rest.mean(axis=0)
print("mean rest vector")
print(mean_rest)
dist = v - mean_rest
print("dist vector")
print(dist)
dists.append(dist)
# dists is now a matrix of distance vectors (distance from the mean vector)
dists = np.array(dists)
print("distance vector matrix")
print(dists)
# here we matmult each vector
# sum them up
# and divide by the total number of elements
result = np.sum([np.matmul(d, d) for d in dists]) / dists.size
return result
features = np.array([
[1,2,3,4],
[4,3,2,1]
])
c = mean_euclid_distance_from_mean_vector(features)
print(c)
Run Code Online (Sandbox Code Playgroud)
tensorflow但是我需要这个函数才能在Keras 中工作。所以自定义 lambda https://www.tensorflow.org/api_docs/python/tf/keras/layers/Lambda
但是,我不确定如何在 Keras/Tensorflow 中实现上述内容,因为它有循环,并且论文中讨论的计算方式似乎m_i需要循环,就像我实现上面的方式一样。
作为参考,此代码的 PyTorch 版本位于: https: //github.com/PramuPerera/DeepOneClass
给定一个特征图,例如:
\n\nfeatures = np.array([\n [1, 2, 3, 4],\n [2, 4, 4, 3],\n [3, 2, 1, 4],\n], dtype=np.float64)\nRun Code Online (Sandbox Code Playgroud)\n\nbatch_size反映了一个
batch_size = features.shape[0]\nRun Code Online (Sandbox Code Playgroud)\n\n和
\n\nk = features.shape[1]\nRun Code Online (Sandbox Code Playgroud)\n\n在 Tensorflow 中实现上述公式可以通过以下方式表达(原型化):
\n\ndim = (batch_size, features.shape[1])\ndef zero(i):\n arr = np.ones(dim)\n arr[i] = 0\n return arr\n\n\nmapper = [zero(i) for i in range(batch_size)]\nelems = (features, mapper)\nm = (1 / (batch_size - 1)) * tf.map_fn(lambda x: tf.math.reduce_sum(x[0] * x[1], axis=0), elems, dtype=tf.float64)\npairs = tf.map_fn(lambda x: tf.concat(x, axis=0) , tf.stack([features, m], 1), dtype=tf.float64)\ncompactness_loss = (1 / (batch_size * k)) * tf.map_fn(lambda x: tf.math.reduce_euclidean_norm(x), pairs, dtype=tf.float64)\n\nwith tf.Session() as sess:\n print("loss value output is: ", compactness_loss.eval())\nRun Code Online (Sandbox Code Playgroud)\n\n其产量:
\n\nloss value output is: [0.64549722 0.79056942 0.64549722]\nRun Code Online (Sandbox Code Playgroud)\n\n但批量需要单次测量,因此需要减少;通过所有值的总和。
\n\nTensorflow 所需的紧凑性损失函数 \xc3\xa0 为:
\n\ndef compactness_loss(actual, features):\n features = Flatten()(features)\n k = 7 * 7 * 512\n dim = (batch_size, k)\n\n def zero(i):\n z = tf.zeros((1, dim[1]), dtype=tf.dtypes.float32)\n o = tf.ones((1, dim[1]), dtype=tf.dtypes.float32)\n arr = []\n for k in range(dim[0]):\n arr.append(o if k != i else z)\n res = tf.concat(arr, axis=0)\n return res\n\n masks = [zero(i) for i in range(batch_size)]\n m = (1 / (batch_size - 1)) * tf.map_fn(\n # row-wise summation\n lambda mask: tf.math.reduce_sum(features * mask, axis=0),\n masks,\n dtype=tf.float32,\n )\n dists = features - m\n sqrd_dists = tf.pow(dists, 2)\n red_dists = tf.math.reduce_sum(sqrd_dists, axis=1)\n compact_loss = (1 / (batch_size * k)) * tf.math.reduce_sum(red_dists)\n return compact_loss\nRun Code Online (Sandbox Code Playgroud)\n\n当然,Flatten()为了方便起见,可以将其移回模型中,并且k可以直接从特征图中导出;这回答了你的问题。您可能只是在找出模型的预期值时遇到一些麻烦 - 例如针对 VGG16(或任何其他架构)训练的特征图imagenet?
论文称:
\n\n\n\n\n在我们的公式中(如图 2 (e) 所示),从预训练的深度模型开始,我们冻结初始特征 (gs) 并学习 (gl) 和 (hc)。基于分类子网络(hc)的输出,评估两个损失:紧凑性损失和描述性损失。后续部分介绍的这两个损失用于评估学习的深度特征的质量。我们使用提供的一类数据集来计算紧凑性损失。使用外部多类参考数据集来评估描述性损失。如图3所示,在所提出的方法中,gl和hc的权重是通过复合损失的反向传播来学习的。一旦训练收敛,图 2(d) 中设置所示的系统将用于执行分类,其中生成的模型用作预训练模型。
\n
然后看看这里的“框架”主干加上:
\n\n\n\n\nAlexNet 二进制和 VGG16 二进制(基线)。通过分别使用 AlexNet 和 VGG16 架构将 ImageNet 样本和一类图像样本作为两个类别来训练二值 CNN。使用 k 最近邻、一类 SVM [43]、隔离森林 [3] 和高斯混合模型 [3] 分类器进行测试。
\n
Secondary让我想知道将建议的密集层添加到和Reference网络到单类输出(Sigmoid)或偶数和二进制类输出(使用 Softmax)并使用mean_squared_error所谓的紧凑性损失和binary_cross_entropy作为是否不合理描述性损失。