杭州精高端网站建设,商城模板建站价格,建造师网,长沙哪个平台做网站好紧随上一篇#xff0c;我们已经设置好了一些参数#xff0c;下面我们来定义模型#xff1a;
代码如下#xff1a;
import typing
import tensorflow as tf
import theone
def get_vgg19_model(layers):初始化并创建vgg19模型:param layers::return:我们已经设置好了一些参数下面我们来定义模型
代码如下
import typing
import tensorflow as tf
import theone
def get_vgg19_model(layers):初始化并创建vgg19模型:param layers::return:#加载imagenet上预训练的vgg19#include_topFalse表示不包含模块的顶层也就是全链接层#weightsimagenet表示使用在Imagenet数据集上的预训练权重加载模型vggtf.keras.applications.VGG19(include_topFalse,weightsimagenet)#提取需要被用到的vgg层的outputoutputs[vgg.get_layer(layer).output for layer in layers]#使用outputs创建新的模型modeltf.keras.Model([vgg.input, ],outputs)#锁死参数不进行训练model.trainableFalsereturn model
class NeuralStyleTransferModel(tf.keras.Model):def __init__(self, content_layers:typing.Dict[str,float] theone.CONTENT_LAYERS,style_layers:typing.Dict[str,float] theone.STYLE_LAYERS):super(NeuralStyleTransferModel,self).__init__()#内容特征层字典DICT[层名加权系数]self.content_layerscontent_layers#风格特征层self.style_layersstyle_layers#提取需要用到的所有vgg层layerslist(self.content_layers.keys())list(self.style_layers.keys())#创建layer_name到output索引的映射self.outputs_index_mapdict(zip(layers,range(len(layers))))#创建并初始化vgg网络self.vggget_vgg19_model(layers)def call(self,inputs,trainingNone,maskNone):前向传播:returntyping.Dict[str,typing.List[outputs,加权系数]outputsself.vgg(inputs)#分离内容特征层和风格特征层的输出方便后续计算typing.List[outputs,加权系数]content_outputs[]for layer,factor in self.content_layers.items():content_outputs.append((outputs[self.outputs_index_map[layer]][0],factor))style_outputs[]for layer,factor in self.style_layers.items():style_outputs.append((outputs[self.outputs_index_map[layer]][0],factor))#以字典形式返回输出return {content:content_outputs,style:style_outputs} 下面看分析
先来看这段代码
def get_vgg19_model(layers):初始化并创建vgg19模型:param layers::return:#加载imagenet上预训练的vgg19#include_topFalse表示不包含模块的顶层也就是全链接层#weightsimagenet表示使用在Imagenet数据集上的预训练权重加载模型vggtf.keras.applications.VGG19(include_topFalse,weightsimagenet)#提取需要被用到的vgg层的outputoutputs[vgg.get_layer(layer).output for layer in layers]#使用outputs创建新的模型modeltf.keras.Model([vgg.input, ],outputs)#锁死参数不进行训练model.trainableFalsereturn model
vggtf.keras.applications.VGG19(include_topFalse,weightsimagenet) 调用VGG19模型其中include_topFalse表示不包含模块的顶层也就是全连接层。只包含卷积层。weightimagenet表示使用在imagenet数据集上的训练权重加载模型。
具体来说当我们使用VGG19ResNet50InceptionV3等经典的神经网络模型时这些模型通常在大规模图像数据集ImageNet上进行了预训练在预训练过程中模型通过学习大量的图像样本来提取特征并对这些样本进行分类。当我们自己在任务中使用这些预训练模型时我们可以选择是否加载预训练权重。如果我们将weightsimagenet设置为true。在实例化模型的时候TensorFlow会自动下载并加载在ImageNet数据集上预训练的权重。这样做的好处是模型会具有较好的初始特征提取能力通常能够提高模型的性能和收敛速度。
outputs[vgg.get_layer(layer).output for layer in layers]
这段代码创建了一个列表outputs其中包含了VGG模型中指定层的输出。 这段代码使用列表推导式遍历layers中每个层名layer并为每个层名获取其对应的输出张量然后将这些输出张量存储在列表‘outputs’中。
总体而言就是根据传入的层列表layers提取需要的VGG层输出加载预训练模型的权重。
modeltf.keras.Model([vgg.input, ],outputs)
tf.keras.Model是Keras中用于创建模型的类。 [vgg.input, ]这个列表包含了模型的输入张量其中vgg.input表示了VGG的输入张量。 在Keras中模型的输入层可以通过模型的.input属性来访问。 为什么要将其打包成一个列表呢 tf.keras.Model类构造函数需要接受输入参数的列表。当然只有一个元素将其写成[vgg.input]其实也可以。 outputs是一个列表包含了VGG模型中指定层的输出张量这些张量将作为新模型的输出。
总的而言就是使用tf.keras.Model类创建了一个新的模型指定了模型的输入和输出。
model.trainableFalse是指定模型的参数不可训练即在模型进行反向传播算法优化参数时这些参数不会被更新意味着模型的参数将不会参与训练过程他们的值将会保持不变这通常用于在迁移学习或特定场景下固定住某些层的参数只训练模型的部分参数或者在指定的任务中只使用模型的特征提取能力而不更新模型的参数。显然使用的参数是预训练模型上的具有很高的可靠性训练反而会使可靠性降低。
接下来我们看
class NeuralStyleTransferModel(tf.keras.Model):def __init__(self, content_layers:typing.Dict[str,float] theone.CONTENT_LAYERS,style_layers:typing.Dict[str,float] theone.STYLE_LAYERS):super(NeuralStyleTransferModel,self).__init__()#内容特征层字典DICT[层名加权系数]self.content_layerscontent_layers#风格特征层self.style_layersstyle_layers#提取需要用到的所有vgg层layerslist(self.content_layers.keys())list(self.style_layers.keys())#创建layer_name到output索引的映射self.outputs_index_mapdict(zip(layers,range(len(layers))))#创建并初始化vgg网络self.vggget_vgg19_model(layers)
我们定义了一个名为NeuralStyleTransferModel的自定义神经风格迁移模型类继承自tf.keras.Model类。表示这个类是一个Keras模型。
def __init__(self, content_layers:typing.Dict[str,float] theone.CONTENT_LAYERS, style_layers:typing.Dict[str,float] theone.STYLE_LAYERS): super(NeuralStyleTransferModel,self).__init__()
这是一个构造函数在创建类的实例时会自动调用。 content_layers和style_layers是构造函数的参数它们指定了内容特征层和风格特征层以及它们的加权系数。格式就是字典类型使用content_layers:typing.Dict[str,float]无非就是一个注释功能。 当然我们可以选择个人认为这种方法更简洁源码更能凸显参数类型。 def __init__(self, content_layerstheone.CONTENT_LAYERS, style_layerstheone.STYLE_LAYERS): super(NeuralStyleTransferModel, self).__init__() self.content_layerscontent_layers为什么在构造函数中已经初始化content之后还要再初始化
在构造函数中通过参数传入的content_layers和style_layers变量仅在构造函数内部可见并且只在构造函数执行过程中有效为了在整个类中都能访问这些变量我们需要将它们保存为类的实例变量以便在类的其他方法中也能使用它们。
layers list(self.content_layers.keys()) list(self.style_layers.keys())
这段代码将内容特征层和风格特征层的层名合并为一个列表layers得到一个包含所有层名的列表。
self.outputs_index_map dict(zip(layers, range(len(layers))))
创建一个字典outputs_index_map用于将层名与它们在VGG模型输出列表中的索引位置相对应。 range(len(layers))生成一个从0到len(layers)-1的整数序列其长度与列表layers的长度相同。 zip(layers,range(len(layers))):将两个列表中的元素逐一配对形成一个可迭代的元组序列每个元组中包含了layers中的一个元素和对应的range(len(layers))中的元素。
self.vgg get_vgg19_model(layers)
这段代码调用一个函数get_vgg19_model()并传入层列表layers作为参数。 这个函数的作用是创建并初始化一个VGG19的网络模型其中包含了指定层名的部分用于提取图像的特征。 用于后面提取图像的特征。 最后一个模块写完收工
def call(self,inputs,trainingNone,maskNone):前向传播:returntyping.Dict[str,typing.List[outputs,加权系数]outputsself.vgg(inputs)#分离内容特征层和风格特征层的输出方便后续计算typing.List[outputs,加权系数]content_outputs[]for layer,factor in self.content_layers.items():content_outputs.append((outputs[self.outputs_index_map[layer]][0],factor))style_outputs[]for layer,factor in self.style_layers.items():style_outputs.append((outputs[self.outputs_index_map[layer]][0],factor))#以字典形式返回输出return {content:content_outputs,style:style_outputs}
这个模型时前向传播模型
def call(self,inputs,trainingNone,maskNone):
input是模型输入数据。training表示模型是否处于训练模式如果为True表示模型正在训练中在训练模式下模型通常会执行一些特定的操作。trainingFalse表示处于推断模式测试模式或者评估模式在推断模式下模型可能会有一些与训练不同的行为。trainingNone的时候表示模型的训练模式将由框架自动确定通常情况下在调用模型的时候如果没有显式指定训练模式框架会自动将模型置于推断模式下。
maskNone
如果mask被指定为一个张量tensor那么模型的计算将会受到这个掩码的影响掩码可以指示哪些位置的输入需要被忽略或者被加权。 当maskNone时表示没有提供掩码模型在计算时将不会考虑额外的掩码信息。
outputsself.vgg(inputs)
由前面的可知vgg是一个模型通过向get_vgg19_model中传入层layers得到。将inputs传入得到outputs输出。
for layer,factor in self.content_layers.items(): content_outputs.append((outputs[self.outputs_index_map[layer]][0],factor))
重点就是看outputs[self.outputs_index_map[layer]]
self.outputs_index_map是一个将层名称映射到输出索引的字典[self.outputs_index_map[layer]]得到的是一个数值索引在outputs中的索引后面的[0]表示取该元素outputs的该索引处对应的元素的第一个元素。通常是因为特征表示是一个张量的数组而我们只需要其中的一个特征。 而factor表示的是与特征表示相关联的因子或权重在风格迁移中这个因子常用于调整特征表示的权重。
整体而言这个元组表示了一个特征表示通过outputs和self.outputs_index_map获取和与之相关联的权重或因子的组合。
return {content:content_outputs,style:style_outputs}
最后将得到的字典以字典的形式返回。