我正在尝试为进程创建自动编码器。每个过程都是一系列事件,每个事件代表从0到461的数字(重要的是,具有接近数字的事件不相似,数字是随机发出的)。每个流程的长度为60,流程总数为n
。所以我的输入数据是数组(n, 60)
。
首先,我创建了嵌入层,将事件数转换为单热表示:
BLOCK_LEN = 60
EVENTS_CNT = 462
input = Input(shape=(BLOCK_LEN,))
embedded = Embedding(input_dim=EVENTS_CNT+1, input_length=BLOCK_LEN, output_dim=200)(input)
emb_model = Model(input, embedded)
emb_model.summary()
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) (None, 60) 0
_________________________________________________________________
embedding_1 (Embedding) (None, 60, 200) 92600
=================================================================
Total params: 92,600
Trainable params: 92,600
Non-trainable params: 0
_________________________________________________________________
None
其次,我创建了主要的Seq2Seq模型(使用that library):
seq_model = Seq2Seq(batch_input_shape=(None, BLOCK_LEN, 200), hidden_dim=200, output_length=BLOCK_LEN, output_dim=EVENTS_CNT)
结果模型:
model = Sequential()
model.add(emb_model)
model.add(seq_model)
model.summary()
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
model_1 (Model) (None, 60, 200) 92600
_________________________________________________________________
model_12 (Model) (None, 60, 462) 1077124
=================================================================
Total params: 1,169,724
Trainable params: 1,169,724
Non-trainable params: 0
_________________________________________________________________
此外,我有自己的准确度指标(因为lib的准确度并不适合我的数据):
def symbol_acc(y_true, y_pred):
isEqual = K.cast(K.equal(y_true, y_pred), K.floatx())
return K.mean(isEqual)
编译:
model.compile(loss=tf.losses.sparse_softmax_cross_entropy,optimizer='adam', target_tensors=[tf.placeholder(tf.int32, [None, 60])], metrics=[symbol_acc])
为什么编译看起来像这样:首先,模型还有一个层model.add(TimeDistributed(Dense(EVENTS_CNT, activation='softmax')))
,编译为model.compile(loss=custom_categorical_crossentropy, optimizer='rmsprop', metrics=[symbol_acc])
。但是这样的模型在检查目标时产生了错误" ValueError:Error:期望time_distributed_2具有3个维度,但是得到了具有形状的数组(2714,60)"。现在所有形状都适合。
但现在我有了新的问题(我的故事的关键时刻):公制symbol_acc
中的形状是dirrefent:
形状(symbol_acc):(?,60)(?,?,462)
因此true
数组的形状为(?, 60)
,预测为(?, ?, 462)
。 true
60个值中的每个值都是0到461之间的数字(表示事件的真实数量),predicted
中每个值60个是0的概率分布大小为462的向量至461(对于462个事件中的每一个)(对于462个事件中的每一个)。我想使true
具有与predicted
相同的形状:对于60个值中的每一个,使得大小为462的向量在事件编号位置上为1,在其他位置上为0。
所以我的问题:
K.gather(K.eye(462), tf.cast(number, tf.int32))
:该代码创建一个在number
位置有1的热门数组。但我不明白如何在不知道这个数组的情况下将它应用于数组。我是keras和NN的新手,因此我不确定所有步骤是否正确。如果您发现任何错误,请报告。
答案 0 :(得分:2)
正如我之前测试的那样,使用target_tensors
除非其形状与模型预测的形状相同,否则无法使用y_true
。
因此,不能违反这条一般规则:
您的输出数据必须与您的型号“ouptut”具有相同的形状
这使得y_pred
和from keras.utils import to_categorical
one_hot_X = to_categorical(X_train,462)
肯定具有相同的形状。
您需要的是使用to_categorical()将输出数据调整为模型的形状。
model.fit(X_train, one_hot_X,...)
通过这种方式,您只需正常训练您的模型,而无需在损失和准确性方面创建变通方法:
def batch_generator(batch_size):
while True: #keras generators must be infinite
#you may want to manually shuffle X_train here
for i in range(len(X_train)//batch_size): #make sure len is a multiple of batch_size
x = X_train[i*batch_size:(i+1)*batch_size]
y = to_categorical(x,462)
yield (x,y)
如果您遇到内存问题这样做,您可以考虑创建一个只转换每个批次的部分数据的生成器:
model.fit_generator(batch_generator(size),....)
训练:
K.argmax
现在我们已经更清楚地知道您正在做什么,您的准确性应该使用y_true
来获得准确的结果(而不是考虑462选项,而它应该是1,正确与否)
(我的回答是错误的,因为我忘了y_pred
是确切的,但是def symbol_acc(y_true, y_pred):
y_true = K.argmax(y_true) #this gets the class as an integer (comparable to X_train)
y_pred = K.argmax(y_pred) #transforming (any,60,462) into (any,60)
isEqual = K.cast(K.equal(y_true, y_pred), K.floatx())
return K.mean(isEqual)
是近似的。
{{1}}
只是一个小小的修正:
嵌入不会创造出一个热门的"表示,他们只是创建一个多特征表示。 (一个热点严格地说是向量中只有一个元素是一个的情况,但嵌入对任何元素中的任何值都是自由的)。