建立一个keras模型 [英] Constructing a keras model

查看:111
本文介绍了建立一个keras模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不明白这段代码中发生了什么:

I don't understand what's happening in this code:

def construct_model(use_imagenet=True):
    # line 1: how do we keep all layers of this model ?
    model = keras.applications.InceptionV3(include_top=False, input_shape=(IMG_SIZE, IMG_SIZE, 3),
                                          weights='imagenet' if use_imagenet else None) # line 1: how do we keep all layers of this model ?

    new_output = keras.layers.GlobalAveragePooling2D()(model.output)

    new_output = keras.layers.Dense(N_CLASSES, activation='softmax')(new_output)
    model = keras.engine.training.Model(model.inputs, new_output)
    return model

具体地说,我的困惑是,当我们调用最后一个构造函数时

Specifically, my confusion is, when we call the last constructor

model = keras.engine.training.Model(model.inputs, new_output)

我们指定了输入层和输出层,但是怎么知道我们希望所有其他层都保留呢?

we specify input layer and output layer, but how does it know we want all the other layers to stay?

换句话说,我们将new_output层附加到第1行中加载的预训练模型上,即new_output层,然后在最终的构造函数(最后一行)中,我们只创建并返回一个带有指定的输入和输出层,但是它如何知道我们还希望在它们之间还有哪些其他层?

In other words, we append the new_output layer to the pre-trained model we load in line 1, that is the new_output layer, and then in the final constructor (final line), we just create and return a model with a specified input and output layers, but how does it know what other layers we want in between?

侧面问题1):keras.engine.training.Model和keras.models.Model有什么区别?

Side question 1): What is the difference between keras.engine.training.Model and keras.models.Model?

问题2):当我们进行new_layer = keras.layers.Dense(...)(prev_layer)时,会发生什么? ()操作会返回新层吗?它到底是做什么的?

Side question 2): What exactly happens when we do new_layer = keras.layers.Dense(...)(prev_layer)? Does the () operation return new layer, what does it do exactly?

推荐答案

此模型是使用基本上,它是这样的(也许如果在阅读本文之前进入下面的附带问题2",它可能会变得更加清晰):

Basically it works like this (perhaps if you go to the "side question 2" below before reading this it may get clearer):

  • 您有一个输入张量(您也可以将其视为输入数据")
  • 您创建(或重复使用)层
  • 您将输入张量传递给一个层(您用输入调用"一个层)
  • 您得到一个输出张量
  • You have an input tensor (you can see it as "input data" too)
  • You create (or reuse) a layer
  • You pass the input tensor to a layer (you "call" a layer with an input)
  • You get an output tensor

在创建整个图形之前,您将继续使用这些张量.

You keep working with these tensors until you have created the entire graph.

但是,这还没有创建一个模型". (您可以训练和使用其他东西).
您所拥有的只是一张图,告诉您哪些张量会到达何处.

But this hasn't created a "model" yet. (One you can train and use other things).
All you have is a graph telling which tensors go where.

要创建模型,请定义它的开始终点.

To create a model, you define it's start end end points.

在示例中.

  • 他们采用现有模型:model = keras.applications.InceptionV3(...)
  • 他们想扩展此模型,以便获得其输出张量:model.output
  • 他们将这个张量传递为GlobalAveragePooling2D层的输入
  • 他们获得该层的输出张量为new_output
  • 他们将此作为输入传递到另一个层:Dense(N_CLASSES, ....)
  • 并以new_output的形式获取其输出(此var被替换,因为他们对保持其旧值不感兴趣...)
  • They take an existing model: model = keras.applications.InceptionV3(...)
  • They want to expand this model, so they get its output tensor: model.output
  • They pass this tensor as the input of a GlobalAveragePooling2D layer
  • They get this layer's output tensor as new_output
  • They pass this as input to yet another layer: Dense(N_CLASSES, ....)
  • And get its output as new_output (this var was replaced as they are not interested in keeping its old value...)

但是,由于它可以与功能性API一起使用,因此我们还没有模型,只有图.为了创建模型,我们使用Model定义输入张量和输出张量:

But, as it works with the functional API, we don't have a model yet, only a graph. In order to create a model, we use Model defining the input tensor and the output tensor:

new_model = Model(old_model.inputs, new_output)    

现在您有了模型.
如果像我一样(new_model)在另一个变量中使用它,则旧模型仍将存在于model中.而且这些模型共享相同的层,从而每当您训练其中一个时,另一个也会被更新.

Now you have your model.
If you use it in another var, as I did (new_model), the old model will still exist in model. And these models are sharing the same layers, in a way that whenever you train one of them, the other gets updated as well.

当您这样做:

outputTensor = SomeLayer(...)(inputTensor)    

您在输入和输出之间建立了连接. (Keras将使用内部张量流机制并将这些张量和节点添加到图中).没有输入就无法存在输出张量.整个InceptionV3模型都是从头到尾连接的.它的输入张量遍历所有层以产生输出张量.数据遵循的只有一种可能的方式,而图形就是这种方式.

you have a connection between the input and output. (Keras will use the inner tensorflow mechanism and add these tensors and nodes to the graph). The output tensor cannot exist without the input. The entire InceptionV3 model is connected from start to end. Its input tensor goes through all the layers to yield an ouptut tensor. There is only one possible way for the data to follow, and the graph is the way.

当您获得此模型的输出并用于其他输出时,所有新的输出都将与此连接,从而与模型的第一个输入连接.

When you get the output of this model and use it to get further outputs, all your new outputs are connected to this, and thus to the first input of the model.

添加到张量中的属性_keras_history可能与其跟踪图形的方式密切相关.

Probably the attribute _keras_history that is added to the tensors is closely related to how it tracks the graph.

因此,进行Model(old_model.inputs, new_output)自然会遵循唯一可能的方法:图形.

So, doing Model(old_model.inputs, new_output) will naturally follow the only way possible: the graph.

如果尝试使用未连接的张量执行此操作,则会出现错误.

If you try doing this with tensors that are not connected, you will get an error.

首选从"keras.models"导入.基本上,该模块将从其他模块导入:

Prefer to import from "keras.models". Basically, this module will import from the other module:

请注意,文件keras/models.pykeras.engine.training导入Model.所以,这是同一回事.

Notice that the file keras/models.py imports Model from keras.engine.training. So, it's the same thing.

不是new_layer = keras.layers.Dense(...)(prev_layer).

output_tensor = keras.layers.Dense(...)(input_tensor).

您正在同一行中做两件事:

You're doing two things in the same line:

  • 使用keras.layers.Dense(...)
  • 创建图层
  • 使用输入张量调用图层以获取输出张量
  • Creating a layer - with keras.layers.Dense(...)
  • Calling the layer with an input tensor to get an output tensor

如果您想将同一图层用于不同的输入:

If you wanted to use the same layer with different inputs:

denseLayer = keras.layers.Dense(...) #creating a layer

output1 = denseLayer(input1)  #calling a layer with an input and getting an output
output2 = denseLayer(input2)  #calling the same layer on another input
output3 = denseLayer(input3)  #again   

奖金-创建与顺序模型相同的功能模型

如果您创建此顺序模型:

Bonus - Creating a functional model that is equal to a sequential model

If you create this sequential model:

model = Sequential()
model.add(Layer1(...., input_shape=some_shape))   
model.add(Layer2(...))
model.add(Layer3(...))

您所做的与以下操作完全相同:

You're doing exactly the same as:

inputTensor = Input(some_shape)
outputTensor = Layer1(...)(inputTensor)
outputTensor = Layer2(...)(outputTensor)    
outputTensor = Layer3(...)(outputTensor)

model = Model(inputTensor,outputTensor)

有什么区别?

无论如何,功能性API模型都是完全免费的.您可以创建分支:

Well, functional API models are totally free to be build anyway you want. You can create branches:

out1 = Layer1(..)(inputTensor)    
out2 = Layer2(..)(inputTensor)

您可以加入张量:

joinedOut = Concatenate()([out1,out2])   

以此,您可以使用各种奇特的东西,分支,门,串联,添加等来创建任何内容,而这是顺序模型无法做到的.

With this, you can create anything you want with all kinds of fancy stuff, branches, gates, concatenations, additions, etc., which you can't do with a sequential model.

实际上,Sequential模型也是Model,但是创建时是为了在没有分支的模型中快速使用.

In fact, a Sequential model is also a Model, but created for a quick use in models without branches.

这篇关于建立一个keras模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆