Существует ли API с керасом тензорного потока для определения того, где функции оказываются в плотном слое? То есть, учитывая список столбцов функций, скажем
cols = [numeric_feature, bucketized_feature, embedded_categorical_feature]
, и если вы затем создадите слой функций
feature_layer = tf.keras.layers.DenseFeatures(cols)
, как вы можете определить, какой столбец numeric_feature занимает в feature_layer? Аналогично, если bucketized_feature - это 3 ведра, где эти 3 столбца? numeri c и с разделением на две части, а также размер встраивания - из-за его использования в коде это кажется «официальным» способом определения ширины объекта в плотном слое, но я не видел API чтобы указать порядок функций - я думал, что это будет их порядок в аргументе cols
для DenseLayer
, но мой тест показывает, что это не так, порядок embedded_categorical
, numeric
, bucketized
, когда Я даю numeric
bucketized
, а затем категоричный в конце.
Было бы неплохо иметь возможность идентифицировать расположение пространственных объектов в плотном слое - но, возможно, это не определено каким-то образом пользователь может положиться на?
Ниже приведен модульный тест, который не прошел, потому что я предполагал, что заказ был для списка cols
import unittest
import numpy as np
import tensorflow as tf
from tensorflow import feature_column
def where_feats_in_concat_state(state_columns):
locs = {}
next_loc = 0
for feature_column in state_columns:
width = feature_column.variable_shape.num_elements()
locs[feature_column.name] = {"start": next_loc, "width": width}
next_loc += width
return locs
class WhereFeatsInConcatState(unittest.TestCase):
def test_basic(self):
N = 10
vocab_N = 20
bsize = 1
vocab = list(map(str, np.arange(vocab_N)))
data = {'numeric1': np.random.randn(N, 1).astype(np.float32),
'numeric2': np.random.randn(N, 1).astype(np.float32),
'categorical1': np.reshape(np.array(list(map(str, np.random.randint(0, vocab_N-1, N)))), [N, 1]),
'categorical2': np.reshape(np.array(list(map(str, np.random.randint(0, vocab_N, N)))), [N, 1])}
numeric1 = feature_column.numeric_column("numeric1")
numeric2 = feature_column.numeric_column("numeric2")
bins = [-2, -1, -0.5, -0.1, .1, 0.5, 1, 2]
bucket1 = feature_column.bucketized_column(numeric2, boundaries=bins)
cat1 = feature_column.categorical_column_with_vocabulary_list('categorical1', vocab)
cat2 = feature_column.categorical_column_with_vocabulary_list('categorical2', vocab)
emb1 = feature_column.embedding_column(cat1, dimension=4)
emb2 = feature_column.embedding_column(cat2, dimension=3)
state_columns = [numeric1, bucket1, emb1, emb2]
locs = where_feats_in_concat_state(state_columns=state_columns)
numeric1_start, numeric1_width = locs['numeric1']['start'], locs['numeric1']['width']
bucket1_start, bucket1_width = locs['numeric2_bucketized']['start'], locs['numeric2_bucketized']['width']
emb1_start, emb1_width = locs['categorical1_embedding']['start'], locs['categorical1_embedding']['width']
emb2_start, emb2_width = locs['categorical2_embedding']['start'], locs['categorical2_embedding']['width']
state_width = emb2_start + emb2_width
self.assertEqual(1, numeric1_width)
feature_layer = tf.keras.layers.DenseFeatures(state_columns)
ds = tf.data.Dataset.from_tensor_slices(data).batch(bsize)
for idx, batch in enumerate(ds):
state = feature_layer(batch).numpy()
self.assertEqual(state_width, state.shape[1])
numeric1_answser = data['numeric1'][idx, 0]
numeric2_answser = data['numeric2'][idx, 0]
bucket2_idx_answer = np.digitize(numeric2_answser, bins=bins, right=False)
bucket2_onehot_answer = np.eye(1 + len(bins))[bucket2_idx_answer]
where_res = state[0, numeric1_start]
self.assertAlmostEqual(numeric1_answser, where_res,
msg="idx=%d feat=numeric1\nanswer=%.3f col=%d\nres=%.3f\nstate=%s\nbucket2_one_hot=%s" %
(idx, numeric1_answser, numeric1_start, where_res, state, bucket2_onehot_answer))
if __name__ == "__main__":
unittest.main()
Последний запуск дал:
AssertionError: 1.178217 != 0.25312936 within 7 places (0.9250877 difference) : idx=0 feat=numeric1
answer=1.178 col=0
res=0.253
state=[[ 0.25312936 0.08003955 -0.01629014 0.23871408 0.3213957 -0.4140397
0.51011735 1.178217 0. 0. 0. 0.
0. 0. 1. 0. 0. ]]
bucket2_one_hot=[0. 0. 0. 0. 0. 0. 1. 0. 0.]
, что показывает, что это вложения, numeri c, чем ведро.