Я работаю над полуобучаемым методом обучения и хочу добавить штраф к большим потерям в назначениях кластеров. В Керасе есть функция дисперсии (я использую бэкэнд тензорного потока). Моя идея заключалась в том, чтобы использовать функцию тензорного потока boolean_mask () для индексации только подматрицы одного кластера за раз. Однако для итерации кластеров потребуется всего лишь oop, что приведет к проблемам, т.е. к потерям NaN.
Есть ли способ векторизации этой операции?
(Это, очевидно, очень упрощенная версия моего кода и термин потери не имеет большого смысла в этом контексте.)
import tensorflow as tf
import keras
from keras.models import Model
from keras.layers import Dropout, Dense, Input
from keras.optimizers import SGD
from keras.activations import relu
from keras.initializers import RandomNormal
import keras.backend as K
import numpy as np
from sklearn.datasets import make_blobs
n_clusters = 100
n_features = 2
# create toy data with 100 clusters
X, y = make_blobs(n_samples=10000, cluster_std = 0.5, centers=n_clusters, random_state=1)
inputs = Input(shape=(n_features,))
outputs = Dropout(0.2)(inputs)
outputs = Dense(500, activation='relu', kernel_initializer=RandomNormal(0.0,0.01))(outputs)
outputs = Dropout(0.2)(outputs)
outputs = Dense(n_clusters, kernel_initializer=RandomNormal(0.0,0.01))(outputs)
# custom loss
def loss_var(y_true, q):
# input: labels y_true, soft clustering assignments q
var=0
for c in range(n_clusters):
# get indices of cluster c
mask = K.equal(y_true, c)
# boolean mask for indexing q, get only cluster c elements
q_c = tf.boolean_mask(q, mask, axis=0)
# variance of this cluster
var += K.mean(K.var(q_c, axis=0))
var = var / n_clusters
return var
model = Model(inputs, outputs)
model.compile(optimizer=SGD(lr=0.1, momentum=0.9), loss=loss_var)
model.fit(X,y,batch_size=256, epochs=10)