StringLookup은 엑셀에서 굳이 비슷한 이름을 가진 함수를 찾아보자면, VLookup, HLookup처럼 인덱스를 찾아주는 함수인데, tensorflow version 2.4부터 tf.keras.layers.experimental.preprocessing.StringLookUp으로 만나볼 수 있습니다.
tf.keras.layers.experimental.preprocessing.StringLookup(
max_tokens=None, num_oov_indices=1, mask_token='',
oov_token='[UNK]', vocabulary=None, encoding=None, invert=False,
**kwargs
)
사용 방법은 예제만 봐도 단번에 알 수 있는데요. vocabulary를 만들어서 StringLookUp에게 던져주면, word Embedding처럼 각 data value들이 index로 표현될 수 있도록 도와주는 함수입니다.
vocab = ["a", "b", "c", "d"]
data = tf.constant([["a", "c", "d"], ["d", "z", "b"]])
layer = StringLookup(vocabulary=vocab)
layer(data)
# <tf.Tensor: shape = (2, 3), dtype=int64, numpy =
# array([[2, 4, 5],
# [5, 1, 3]])>
"a"가 index 2인 이유는 바로 다음 예제를 보면 단번에 알 수 있습니다. OOV 처리 등.
data = tf.constant([["a", "c", "d"], ["d", "z", "b"]])
layer = StringLookup()
layer.adapt(data)
layer.get_vocabulary()
# ['','[UNK]', 'd', 'z', 'c', 'b', 'a']
그런데 TesnorFlow 2.4 이전 버전은 StringLookUp 함수가 제공되지 않기 때문에 다른 방법으로 사용해야 합니다.
물론 다양한 방법이 있겠지만, tensorflow가 제공하는 함수를 활용해볼거라면 tensorflow lookup 모듈을 고려해볼 수 있었습니다.
이를 위해선 두 가지를 사용해야 합니다.
- tf.lookup.StaticHashTable
- tf.lookup.KeyValueTensorInitializer
tf.lookup.KeyValueTensorInitializer에서 vocab(key)와 data value(value)를 준비해주면, StaticHashTable에 넣어 Table을 만드는 구조인 것으로 보입니다.
이 역시 텐서플로우 공식 홈페이지 예제를 보면 쉽게 이해할 수 있습니다.
keys_tensor = tf.constant(['a', 'b', 'c'])
vals_tensor = tf.constant([7, 8, 9])
input_tensor = tf.constant(['a', 'f'])
init = tf.lookup.KeyValueTensorInitializer(keys_tensor, vals_tensor)
table = tf.lookup.StaticHashTable(
init,
default_value=-1)
table.lookup(input_tensor).numpy()
# array([7, -1], dtype = int32)
중요하진 않지만, tf 2.2에서는 table.lookup(input_tensor).numpy()가 작동하지 않습니다.
예제가 완벽히 설명해주고 있으니 추가로 설명하진 않겠습니다.
이를 활용하면 StringLookUp처럼 사용할 수 있는데, 형변환 에러가 발생합니다
(tf 2.4에서는 아마 발생하지 않을거에요).
그래서 예제처럼 사용하기보다는 Custom_Layer로 만든 후, Tensor로 변환시키게끔해서 사용해야 하는 것 같습니다.
다음처럼 구현할 수 있고, 물론 중요한 Embedding Layer와도 연결해서 사용할 수 있습니다.
import tensorflow as tf
key = tf.range(start = 0, limit = 100, delta = 1, dtype = tf.int64)
value = tf.range(start = 0, limit = 100, delta = 1, dtype = tf.int64)
table = tf.lookup.StaticHashTable(initializer=tf.lookup.KeyValueTensorInitializer(keys = key, values = value),
default_value = -1)
class custom_layer(tf.keras.layers.Layer):
def __init__(self):
super(custom_layer, self).__init__()
def call(self, inputs):
return table.lookup(inputs)
custom_layer = custom_layer()
# layer 연결
inputs = tf.keras.layers.Input(shape = (1, ), dtype = tf.int64)
encoded_feature = custom_layer(inputs)
embedding_feature = tf.keras.layers.Embedding(input_dim = 100,
output_dim = 100)(encoded_feature)
model = tf.keras.models.Model(inputs = inputs, outputs = embedding_feature)
# Embedding을 사용하지 않는 경우의 test example
# test_data = tf.constant([[50],
# [37]], dtype = tf.int64)
# model.predict(test_data) # array([[50], [37]])
- 어쨌든 버전이 높으면 뭐가 많아서 사용하긴 편해보인다...가 결론
'# Machine Learning > TensorFlow Function' 카테고리의 다른 글
Binary Accuracy vs Accuracy in TF (0) | 2021.11.10 |
---|---|
tf.data.dataset.window 예시 (0) | 2020.04.05 |
tensorflow Loss 함수에 존재하는 from_logits란 (3) | 2020.03.06 |
tf.feature_column에 포함된 여러 함수들 (0) | 2019.05.24 |
tf.image.non_max_suppression (0) | 2019.04.16 |