简体   繁体   English

具有多个张量输入的 Keras fit_generator

[英]Keras fit_generator with multiple tensor input

I have a Keras model with 4 tensor input and one array output.我有一个带有 4 个张量输入和一个数组输出的 Keras 模型。 It works properly using model.fit method它使用model.fit方法正常工作

model.fit([inputUM, inputMU, inputUU, inputMM],outputY , validation_data=([inputTestUM, inputTestMU, inputTestUU, inputTestMM],outputTest), batch_size=None, epochs=3, steps_per_epoch=200,validation_steps=200, callbacks=[checkpointer])

Now I change model.fit to model.fit_generator as现在我将model.fit更改为model.fit_generator

batchSize = 10
samples = int(outputY.shape[0]) #number of all samples
stepsPerEpoch = int(samples/batchSize)
model.fit_generator(dataGenerator(inputUM, inputMU, inputUU, inputMM, outputY, batchSize),
    steps_per_epoch=stepsPerEpoch,
    epochs=2,
    verbose=1,
    callbacks=[checkpointer],
    validation_data=dataGenerator(inputTestUM, inputTestMU, inputTestUU, inputTestMM, outputTest, batchSize),
    validation_steps=stepsPerEpoch))

In the dataGenerator each tensor is sliced as followingdataGenerator每个张量被切片如下

def dataGenerator(inputUM, inputMU, inputUU, inputMM, outputY, batchSize):       
    samples = int(outputY.shape[0]) #number of all samples
    batchNumber = int(samples/batchSize)  #number of batches
    counter=0

    while True:
        if counter > batchNumber: #restart counter at the end of each epoch
            counter = 0
        inUM = tf.slice(inputUM,[counter*batchSize,0,0],[batchSize,60,1])            
        inMU = tf.slice(inputMU,[counter*batchSize,0,0],[batchSize,60,1])            
        inUU = tf.slice(inputUU,[counter*batchSize,0,0],[batchSize,60,1])    
        inMM = tf.slice(inputMM,[counter*batchSize,0,0],[batchSize,60,1])            
        outY = outputY[counter*batchSize:(counter+1)*batchSize]

        counter += 1
        yield ([inUM, inMU, inUU, inMM], outY)

However I get this error:但是我收到这个错误:

File "C:\ProgramData\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 705, in runfile
execfile(filename, namespace)
File "C:\ProgramData\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 102, in execfile
exec(compile(f.read(), filename, 'exec'), namespace)
File "mycode.py", line 529, in <module>
main(data)
File "mycode.py", line 236, in main
initial_epoch=0)
File "C:\ProgramData\Anaconda3\lib\site-packages\keras\legacy\interfaces.py", line 91, in wrapper
return func(*args, **kwargs)
File "C:\ProgramData\Anaconda3\lib\site-packages\keras\engine\training.py", line 1418, in fit_generator
initial_epoch=initial_epoch)
File "C:\ProgramData\Anaconda3\lib\site-packages\keras\engine\training_generator.py", line 223, in fit_generator
callbacks.on_batch_end(batch_index, batch_logs)
File "C:\ProgramData\Anaconda3\lib\site-packages\keras\callbacks.py", line 115, in on_batch_end
callback.on_batch_end(batch, logs)
File "C:\ProgramData\Anaconda3\lib\site-packages\keras\callbacks.py", line 238, in on_batch_end
self.totals[k] = v * batch_size
File "C:\ProgramData\Anaconda3\lib\site-packages\tensorflow\python\framework\tensor_shape.py", line 410, in __rmul__
return self * other
TypeError: unsupported operand type(s) for *: 'Dimension' and 'float'

I know it needs some integer variable, however it gets other type data.我知道它需要一些整数变量,但是它会获取其他类型的数据。 I can't understand which parameter type is wrong.我无法理解哪个参数类型是错误的。 I cast all1 variables like stepsPerEpoch and samples , to integer.我将所有1个变量(如stepsPerEpochsamples )转换为整数。 Also it seems the generator works properly, in debug mode it returns [<tf.Tensor 'Slice_48:0' shape=(100, 60, 1) dtype=float32>, <tf.Tensor 'Slice_49:0' shape=(100, 60, 1) dtype=float32>, <tf.Tensor 'Slice_50:0' shape=(100, 60, 1) dtype=float32>, <tf.Tensor 'Slice_51:0' shape=(100, 60, 1) dtype=float32>] as input and array([4., 5., 4., ..., 4., 4., 5.]) as output.此外,生成器似乎工作正常,在调试模式下它返回[<tf.Tensor 'Slice_48:0' shape=(100, 60, 1) dtype=float32>, <tf.Tensor 'Slice_49:0' shape=(100, 60, 1) dtype=float32>, <tf.Tensor 'Slice_50:0' shape=(100, 60, 1) dtype=float32>, <tf.Tensor 'Slice_51:0' shape=(100, 60, 1) dtype=float32>]作为输入和array([4., 5., 4., ..., 4., 4., 5.])作为输出。

In model definition, you could use name parameter to give the name of each layer.在模型定义中,您可以使用name参数来给出每个层的名称。 For example:例如:

x1in = Input(shape = x1[0].shape, name='in1')
x2in = Input(shape = x2[0].shape, name='in2')

In your generator, you can yield a dict to fit the data:在您的生成器中,您可以生成一个字典来拟合数据:

yield {'in1' : in1, 'in2' : in2}, out

Finally, just fit the generator as usual:最后,像往常一样安装生成器:

model.fit_generator(datagen, epochs=300, steps_per_epoch=int(data_size/batch_size))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM