### Keras中的条件CNN模型

我正在尝试构建一个条件CNN模型。这个模型是这样的,

enter image description here

在我的模型的第一阶段,我将数据输入到模型1,然后,基于模型1的预测,我想训练模型为条件猫模型或条件狗模型,最后,从条件猫模型或条件狗模型中输出结果。我该如何实现这一点?

注意:我的努力是,

import kerasfrom keras.layers import *from keras.models import *from keras.utils import *img_rows,img_cols,number_of_class = 256,256,2input = Input(shape=(img_rows,img_cols,3))#----------- 主模型(模型1) ------------------------------------conv_01 = Convolution2D(64, 3, 3, activation='relu',name = 'conv_01') (input)conv_02 = Convolution2D(64, 3, 3, activation='relu',name = 'conv_02') (conv_01)skip_dog =  conv_02conv_03 = Convolution2D(64, 3, 3, activation='relu',name = 'conv_03') (conv_02)skip_cat =  conv_03conv_04 = Convolution2D(64, 3, 3, activation='relu',name = 'conv_04') (conv_03)flatten_main_model =  Flatten() (conv_04)Output_main_model = Dense(units = number_of_class , activation = 'softmax', name = "Output_layer")(flatten_main_model)#----------- 条件猫模型 ------------------------------------ conv_05 = Convolution2D(64, 3, 3, activation='relu',name = 'conv_05') (skip_cat)flatten_cat_model =  Flatten() (conv_05)Output_cat_model = Dense(units = number_of_class , activation = 'softmax', name = "Output_layer_cat")(flatten_cat_model)#----------- 条件狗模型 ------------------------------------ conv_06 = Convolution2D(64, 3, 3, activation='relu',name = 'conv_06') (skip_dog)flatten_dog_model =  Flatten() (conv_06)Output_dog_model = Dense(units = number_of_class , activation = 'softmax', name = "Output_layer_dog")(flatten_dog_model)#----------------------------- 我的三个独立模型 --------------------------------model_01 = Model(inputs = input , outputs = Output_main_model,name = 'model_main')model_02_1 = Model(inputs = input , outputs = Output_cat_model ,name = 'Conditional_cat_model')model_02_2 = Model(inputs = input , outputs = Output_dog_model ,name = 'Conditional_dog_model')

我如何根据这些条件合并这三个模型(model_01, model_02_1, model_02_2)?

**条件如下: **

  1. 将数据输入到模型model_01
  2. 根据model_01的结果,将数据输入到model_02_1或model_02_2
  3. 接下来,从model_02_1或model_02_2预测最终输出

回答:

神经网络中的条件问题

在神经网络中使用切换或条件(如if-then-else)的问题在于,条件在某些地方不是可微分的。因此,自动微分方法将无法直接工作,解决这个问题非常复杂。请查看这里以获取更多详情。

一个捷径是,你可以独立训练三个模型,然后在推理时使用条件控制流程从中推断。

#训练 - model1 = model.fit(all images, P(cat/dog))model2 = model.fit(all images, P(cat))model3 = model.fit(all images, P(dog))final prediction = argmax(model2, model3)#推理 - if model1.predict == Cat:     model2.predictelse:    model3.predict

但我认为你并不在寻找这个方法。我认为你希望将条件作为计算图的一部分来包含。

遗憾的是,根据我的了解,没有直接的方法在计算图中构建if-then条件。你看到的keras.switch允许你处理张量输出,但在训练过程中不能用于图层的层。这就是为什么你会看到它被用作损失函数的一部分,而不是在计算图中使用(会抛出输入错误)。

可能的解决方案 – 跳跃连接与软切换

然而,你可以尝试使用跳跃连接软切换构建类似的东西。

跳跃连接是从前一层到另一层的连接,允许你将信息传递给后续层。这在非常深的网络中很常见,原始数据的信息会逐渐丢失。例如,查看U-netResnet,它们在层之间使用跳跃连接将信息传递给未来的层。

enter image description here

接下来的问题是切换问题。你想在图中切换两个可能的路径。你可以使用一种软切换方法,这是我从这篇论文中获得的灵感。注意,为了切换两个词的分布(一个来自解码器,另一个来自输入),作者将它们分别乘以p(1-p)以获得累积分布。这是一种软切换,允许模型从解码器或输入本身中选择下一个预测的词。(当你希望你的聊天机器人能在响应中说出用户输入的词时,这很有帮助!)

enter image description here

了解了这两个概念后,让我们尝试直观地构建我们的架构。

  1. 首先,我们需要一个单输入多输出的图,因为我们在训练两个模型

  2. 我们的第一个模型是多类分类,分别预测猫和狗的个别概率。这将使用softmax激活和categorical_crossentropy损失进行训练。

  3. 接下来,我们取预测猫的概率的logit,并将其与卷积层3相乘。这可以通过Lambda层来完成。

  4. 同样,我们取狗的概率并将其与卷积层2相乘。这可以看作是以下情况 –

    • 如果我的第一个模型完美地预测出猫而不是狗,那么计算将是1*(Conv3)0*(Conv2)
    • 如果第一个模型完美地预测出狗而不是猫,那么计算将是0*(Conv3)1*(Conv2)
    • 你可以将这视为软切换遗忘门来自LSTM遗忘门是一个sigmoid(0到1)输出,它乘以单元状态以对其进行门控,允许LSTM忘记或记住之前的时间步。类似的概念在这里!
  5. 这些Conv3和Conv2现在可以进一步处理、扁平化、连接,并传递给另一个Dense层以进行最终预测。

这样,如果模型对狗或猫不确定,conv2和conv3的特征都会参与到第二个模型的预测中。这是你如何使用跳跃连接软切换启发的机制,为你的网络添加一些条件控制流程的方法。

查看我下面的计算图实现。

from tensorflow.keras import layers, Model, utilsimport numpy as npX = np.random.random((10,500,500,3))y = np.random.random((10,2))#Modelinp = layers.Input((500,500,3))x = layers.Conv2D(6, 3, name='conv1')(inp)x = layers.MaxPooling2D(3)(x)c2 = layers.Conv2D(9, 3, name='conv2')(x)c2 = layers.MaxPooling2D(3)(c2)c3 = layers.Conv2D(12, 3, name='conv3')(c2)c3 = layers.MaxPooling2D(3)(c3)x = layers.Conv2D(15, 3, name='conv4')(c3)x = layers.MaxPooling2D(3)(x)x = layers.Flatten()(x)out1 = layers.Dense(2, activation='softmax', name='first')(x)c = layers.Lambda(lambda x: x[:,:1])(out1)d = layers.Lambda(lambda x: x[:,1:])(out1)c = layers.Multiply()([c3, c])d = layers.Multiply()([c2, d])c = layers.Conv2D(15, 3, name='conv5')(c)c = layers.MaxPooling2D(3)(c)c = layers.Flatten()(c)d = layers.Conv2D(12, 3, name='conv6')(d)d = layers.MaxPooling2D(3)(d)d = layers.Conv2D(15, 3, name='conv7')(d)d = layers.MaxPooling2D(3)(d)d = layers.Flatten()(d)x = layers.concatenate([c,d])x = layers.Dense(32)(x)out2 = layers.Dense(2, activation='softmax',name='second')(x)model = Model(inp, [out1, out2])model.compile(optimizer='adam', loss='categorical_crossentropy', loss_weights=[0.5, 0.5])model.fit(X, [y, y], epochs=5)utils.plot_model(model, show_layer_names=False, show_shapes=True)
Epoch 1/51/1 [==============================] - 1s 1s/step - loss: 0.6819 - first_loss: 0.7424 - second_loss: 0.6214Epoch 2/51/1 [==============================] - 0s 423ms/step - loss: 0.6381 - first_loss: 0.6361 - second_loss: 0.6400Epoch 3/51/1 [==============================] - 0s 442ms/step - loss: 0.6137 - first_loss: 0.6126 - second_loss: 0.6147Epoch 4/51/1 [==============================] - 0s 434ms/step - loss: 0.6214 - first_loss: 0.6159 - second_loss: 0.6268Epoch 5/51/1 [==============================] - 0s 427ms/step - loss: 0.6248 - first_loss: 0.6184 - second_loss: 0.6311

enter image description here

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注