有没有一种方法可以在不使用一个热编码器的情况下训练 RNN?
Is there a way by which we can train RNN without using one hot encoders?
我正在尝试为我的日志分析项目开发顺序循环神经网络。
输入是一个日志序列,比如 [1,2,3,4,5,6,1,5,2,7,8,2,1]
目前我正在使用 keras 库中的 to_categorical 函数,该函数将序列转换为单热编码。
def to_categorical(y, num_classes=None, dtype='float32'):
"""Converts a class vector (integers) to binary class matrix.
E.g. for use with categorical_crossentropy.
# Arguments
y: class vector to be converted into a matrix
(integers from 0 to num_classes).
num_classes: total number of classes.
dtype: The data type expected by the input, as a string
(`float32`, `float64`, `int32`...)
# Returns
A binary matrix representation of the input. The classes axis
is placed last.
# Example
```python
# Consider an array of 5 labels out of a set of 3 classes {0, 1, 2}:
> labels
array([0, 2, 1, 2, 0])
# `to_categorical` converts this into a matrix with as many
# columns as there are classes. The number of rows
# stays the same.
> to_categorical(labels)
array([[ 1., 0., 0.],
[ 0., 0., 1.],
[ 0., 1., 0.],
[ 0., 0., 1.],
[ 1., 0., 0.]], dtype=float32)
```
"""
y = np.array(y, dtype='int')
input_shape = y.shape
if input_shape and input_shape[-1] == 1 and len(input_shape) > 1:
input_shape = tuple(input_shape[:-1])
y = y.ravel()
if not num_classes:
num_classes = np.max(y) + 1
n = y.shape[0]
categorical = np.zeros((n, num_classes), dtype=dtype)
categorical[np.arange(n), y] = 1
output_shape = input_shape + (num_classes,)
categorical = np.reshape(categorical, output_shape)
return categorical
我面临的问题是可能有一些日志可能不属于经过训练的数据让我们说 [9,10,11]
如果我有 2000 个日志键和 275 个唯一日志的序列。
总是有看不见的日志,但如果我想保存这个模型并在新数据上重用它,它可能无法将它转换为相同的分类格式,因为最初只有 275 个独特的日志 类 在我的 RNN 中,但现在我有 275+ 3 个新的 类.
我们如何解决这个问题?
您必须具有 class 一致性,否则您的模型将无法正常工作。
如果这些数字在数字上有意义,您可以使用这些数字而不是 one-hot。但是既然你说他们是 classes,他们可能没有意义。
您可以尝试将一些火车 classes 分离为未知 classes 并将它们分组为单个 one-hot 编码。然后所有新的 classes 都将接受相同的编码。
但不能保证该模型会给您带来好的结果。
关于@Dainel 关于 class 一致性的回答,您可以将训练序列中未出现的任何值替换为 np.nan
并使用 pd.get_dummies
,如下所示。
train_seq = np.array([1,2,3,4,5])
test_seq = np.array([1,2,3,4,5,6,7,8,9,10], dtype=np.float32)
test_seq[~np.isin(test_seq, train_seq)] = np.nan
df = pd.get_dummies(test_seq, dummy_na=True)
print(df)
它为看不见的数据生成一个单独的 class。
1.0 2.0 3.0 4.0 5.0 NaN
0 1 0 0 0 0 0
1 0 1 0 0 0 0
2 0 0 1 0 0 0
3 0 0 0 1 0 0
4 0 0 0 0 1 0
5 0 0 0 0 0 1
6 0 0 0 0 0 1
7 0 0 0 0 0 1
8 0 0 0 0 0 1
9 0 0 0 0 0 1
我正在尝试为我的日志分析项目开发顺序循环神经网络。
输入是一个日志序列,比如 [1,2,3,4,5,6,1,5,2,7,8,2,1]
目前我正在使用 keras 库中的 to_categorical 函数,该函数将序列转换为单热编码。
def to_categorical(y, num_classes=None, dtype='float32'):
"""Converts a class vector (integers) to binary class matrix.
E.g. for use with categorical_crossentropy.
# Arguments
y: class vector to be converted into a matrix
(integers from 0 to num_classes).
num_classes: total number of classes.
dtype: The data type expected by the input, as a string
(`float32`, `float64`, `int32`...)
# Returns
A binary matrix representation of the input. The classes axis
is placed last.
# Example
```python
# Consider an array of 5 labels out of a set of 3 classes {0, 1, 2}:
> labels
array([0, 2, 1, 2, 0])
# `to_categorical` converts this into a matrix with as many
# columns as there are classes. The number of rows
# stays the same.
> to_categorical(labels)
array([[ 1., 0., 0.],
[ 0., 0., 1.],
[ 0., 1., 0.],
[ 0., 0., 1.],
[ 1., 0., 0.]], dtype=float32)
```
"""
y = np.array(y, dtype='int')
input_shape = y.shape
if input_shape and input_shape[-1] == 1 and len(input_shape) > 1:
input_shape = tuple(input_shape[:-1])
y = y.ravel()
if not num_classes:
num_classes = np.max(y) + 1
n = y.shape[0]
categorical = np.zeros((n, num_classes), dtype=dtype)
categorical[np.arange(n), y] = 1
output_shape = input_shape + (num_classes,)
categorical = np.reshape(categorical, output_shape)
return categorical
我面临的问题是可能有一些日志可能不属于经过训练的数据让我们说 [9,10,11]
如果我有 2000 个日志键和 275 个唯一日志的序列。
总是有看不见的日志,但如果我想保存这个模型并在新数据上重用它,它可能无法将它转换为相同的分类格式,因为最初只有 275 个独特的日志 类 在我的 RNN 中,但现在我有 275+ 3 个新的 类.
我们如何解决这个问题?
您必须具有 class 一致性,否则您的模型将无法正常工作。
如果这些数字在数字上有意义,您可以使用这些数字而不是 one-hot。但是既然你说他们是 classes,他们可能没有意义。
您可以尝试将一些火车 classes 分离为未知 classes 并将它们分组为单个 one-hot 编码。然后所有新的 classes 都将接受相同的编码。
但不能保证该模型会给您带来好的结果。
关于@Dainel 关于 class 一致性的回答,您可以将训练序列中未出现的任何值替换为 np.nan
并使用 pd.get_dummies
,如下所示。
train_seq = np.array([1,2,3,4,5])
test_seq = np.array([1,2,3,4,5,6,7,8,9,10], dtype=np.float32)
test_seq[~np.isin(test_seq, train_seq)] = np.nan
df = pd.get_dummies(test_seq, dummy_na=True)
print(df)
它为看不见的数据生成一个单独的 class。
1.0 2.0 3.0 4.0 5.0 NaN
0 1 0 0 0 0 0
1 0 1 0 0 0 0
2 0 0 1 0 0 0
3 0 0 0 1 0 0
4 0 0 0 0 1 0
5 0 0 0 0 0 1
6 0 0 0 0 0 1
7 0 0 0 0 0 1
8 0 0 0 0 0 1
9 0 0 0 0 0 1