Keras实例:多输入模型

一般情况下,利用Keras建立模型,会使用线性模型(Sequential),但是在一些特殊情况下,我们或许会有多个input,这样的话,我们就不会使用线性模型,而使用Keras的Model。

from keras.models import Sequential # 线性模型,我们这次不使用这种
from keras.models import Model  # Model可以用来处理多输入和多输出

假设我们需要训练这样一个简单的模型:

y = x1 + x2

其中输入为x1和x2,输出为y。我们使用一个for循环生成我们需要的数据,生成结束后我们对数据进行打乱处理,因为默认的方法在分离训练集和验证集的时候并不会打乱顺序,如果我们仅仅在数据的前80%进行训练,那后20%模型是无法学习到任何东西的。

def load_data(data_size = 100):
	x1 = np.zeros(data_size)
	x2 = np.zeros(data_size)
	for i in range(data_size):
		x1[i] = i
		x2[i] = i
	y = x1 + x2

	index = np.arange(data_size)
	np.random.shuffle(index)
	x1 = x1[index] #使用相同的index,shuffle之后的关系依然是对应的
	x2 = x2[index]
	y = y[index]

	return x1,x2,y

接下来我们构建一个简单的模型。简单的使用几层全连层就完成了架构。对Input进行命名不是必须的,但是会比较直观。和线性模型不同的是,我们必须定义每一层的输入和输出,这样才能找到每一层的对应关系。concatenate层链接了x1和x2的输出层,具有合并的作用。最后在定义模型输入的时候,使用数组作为模型的多个输入。

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

	x1out = Dense(256, activation='relu')(x1in)
	x1out = Dense(256, activation='relu')(x1out)

	x2out = Dense(256, activation='relu')(x2in)
	x2out = Dense(256, activation='relu')(x2out)

	out = concatenate([x1out, x2out]) #链接层
	out = Dense(256, activation='relu')(out)
	out = Dense(1)(out)

	model = Model(inputs=[x1in,x2in], outputs=out) #使用数组作为inputs
	model.compile(optimizer='rmsprop', loss='mse', metrics=['mae'])
	return model

定义完模型之后就可以开始训练了。我们同时定义了一个学习率改变器,每100个epoch会下降一下学习率,具体的运作原理不在本文讨论之内,目的只是让这个模型跑的效果更好。

def step_decay(epoch):
	initial_lrate = 0.001
	drop = 0.1
	epochs_drop = 100.0
	lrate = initial_lrate * math.pow(drop, math.floor((1+epoch)/epochs_drop))
	return lrate

def train_model():
	x1,x2,y = load_data()
	x1 = x1.reshape(x1.shape[0], -1) #把数据reshape成模型可以读取的shape
	x2 = x2.reshape(x2.shape[0], -1)
	model = load_model(x1, x2)

	model.summary()
    reduce_lr = LearningRateScheduler(step_decay) #改变学习率
	model.fit([x1,x2], y, epochs=1000, validation_split=0.2, batch_size=10, callbacks=[reduce_lr])
	model.save('linear.model')

def main():
	train_model()

来看一下模型的结构:

__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
in1 (InputLayer)                (None, 1)            0                                            
__________________________________________________________________________________________________
in2 (InputLayer)                (None, 1)            0                                            
__________________________________________________________________________________________________
dense_1 (Dense)                 (None, 256)          512         in1[0][0]                        
__________________________________________________________________________________________________
dense_3 (Dense)                 (None, 256)          512         in2[0][0]                        
__________________________________________________________________________________________________
dense_2 (Dense)                 (None, 256)          65792       dense_1[0][0]                    
__________________________________________________________________________________________________
dense_4 (Dense)                 (None, 256)          65792       dense_3[0][0]                    
__________________________________________________________________________________________________
concatenate_1 (Concatenate)     (None, 512)          0           dense_2[0][0]                    
                                                                 dense_4[0][0]                    
__________________________________________________________________________________________________
dense_5 (Dense)                 (None, 256)          131328      concatenate_1[0][0]              
__________________________________________________________________________________________________
dense_6 (Dense)                 (None, 1)            257         dense_5[0][0]                    
==================================================================================================
Total params: 264,193
Trainable params: 264,193
Non-trainable params: 0
__________________________________________________________________________________________________

再来看一下训练的结果:

Epoch 1000/1000
80/80 [==============================] - 0s 308us/step - loss: 4.2059e-06 - mae: 0.0017 - val_loss: 4.2603e-06 - val_mae: 0.0018

发现结果非常准确,验证集的loss也非常低。

以上就是Keras多输入模型的例子了,同样Keras也支持多输出,一样举一反三。

你可能感兴趣的:(神经网络,深度学习)