use*_*181 5 deep-learning keras
我正在尝试在 keras 中创建一个自动编码器,其中输入和输出具有不同的时间步长。
model = Sequential()
#encoder
model.add(Embedding(vocab_size, embedding_size, mask_zero=True))
model.add(LSTM(units=hidden_size, return_sequences=False))
#decoder
model.add(RepeatVector(max_out_length))
model.add(LSTM(units=hidden_size, return_sequences=True))
model.add(TimeDistributed(Dense(num_class, activation='softmax')))
Run Code Online (Sandbox Code Playgroud)
对于输入来说,没有问题,因为只要整个批次具有相同的长度,网络就可以接受不同长度的输入。然而,问题在于输出大小是由 RepeatVector 长度决定的,并且没有简单的方法来改变它。
对于这样的问题有解决办法吗?
如果您的意思是“可变长度的输入”和“与输入长度相同的输出”,您可以这样做:
警告:此解决方案必须使用批量大小 = 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
Run Code Online (Sandbox Code Playgroud)
在 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
Run Code Online (Sandbox Code Playgroud)
创建模型:
我假设输出等于输入,但由于您使用的是嵌入,所以我将“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()
Run Code Online (Sandbox Code Playgroud)
只是一个带有假数据的示例以及用于训练的方法:
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)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2893 次 |
最近记录: |