我正在尝试使用bucketing在keras中创建一个自动编码器,其中输入和输出具有不同的时间步长。
./directory
|
+-- subdirectory1/
| |
| + fileA.md
|
+-- subdirectory2/
|
+ fileA.md
+ ...
对于输入,没有问题,因为只要整个批次具有相同的长度,网络就可以接受不同长度的输入。但问题是输出大小是由RepeatVector长度决定的,并且没有简单的方法来改变它。
这样的问题有解决方案吗?
答案 0 :(得分:0)
如果您的意思是"输入长度可变的"和"输出长度与输入相同",你可以这样做:
警告:此解决方案必须适用于批量大小= 1
您将需要创建一个外部循环并将每个样本作为具有精确长度
的numpy数组传递 您不能在此解决方案中使用屏蔽,正确的输出取决于输入的正确长度
这是使用Keras + Tensorflow的工作代码:
进口:
from keras.layers import *
from keras.models import Model
import numpy as np
import keras.backend as K
from keras.utils.np_utils import to_categorical
要在Lambda图层中使用的自定义函数:
#this function gets the length from the original input
#and stores it in the final output of the encoder
def storeLength(x):
inputTensor = x[0]
storeInto = x[1] #the final output
length = K.shape(inputTensor)[1]
length = K.cast(length,K.floatx())
length = K.reshape(length,(1,1))
#will put length as the first element in the final output
return K.concatenate([length,storeInto])
#this function expands the length of the input in the decoder
def expandLength(x):
#lenght is the first element in the encoded input
length = K.cast(x[0,0],'int32') #or int64 if necessary
#the remaining elements are the actual data to be decoded
data = x[:,1:]
#a tensor with shape (length,)
length = K.ones_like(K.arange(0,length))
#make both length tensor and data tensor 3D and with paired dimensions
length = K.cast(K.reshape(length,(1,-1,1)),K.floatx())
data = K.reshape(data,(1,1,-1))
#this automatically repeats the elements based on the paired shapes
return data*length
创建模型:
我假设输出等于输入,但由于您使用了嵌入,我制作了#34; num_classes"等于单词的数量。
对于此解决方案,我们使用分支,因此我必须使用功能API Model
。以后会更好,因为您需要使用autoencoder.train_on_batch
进行训练,然后只使用encoder.predict()
进行编码,或者只使用decoder.predict()
进行解码。
vocab_size = 100
embedding_size = 7
num_class=vocab_size
hidden_size = 3
#encoder
inputs = Input(batch_shape = (1,None))
outputs = Embedding(vocab_size, embedding_size)(inputs)
outputs = LSTM(units=hidden_size, return_sequences=False)(outputs)
outputs = Lambda(storeLength)([inputs,outputs])
encoder = Model(inputs,outputs)
#decoder
inputs = Input(batch_shape=(1,hidden_size+1))
outputs = Lambda(expandLength)(inputs)
outputs = LSTM(units=hidden_size, return_sequences=True)(outputs)
outputs = TimeDistributed(Dense(num_class, activation='softmax'))(outputs)
decoder = Model(inputs,outputs)
#autoencoder
inputs = Input(batch_shape=(1,None))
outputs = encoder(inputs)
outputs = decoder(outputs)
autoencoder = Model(inputs,outputs)
#see each model's shapes
encoder.summary()
decoder.summary()
autoencoder.summary()
只是假数据和应该用于培训的方法的示例:
inputData = []
outputData = []
for i in range(7,10):
inp = np.arange(i).reshape((1,i))
inputData.append(inp)
outputData.append(to_categorical(inp,num_class))
autoencoder.compile(loss='mse',optimizer='adam')
for epoch in range(1):
for inputSample,outputSample in zip(inputData,outputData):
print(inputSample.shape,outputSample.shape)
autoencoder.train_on_batch(inputSample,outputSample)
for inputSample in inputData:
print(autoencoder.predict(inputSample).shape)