赞
踩
def cnn(input_shape,classes):
model = Sequential()
model.add(Conv2D(input_shape=input_shape,filters=25,kernel_size=(3,3),padding='same',activation='relu'))
model.add(MaxPool2D())
model.add(Dropout(rate=0.3,name='student_feature1'))
model.add(Flatten())
model.add(Dense(32,activation='relu',name='student_feature2'))
model.add((Dense(classes,activation='softmax')))
return model
model = cnn(input_shape=(28,28,1),classes=10)
这是一个非常简单的 CNN 网络,里面包含了:
那么,如果我们需要构建一个模型,里面同时集成多个这样的 CNN 模型,该怎么写呢?、
在如下的实例中,我写了一个简单的多模型集成的神经网络,来实现自己想要的小功能
from keras.layers import Input,MaxPooling2D,Lambda,Dropout,Flatten,Dense,Activation from keras.models import Model,Sequential def cnn(input_shape,classes): model = Sequential() model.add(Conv2D(input_shape=input_shape,filters=25,kernel_size=(3,3),padding='same',activation='relu')) model.add(MaxPooling2D()) model.add(Dropout(rate=0.3,name='student_feature1')) model.add(Flatten()) model.add(Dense(32,activation='relu',name='student_feature2')) model.add((Dense(classes,activation='softmax'))) return model cnn1 = cnn((28,28,1),10) cnn2 = cnn((28,28,1),10) cnn3 = cnn((28,28,1),10) def mean(data): return (data[0] + data[1] + data[2])/3 def multi_model_net(): inputs = Input((28,28,1)) result1 = cnn1(inputs) result2 = cnn2(inputs) result3 = cnn3(inputs) outputs = Lambda(mean,output_shape=(10,))([result1,result2,result3]) model = Model(inputs,outputs) return model mod = multi_model_net() print(mod.summary())
首先定义 CNN 网络
然后创建 3 个 CNN 网络
第一个需要注意的点:使用 cnn1(inputs) 这种形式,是因为当你创建了一个 CNN 网络之后,这个网络可以被用作函数一样,把 inputs 输进去,输出来一组预测的概率值。
第二个需要注意的点:使用 Lambda 来进行最终的融合操作,在神经网络的搭建过程中,所有的动作都必须在 layer 里面完成,比如你要对 layer 进行加和或者是一些运算,只要是不产生额外的参数,所有的额外操作都使用 Lambda 层来完成。就比如我们这段代码中,只是对 3 个子网络的结果进行加和求平均,并没有产生额外的训练参数。如果产生了额外训练的参数,这个时候需要额外自定义一个 layer 来完成这个工作。
第三个需要注意的点:如果要创建的神经网络内部比较复杂,有多个分支,组合,处理的步骤,要使用 keras.models.Model
来建立模型,而不是简单的使用 Sequential 模型。这里也是为了给大家一个对比。在这个网络中有 3 个分支,最后又融合,使用 Sequential 模型是无法完成这个工作的。
第四个需要注意的点:建立模型,输入和输出之间一定要贯通,不贯通的部分不会出现在模型里面。我们用下面的例子来解释这句话。
def mean(data): return (data[0] + data[1])/2 def multi_model_net(): inputs = Input((28,28,1)) result1 = cnn1(inputs) result2 = cnn2(inputs) result3 = cnn3(inputs) outputs = Lambda(mean,output_shape=(10,))([result1,result2]) model = Model(inputs,outputs) return model mod = multi_model_net() print(mod.summary())
下面我们再通过一个例子,将第 3 个模型来贯通到输出层,使它可以重新作用于模型内部。
def mean(data): return (data[0] + data[1])/2 def multi_model_net(): inputs = Input((28,28,1)) result1 = cnn1(inputs) result2 = cnn2(inputs) result3 = cnn3(inputs) outputs = Lambda(mean,output_shape=(10,))([result1,result2]) model = Model(inputs,[outputs,result3]) return model mod = multi_model_net() print(mod.summary())
(28,28,1)
,output1
--> lambda 的输出,维度是 (None,10)
;output2
--> cnn3 的输出,维度是 (None,10)
还是先来看看单个模型的神经网络的训练
cnn1.compile(loss=keras.losses.categorical_crossentropy,optimizer=keras.optimizers.Adam(0.001),metrics=['accuracy'])
history = cnn1.fit(x_train,y_train,batch_size=64,epochs=10,shuffle=True)
我们看这段代码,应该知道为什么在 fit
里面是 x_train
和 y_train
。
x_train
输入到模型里面,根据模型中的各种操作和步骤,最后会在输出层产生一个结果,这个结果在 10
分类任务中维度是 (10,)
。
因此,我们为了对模型进行训练,我们要使用 y_train
作为 groundtruth
来不断地引导神经网络输出的结果。所以我们得到了一个 结论:模型有多少个输出,我们就应该给在 fit
中设置几个 groundtruth
,
例如我们在 第二部分 提到的例子,我们拿过来看一下:
def mean(data): return (data[0] + data[1])/2 def multi_model_net(): inputs = Input((28,28,1)) result1 = cnn1(inputs) result2 = cnn2(inputs) result3 = cnn3(inputs) outputs = Lambda(mean,output_shape=(10,))([result1,result2]) model = Model(inputs,[outputs,result3]) return model mod = multi_model_net() print(mod.summary())
我们整个模型的输出有两个部分构成:
所以显而易见,我们在训练这个模型的时候,应该设置 两个 groundtruth 来引导训练。
mod.compile(loss=keras.losses.categorical_crossentropy,optimizer=keras.optimizers.Adam(0.001),metrics=['accuracy'])
history = mod.fit(x_train,[y_train,y_train],batch_size=64,epochs=10,shuffle=True)
当然,如果你使用了更复杂的模型集成方法,例如你的网络中的 3 个子网络每个用的都是不同的数据集,你最后的 groundtruth
就要根据自己的需要来设定,而不是简单的都用 y_train
。
对于 多输入的模型 ,只需要在训练的时候把输入的训练集写在方括号里,比如我随便制造一个 两个输入,一个输出的模型:
def mean(data): return (data[0] + data[1] + data[2])/3 def multi_model_net(): input1 = Input((28,28,1)) input2 = Input((28,28,1)) result1 = cnn1(input1) result2 = cnn2(input1) result3 = cnn3(input2) outputs = Lambda(mean,output_shape=(10,))([result1,result2,result3]) model = Model([input1,input2],outputs) return model mod = multi_model_net() print(mod.summary())
在训练的时候你就可以随机应变:
mod.compile(loss=keras.losses.categorical_crossentropy,optimizer=keras.optimizers.Adam(0.001),metrics=['accuracy'])
history = mod.fit([x_train,x_train],y_train,batch_size=64,epochs=10,shuffle=True)
相信聪明的你对于 多个输入和多个输出 的模型,也会训练了
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。