Я пытаюсь реализовать CNN для оценки трехмерной человеческой позы по карте глубины из этой статьи: https://www.researchgate.net/publication/326437587_3D_human_pose_estimation_from_depth_maps_using_a_deep_combination_of_poses
Однако моя реализация в керасе, и я никак не могу достичьта же точность, что и в статье.Моя главная проблема, похоже, заключается в регуляризации, так как я могу почти переопределить (средняя ошибка ~ 1 см) тренировочный набор данных при отсутствии регуляризации, но при использовании члена регуляризации в функции потерь так же, как упомянуто в статье, обаошибка обучения и проверки увеличивается.Я могу понять, почему ошибка обучения выше, но я предполагаю, что ошибка проверки должна уменьшиться.Я также использую выпадение 0.2, как указано в статье.
Вот как я построил модель:
def DPP(weights=None):
model = Sequential()
model.add(Conv2D(filters=96, kernel_size=(7, 7), strides=(1, 1), input_shape=(100, 100, 1),
kernel_initializer=keras.initializers.glorot_normal(),
data_format="channels_last",
bias_initializer='zeros', activation='relu'))
model.add(MaxPooling2D((2, 2), strides=(2, 2)))
model.add(Conv2D(filters=192, kernel_size=(5, 5), strides=(2, 2), activation='relu'))
model.add(MaxPooling2D((2, 2), strides=(2, 2)))
model.add(Conv2D(filters=512, kernel_size=(3, 3), strides=(1, 1), activation='relu'))
model.add(MaxPooling2D((2, 2), strides=(2, 2)))
model.add(Conv2D(filters=1024, kernel_size=(2, 2), strides=(2, 2), activation='relu'))
model.add(Conv2D(filters=2048, kernel_size=(2, 2), strides=(1, 1),
activation='relu'))
model.add(Flatten())
model.add(Dense(1024))
model.add(Dropout(0.2))
model.add(Dense(256))
model.add(Dense(K, name='output'))
if weights:
model.load_weights(weights)
return model
и мою реализацию функции потерь:
def loss_function(y_true, y_pred):
y = Kb.stack([y_pred] * (J * 3), axis=-1)
yt = Kb.permute_dimensions(y, [0, 2, 1]) # same weight for each joint in particular prototype in column
# normalize
tci = Kb.transpose(Kb.transpose(C) - meanpose)
tci = Kb.transpose(Kb.transpose(tci) / np.sqrt(varpose))
#######
c_pred = yt * tci
c_pred = Kb.sum(c_pred, axis=-1)
# back to real center and scale
c_pred = c_pred * np.sqrt(varpose)
c_pred = c_pred + meanpose
#######
y_true = Reshape(target_shape=(J * 3,))(y_true) # flatten last two dimensions (15,3) into one
reslos = res_loss(c_pred, y_true)
p1 = (1 - alpha) * reslos
reg_term = alpha * L1(y_pred)
return p1 + reg_term
def L1(v):
return Kb.sum(Kb.abs(v), axis=-1)
def res_loss(pred, gtrue):
r = gtrue - pred
logic = Kb.less(Kb.abs(r), 1 / (o ** 2))
p = Kb.switch(logic, 0.5 * (o ** 2) * Kb.square(r), Kb.abs(r) - (0.5 / (o ** 2)))
return Kb.sum(p, axis=-1)
где C - тензор с позами прототипа, meanpose и varpose - среднее значение и вариация набора данных кластеризованного поезда.
Есть ли что-то очевидное, что я упускаю в отношении регуляризации?