当前位置: 首页 > news >正文

沧州兼职网站建设施工企业价值链

沧州兼职网站建设,施工企业价值链,上海十大好厂排名,网站建设空格怎么打原文#xff1a;Deep Learning for Computer Vision 协议#xff1a;CC BY-NC-SA 4.0 译者#xff1a;飞龙 本文来自【ApacheCN 深度学习 译文集】#xff0c;采用译后编辑#xff08;MTPE#xff09;流程来尽可能提升效率。 不要担心自己的形象#xff0c;只关心如何实… 原文Deep Learning for Computer Vision 协议CC BY-NC-SA 4.0 译者飞龙 本文来自【ApacheCN 深度学习 译文集】采用译后编辑MTPE流程来尽可能提升效率。 不要担心自己的形象只关心如何实现目标。——《原则》生活原则 2.3.c 六、相似性学习 在本章中我们将学习相似性学习并学习相似性学习中使用的各种损失函数。 当每个类别的数据集都很小时相似性学习对我们很有用。 我们将了解可用于人脸分析的不同数据集并建立用于人脸识别界标检测的模型。 我们将在本章介绍以下主题 相似性学习的不同算法用于相似度学习的各种损失函数可以使用此类模型的各种方案人脸识别的完整过程 相似性学习算法 相似性学习是训练度量以计算两个实体之间的相似性的过程。 由于学习了相似性这也可以称为度量学习。 度量可以是欧几里得或余弦或其他自定义距离函数。 实体可以是任何数据例如图像视频文本或表格。 为了计算度量需要图像的向量表示。 此表示可以是 CNN 计算的特征如第 3 章“图像检索”中所述。 为对象分类而学习的 CNN 可以用作计算度量的向量。 为图像分类而获得的特征向量将不是手头任务的最佳表示。 在相似性学习中我们发现有关 CNN 的信息这些 CNN 会为相似性学习任务生成经过训练的特征。 这里给出了相似性学习的一些应用 使用生物识别比较两个人脸的人脸验证用于在线查找类似产品的现实世界中的对象的视觉搜索某些属性相似的产品的视觉推荐 在本章中我们将详细了解人脸验证。 因此让我们从可用于相似性学习的算法开始。 连体网络 顾名思义连体网络是一种神经网络模型其中训练该网络以区分两个输入。 连体网络可以训练 CNN以通过两个编码器产生嵌入。 每个编码器被馈送正对或负对中的一个图像。 连体网络所需的数据少于其他深度学习算法。 最初引入连体网络来比较签名。 下图显示了一个连体网络。 权重在网络之间共享 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Qsv21gtk-1681567606691)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/451420ac-8f1b-415c-b8d7-f893cf701fee.png)] 连体网络的另一种用途是单样本学习。 单样本学习是仅举一个示例的学习技术。 在这种情况下可以显示图像并判断它们是否相似。 对于大多数相似性学习任务需要一对正负对进行训练。 可以将此类数据集与可用于分类任务的任何数据集一起形成前提是它们是欧几里得距离。 这些算法与前几章中的算法之间的主要区别在于这些编码器试图将一个编码器与另一个编码器区分开。 对比损失 对比损失通过相似度区分图像。 使用相似性度量比较特征或潜在层并与目标一起训练相似性得分。 在正对的情况下目标将为 0因为两个输入相同。 对于负数对在余弦距离或正则欧几里得距离的情况下潜对之间的距离最大为 0。 损耗可以由contrastive_loss定义在以下代码中进行解释 def contrastive_loss(model_1, model_2, label, margin0.1):distance tf.reduce_sum(tf.square(model_1 - model_2), 1)loss label * tf.square(tf.maximum(0., margin - tf.sqrt(distance))) (1 - label) * distanceloss 0.5 * tf.reduce_mean(loss)return loss比较两个模型的距离并计算损失。 现在我们将定义和训练一个连体网络。 对于连体网络我们将需要两个相同的模型。 接下来借助以下代码为具有给定输入的简单 CNN 定义一个函数 def get_model(input_):input_reshape tf.reshape(input_, [-1, 28, 28, 1],nameinput_reshape)convolution_layer_1 convolution_layer(input_reshape, 64)pooling_layer_1 pooling_layer(convolution_layer_1)convolution_layer_2 convolution_layer(pooling_layer_1, 128)pooling_layer_2 pooling_layer(convolution_layer_2)flattened_pool tf.reshape(pooling_layer_2, [-1, 5 * 5 * 128],nameflattened_pool)dense_layer_bottleneck dense_layer(flattened_pool, 1024)return dense_layer_bottleneck定义的模型将使用两次来定义连体网络所需的编码器。 接下来定义两个模型的占位符。 对于每一对输入的相似性也作为输入提供。 定义的模型相同。 还可以定义模型以便共享权重。 此处定义了左右两个模型 left_input tf.placeholder(tf.float32, shape[None, input_size]) right_input tf.placeholder(tf.float32, shape[None, input_size]) y_input tf.placeholder(tf.float32, shape[None, no_classes]) left_bottleneck get_model(left_input) right_bottleneck get_model(right_input)瓶颈层是从模型中获取的并被连接在一起。 这对于相似性学习问题至关重要。 可以创建任意数量的模型并且可以连接最后的层如下所示 dense_layer_bottleneck tf.concat([left_bottleneck, right_bottleneck], 1)接下来添加一个丢弃层并从级联层中计算出对率。 然后该过程类似于任何其他网络如下所示 dropout_bool tf.placeholder(tf.bool) dropout_layer tf.layers.dropout(inputsdense_layer_bottleneck,rate0.4,trainingdropout_bool) logits dense_layer(dropout_layer, no_classes)with tf.name_scope(loss):softmax_cross_entropy tf.nn.softmax_cross_entropy_with_logits(labelsy_input, logitslogits)loss_operation tf.reduce_mean(softmax_cross_entropy, nameloss)tf.summary.scalar(loss, loss_operation)with tf.name_scope(optimiser):optimiser tf.train.AdamOptimizer().minimize(loss_operation)with tf.name_scope(accuracy):with tf.name_scope(correct_prediction):predictions tf.argmax(logits, 1)correct_predictions tf.equal(predictions, tf.argmax(y_input, 1))with tf.name_scope(accuracy):accuracy_operation tf.reduce_mean(tf.cast(correct_predictions, tf.float32)) tf.summary.scalar(accuracy, accuracy_operation)session tf.Session() session.run(tf.global_variables_initializer())merged_summary_operation tf.summary.merge_all() train_summary_writer tf.summary.FileWriter(/tmp/train, session.graph) test_summary_writer tf.summary.FileWriter(/tmp/test)test_images, test_labels mnist_data.test.images, mnist_data.test.labels数据必须分别输入左右模型如下所示 for batch_no in range(total_batches):mnist_batch mnist_data.train.next_batch(batch_size)train_images, train_labels mnist_batch[0], mnist_batch[1]_, merged_summary session.run([optimiser, merged_summary_operation],feed_dict{left_input: train_images,right_input: train_images,y_input: train_labels,dropout_bool: True})train_summary_writer.add_summary(merged_summary, batch_no)if batch_no % 10 0:merged_summary, _ session.run([merged_summary_operation,accuracy_operation], feed_dict{left_input: test_images,right_input: test_images,y_input: test_labels,dropout_bool: False})test_summary_writer.add_summary(merged_summary, batch_no)我们已经看到了如何定义一个连体网络。 定义了两个编码器并连接了潜在空间以形成训练损失。 左右模型分别提供数据。 接下来我们将看到如何在单个网络中执行相似性学习。 FaceNet Schroff 等人提出的 FaceNet 模型解决了人脸验证问题。 它学习一个深层的 CNN然后将人脸图像转换为嵌入图像。 嵌入可用于比较人脸以查看其相似程度并可通过以下三种方式使用 人脸验证考虑两个人脸并确定它们是否相似。 人脸验证可以通过计算距离度量来完成。人脸识别是用于用名字标记人脸的分类问题。 嵌入向量可用于训练最终标签。人脸聚类将相似的人脸分组就像照片应用将同一个人的照片聚在一起的方式一样。 诸如 KMeans 之类的聚类算法用于对人脸进行分组。 下图显示了 FaceNet 架构 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0Vi2USZ0-1681567606693)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/b1d11aa0-8cd0-498c-873c-edc53897f6c9.png)] 经 Schroff 等人许可复制。 FaceNet 会获取一批人脸图像并进行训练。 在那一批中将有几个正对。 在计算损耗时考虑正对和最接近的几个负对。 挖掘选择性对可实现平稳训练。 如果所有负面因素一直都被推开则训练不稳定。 比较三个数据点称为三元组损失。 在计算损耗时图像被认为具有正负匹配。 底片仅被推动一定的幅度。 在此详细说明三元组损失。 三元组损失 三元组损失学习图像的得分向量。 人脸描述符的得分向量可用于验证欧几里得空间中的人脸。 在学习投影的意义上三元组损失类似于度量学习因此可以区分输入。 这些投影或描述符或分数向量是紧凑的表示形式因此可以视为降维技术。 一个三元组由一个锚点正负面组成。 锚可以是任何人的人脸正面是同一个人的图像。 负片图像可能来自另一个人。 显然对于给定的锚点将会有很多负面的人脸。 通过选择当前更靠近锚点的底片编码器将很难区分人脸从而使其学习效果更好。 此过程称为难负例挖掘。 可以在欧氏空间中使用阈值获得更接近的负值。 下图描述了三元组损失模型 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aoKyN6dX-1681567606693)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/861242f9-1c52-49ef-a891-0377251b7745.png)] 经 Schroff 等人许可复制。 TensorFlow 中的损失计算如下所示 def triplet_loss(anchor_face, positive_face, negative_face, margin):def get_distance(x, y):return tf.reduce_sum(tf.square(tf.subtract(x, y)), 1)positive_distance get_distance(anchor_face, positive_face)negative_distance get_distance(anchor_face, negative_face)total_distance tf.add(tf.subtract(positive_distance, negative_distance), margin)return tf.reduce_mean(tf.maximum(total_distance, 0.0), 0)三元组的挖掘是一项艰巨的任务。 每个点都必须与其他点进行比较以获得适当的锚点和正对。 三元组的挖掘如下所示 def mine_triplets(anchor, targets, negative_samples):distances cdist(anchor, targets, cosine)distances cdist(anchor, targets, cosine).tolist()QnQ_duplicated [[target_index for target_index, dist in enumerate(QnQ_dist) if dist QnQ_dist[query_index]]for query_index, QnQ_dist in enumerate(distances)]for i, QnT_dist in enumerate(QnT_dists):for j in QnQ_duplicated[i]:QnT_dist.itemset(j, np.inf)QnT_dists_topk QnT_dists.argsort(axis1)[:, :negative_samples]top_k_index np.array([np.insert(QnT_dist, 0, i) for i, QnT_dist in enumerate(QnT_dists_topk)])return top_k_index由于距离计算发生在 CPU 中因此这可能会使在 GPU 机器上的训练变慢。 FaceNet 模型是训练人脸相似模型的最新方法。 DeepNet 模型 DeepNet 模型用于学习用于人脸验证任务例如 FaceNet的人脸嵌入。 这是对上一部分中讨论的 FaceNet 方法的改进。 它需要对同一张脸进行多次裁剪并通过多个编码器才能获得更好的嵌入效果。 与 FaceNet 相比此方法具有更高的准确率但需要更多时间进行处理。 人脸裁切在相同区域进行并通过其各自的编码器。 然后将所有层连接起来以进行三元组损失的训练。 DeepRank Wang 等人提出的 DeepRank 用于根据相似度对图像进行排名。 图像通过不同的模型传递如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gsJadFrF-1681567606693)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/85e5d360-602e-4bf4-b596-09e44f152e27.png)] 经王等人许可转载。 在此也计算了三元组损耗并且反向传播更加顺利。 然后可以将图像转换为线性嵌入以进行排名如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j4cp4apH-1681567606694)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/e87e214e-cc3c-45bd-8629-75a2beeef0ea.png)] 经 Wang 等人许可复制。 该算法对于排名目的非常有用。 视觉推荐系统 视觉推荐系统非常适合获取给定图像的推荐。 推荐模型提供具有相似属性的图像。 根据 Shankar 等人提出的以下模型您可以了解相似图像的嵌入并提供以下建议 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sukDZHKL-1681567606694)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/7337cf27-f5a5-4292-b4b2-d967bd5382f9.png)] 图a显示了深度排名架构图b显示了 VisNet 架构经 Shankar 等人许可复制。 这些是用于相似性学习的一些算法。 在下一节中我们将看到如何将这些技术应用于人脸。 人脸分析 可以使用计算机视觉以多种方式分析人脸。 为此需要考虑以下几个因素 人脸检测找到人脸位置的边界框人脸标志检测查找鼻子嘴巴等人脸特征的空间点人脸对齐将人脸转换成正面人脸以进行进一步分析属性识别查找诸如性别微笑等属性情感分析分析人的情感人脸验证查找两个图像是否属于同一个人人脸识别识别人脸人脸聚类将同一个人的人脸分组在一起 在以下各节中让我们详细了解这些任务的数据集和实现。 人脸检测 人脸检测类似于对象检测我们在第 4 章“对象检测”中讨论过。 必须从图像中检测出人脸的位置。 可以从这里下载名为人脸检测数据集和基准FDDB的数据集。 。 它具有 2,845 张带有 5,171 张脸的图像。 可以从这里下载 Yang 等人提出的另一个称为宽脸的数据集。 它具有 32,203 张图像和 393,703 张人脸。 这是来自更广泛的人脸数据集的图像示例 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BXaqiovd-1681567606695)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/92e946e7-2fb7-468a-aacd-77039c30fbb4.jpg)] 由杨等人提出。 并转载自这里 数据集的比例姿势遮挡表情妆容和照明度都有很好的变化。 另一个名多属性标签的人脸MALF的数据集包含 5,250 张图像其中包含 11,931 张人脸。 可以从这个链接访问 MALF。 在对象检测中使用的相同技术也可以应用于人脸检测。 人脸标志和属性 人脸标志是人脸的空间点。 空间点对应于各种人脸特征的位置例如眼睛眉毛鼻子嘴巴和下巴。 点数可能会从 5 到 78 不等具体取决于标注。 人脸界标也称为基准点人脸关键点或人脸姿势。 人脸标志具有许多应用如下所示 更好地进行人脸验证或识别的人脸对齐跟踪视频中的人脸测量人脸表情或情感有助于诊断疾病 接下来我们将看到一些带有基准点标注的数据库。 多任务人脸标志MTFL数据集 MTFL数据集由 Zhang 等人提出。 并带有五个人脸标志以及性别微笑眼镜和头部姿势标注。 数据库中存在 12,995 张人脸。 可以从这里下载MTFL。 这是MTFL中存在的图像的示例 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9Telewn4-1681567606695)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/de1113bf-8f62-4752-a656-e0f79ca4b1a4.jpg)] 由张等人提出。 并转载自这里 人脸在年龄照度情感等方面有很多变化。 头部姿势是人脸方向的角度以度为单位。 眼镜微笑性别属性等都用二元标签标注。 Kaggle 关键点数据集 Kaggle 关键点数据集带有 15 个人脸标志。 数据集中存在 8,832 张图像。 可以从这个链接下载。 图像尺寸为 96 像素 x 96 像素。 多属性人脸标志MAFL数据集 Zhang 等人提出的MAFL数据集。 带有 5 种具有 40 种不同人脸属性的人脸标志。 数据库中存在 20,000 张人脸。 可以从这里下载MAFL。 这是MAFL中存在的图像的示例 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5bp6Xiib-1681567606696)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/0c8f1dd3-a580-402f-a9e2-66ccff7c19b1.png)] 由 Liu 等人提出。 并转载自这里 标注的属性包括尖头带子小胡子卷发戴帽子等。 这些图像也包含在CelebA数据集中稍后将详细讨论。 学习人脸关键点 如先前主题中所述在计算关键人脸点时需要定义一些参数。 我们将使用以下代码来定义这些参数 image_size 40 no_landmark 10 no_gender_classes 2 no_smile_classes 2 no_glasses_classes 2 no_headpose_classes 5 batch_size 100 total_batches 300 接下来为各种输入保留一些占位符。 image_input tf.placeholder(tf.float32, shape[None, image_size, image_size]) landmark_input tf.placeholder(tf.float32, shape[None, no_landmark]) gender_input tf.placeholder(tf.float32, shape[None, no_gender_classes]) smile_input tf.placeholder(tf.float32, shape[None, no_smile_classes]) glasses_input tf.placeholder(tf.float32, shape[None, no_glasses_classes]) headpose_input tf.placeholder(tf.float32, shape[None, no_headpose_classes])接下来使用四个卷积层构造主模型如以下代码所示 image_input_reshape tf.reshape(image_input, [-1, image_size, image_size, 1],nameinput_reshape)convolution_layer_1 convolution_layer(image_input_reshape, 16) pooling_layer_1 pooling_layer(convolution_layer_1) convolution_layer_2 convolution_layer(pooling_layer_1, 48) pooling_layer_2 pooling_layer(convolution_layer_2) convolution_layer_3 convolution_layer(pooling_layer_2, 64) pooling_layer_3 pooling_layer(convolution_layer_3) convolution_layer_4 convolution_layer(pooling_layer_3, 64) flattened_pool tf.reshape(convolution_layer_4, [-1, 5 * 5 * 64],nameflattened_pool) dense_layer_bottleneck dense_layer(flattened_pool, 1024) dropout_bool tf.placeholder(tf.bool) dropout_layer tf.layers.dropout(inputsdense_layer_bottleneck,rate0.4,trainingdropout_bool)接下来我们将使用以下代码为所有不同的任务创建一个对率分支 landmark_logits dense_layer(dropout_layer, 10) smile_logits dense_layer(dropout_layer, 2) glass_logits dense_layer(dropout_layer, 2) gender_logits dense_layer(dropout_layer, 2) headpose_logits dense_layer(dropout_layer, 5)损耗是针对所有人脸特征单独计算的如以下代码所示 landmark_loss 0.5 * tf.reduce_mean(tf.square(landmark_input, landmark_logits))gender_loss tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labelsgender_input, logitsgender_logits))smile_loss tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labelssmile_input, logitssmile_logits))glass_loss tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labelsglasses_input, logitsglass_logits))headpose_loss tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labelsheadpose_input, logitsheadpose_logits))loss_operation landmark_loss gender_loss \smile_loss glass_loss headpose_loss现在我们将初始化优化器并开始训练如以下代码所示 optimiser tf.train.AdamOptimizer().minimize(loss_operation) session tf.Session() session.run(tf.initialize_all_variables()) fiducial_test_data fiducial_data.testfor batch_no in range(total_batches):fiducial_data_batch fiducial_data.train.next_batch(batch_size)loss, _landmark_loss, _ session.run([loss_operation, landmark_loss, optimiser],feed_dict{image_input: fiducial_data_batch.images,landmark_input: fiducial_data_batch.landmarks,gender_input: fiducial_data_batch.gender,smile_input: fiducial_data_batch.smile,glasses_input: fiducial_data_batch.glasses,headpose_input: fiducial_data_batch.pose,dropout_bool: True})if batch_no % 10 0:loss, _landmark_loss, _ session.run([loss_operation, landmark_loss],feed_dict{image_input: fiducial_test_data.images,landmark_input: fiducial_test_data.landmarks,gender_input: fiducial_test_data.gender,smile_input: fiducial_test_data.smile,glasses_input: fiducial_test_data.glasses,headpose_input: fiducial_test_data.pose,dropout_bool: False})此过程可用于检测人脸特征以及界标。 人脸识别 人脸识别或人脸识别是从数字图像或视频中识别人物的过程。 让我们在下一部分中了解可用于人脸识别的数据集。 野生LFW数据集中的带标签的人脸 LFW数据集包含 13,233 张人脸和 5,749 位独特的人被视为评估人脸验证数据集的标准数据集。 精度度量可用于评估计法。 可以在这个链接中访问数据集。 YouTube 人脸数据集 YouTube faces数据集包含 3,425 个视频剪辑其中包含 1,595 个独特的人。 这些视频是从 YouTube 收集的。 数据集每人至少有两个视频。 该数据集被视为视频中人脸验证的标准数据集。 可以在这个链接中访问数据集。 CelebFaces 属性数据集CelebA CelebA 数据集带有人物身份以及 5 个人脸标志和 40 个属性的标注。 数据库中有 10,177 位独特的人拥有 202,599 张人脸图像。 它是可用于人脸验证检测界标和属性识别问题的大型数据集之一。 图像具有带有各种标注的良好人脸变化。 可以在这个链接中访问数据集。 CASIA 网络人脸数据库 CASIA数据集带有 10,575 个独特的带标注人脸总共有 494,414 张图像。 该数据集可以从这个链接获得。 这是可用于人脸验证和识别问题的第二大公共数据集。 VGGFace2 数据集 Cao 等人提出的VGGFace2数据集。 被 9,131 位独特的人注解具有 331 万张图片。 数据集可从这个链接获得。 变化包括年龄种族姿势职业和照度。 这是可用于人脸验证的最大数据集。 这是数据集中存在的图像的示例 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cCu28OX0-1681567606696)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/d2c45b27-6fc0-409c-8aa6-196b8569aec2.png)] 由曹等人提出。 并转载自这里 每个唯一的人的最小平均和最大图像数分别是 87、362.6 和 843。 计算人脸之间的相似度 人脸相似度的计算是一个多步骤问题。 必须检测人脸然后找到基准点。 面可以与基准点对齐。 对齐的面可以用于比较。 如前所述人脸检测类似于对象检测。 因此为了找到人脸之间的相似性我们将首先通过以下代码导入所需的库以及facenet库 from scipy import misc import tensorflow as tf import numpy as np import os import facenet print facenet from facenet import load_model, prewhiten import align.detect_face可以如下所示加载和对齐图像 def load_and_align_data(image_paths, image_size160, margin44, gpu_memory_fraction1.0):minsize 20threshold [0.6, 0.7, 0.7]factor 0.709 print(Creating networks and loading parameters)with tf.Graph().as_default():gpu_options tf.GPUOptions(per_process_gpu_memory_fractiongpu_memory_fraction)sess tf.Session(configtf.ConfigProto(gpu_optionsgpu_options, log_device_placementFalse))with sess.as_default():pnet, rnet, onet align.detect_face.create_mtcnn(sess, None)nrof_samples len(image_paths)img_list [None] * nrof_samplesfor i in range(nrof_samples):img misc.imread(os.path.expanduser(image_paths[i]), modeRGB)img_size np.asarray(img.shape)[0:2]bounding_boxes, _ align.detect_face.detect_face(img, minsize, pnet, rnet, onet, threshold, factor)det np.squeeze(bounding_boxes[0, 0:4])bb np.zeros(4, dtypenp.int32)bb[0] np.maximum(det[0] - margin / 2, 0)bb[1] np.maximum(det[1] - margin / 2, 0)bb[2] np.minimum(det[2] margin / 2, img_size[1])bb[3] np.minimum(det[3] margin / 2, img_size[0])cropped img[bb[1]:bb[3], bb[0]:bb[2], :]aligned misc.imresize(cropped, (image_size, image_size), interpbilinear)prewhitened prewhiten(aligned)img_list[i] prewhitenedimages np.stack(img_list)return images现在我们将处理图像路径以获取嵌入。 相同的代码在这里给出 def get_face_embeddings(image_paths, model/20170512-110547/):images load_and_align_data(image_paths)with tf.Graph().as_default():with tf.Session() as sess:load_model(model)images_placeholder tf.get_default_graph().get_tensor_by_name(input:0)embeddings tf.get_default_graph().get_tensor_by_name(embeddings:0)phase_train_placeholder tf.get_default_graph().get_tensor_by_name(phase_train:0)feed_dict {images_placeholder: images, phase_train_placeholder: False}emb sess.run(embeddings, feed_dictfeed_dict)return emb现在我们将使用以下代码来计算嵌入之间的距离 def compute_distance(embedding_1, embedding_2):dist np.sqrt(np.sum(np.square(np.subtract(embedding_1, embedding_2))))return dist此函数将计算嵌入之间的欧几里德距离。 寻找最佳阈值 使用前面的函数可以计算出该系统的精度。 以下代码可用于计算最佳阈值 import sys import argparse import os import re from sklearn.metrics import classification_report from sklearn.metrics import accuracy_score现在使用以下代码从文件夹中获取图像路径 def get_image_paths(image_directory):image_names sorted(os.listdir(image_directory))image_paths [os.path.join(image_directory, image_name) for image_name in image_names]return image_paths通过嵌入时将获得图像的距离如以下代码所示 def get_labels_distances(image_paths, embeddings):target_labels, distances [], []for image_path_1, embedding_1 in zip(image_paths, embeddings):for image_path_2, embedding_2 in zip(image_paths, embeddings):if (re.sub(r\d, , image_path_1)).lower() (re.sub(r\d, , image_path_2)).lower():target_labels.append(1)else:target_labels.append(0)distances.append(compute_distance(embedding_1, embedding_2)) # Replace distance metric herereturn target_labels, distances阈值随以下代码所示而变化并相应打印各种度量 def print_metrics(target_labels, distances):accuracies []for threshold in range(50, 150, 1):threshold threshold/100.predicted_labels [1 if dist threshold else 0 for dist in distances]print(Threshold, threshold)print(classification_report(target_labels, predicted_labels, target_names[Different, Same]))accuracy accuracy_score(target_labels, predicted_labels)print(Accuracy: , accuracy)accuracies.append(accuracy)print(max(accuracies))现在借助以下代码将图像路径传递给嵌入 def main(args):image_paths get_image_paths(args.image_directory)embeddings get_face_embeddings(image_paths) # Replace your embedding calculation heretarget_labels, distances get_labels_distances(image_paths, embeddings)print_metrics(target_labels, distances)最后图像目录作为这些方法的主要参数传递如以下代码所示 if __name__ __main__:parser argparse.ArgumentParser()parser.add_argument(image_directory, typestr, helpDirectory containing the images to be compared)parsed_arguments parser.parse_args(sys.argv[1:])main(parsed_arguments)在此示例中我们采用了预先训练的模型并将其用于构建人脸验证方法。 ; 人脸聚类 人脸聚类是将同一个人的图像分组在一起以形成相册的过程。 可以提取人脸的嵌入并且可以使用诸如 K 均值的聚类算法将同一个人的人脸合并在一起。 TensorFlow 为 KMeans 算法提供了一个称为 tf.contrib.learn.KmeansClustering 的 API。 K 均值算法将数据点分组在一起。 借助这种 KMeans 算法可以提取专辑的嵌入内容并且可以一起找到个人的人脸或者换句话说可以将聚在一起。 总结 在本章中我们介绍了相似性学习的基础知识。 我们研究了度量学习连体网络和 FaceNet 等算法。 我们还介绍了损失函数例如对比损失和三重损失。 还涵盖了两个不同的领域即排名和推荐。 最后通过理解几个步骤包括检测基准点检测和相似性评分涵盖了人脸识别的分步演练。 在下一章中我们将了解循环神经网络及其在自然语言处理问题中的使用。 稍后我们将使用语言模型和图像模型来对图像进行字幕。 我们将针对该问题访问几种算法并查看两种不同类型数据的实现。 七、图像字幕生成 在本章中我们将处理字幕图像的问题。 这涉及到检测对象并且还提出了图像的文本标题。 图像字幕生成也可以称为图像文本转换。 曾经被认为是一个非常棘手的问题我们现在在此方面取得了相当不错的成绩。 对于本章需要具有相应标题的图像数据集。 在本章中我们将详细讨论图像字幕生成的技术和应用。 我们将在本章介绍以下主题 了解用于评估它们的不同数据集和指标了解用于自然语言处理问题的一些技巧向量模型的不同单词几种用于图像字幕生成的算法不良结果和改进范围 了解问题和数据集 自动生成图像标题的过程是一项重要的深度学习任务因为它结合了语言和视觉这两个世界。 该问题的独特性使其成为计算机视觉中的主要问题之一。 用于图像字幕生成的深度学习模型应该能够识别图像中存在的对象并能够以自然语言生成表示对象与动作之间关系的文本。 此问题的数据集很少。 其中最著名的数据集是第 4 章“对象检测”中对象检测中涵盖的 COCO 数据集的扩展。 了解用于图像字幕生成的自然语言处理 由于必须从图像中生成自然语言因此熟悉自然语言处理NLP变得很重要。 NLP 的概念是一个广泛的主题因此我们将范围限制为与图像字幕生成相关的主题。 自然语言的一种形式是文本。 文本是单词或字符的序列。 文本的原子元素称为令牌它是字符的序列。 字符是文本的原子元素。 为了处理文本形式的任何自然语言必须通过删除标点符号方括号等对文本进行预处理。 然后必须通过将文本分隔为空格来将文本标记为单词。 然后必须将单词转换为向量。 接下来我们将看到向量转换如何提供帮助。 以向量形式表达单词 向量形式的单词可以帮助自己执行算术运算。 向量必须紧凑尺寸较小。 同义词应具有相似的向量而反义词应具有不同的向量。 可以将单词转换为向量以便可以如下所示比较关系 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2C1CSnKV-1681567606697)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/d4061008-c857-4130-bb3e-6c1f418ea379.png)] 该向量算法使得能够在不同实体之间的语义空间中进行比较。 接下来我们将看到如何创建可将单词转换为向量表示的深度学习模型。 将单词转换为向量 通过在大型文本语料库上训练模型可以将单词转换为向量。 训练模型使得给定一个单词该模型可以预测附近的单词。 在预测附近单词的单次热编码之前首先对单词进行单次热编码然后进行隐藏层。 以这种方式进行训练将创建单词的紧凑表示。 可以通过两种方式获得单词的上下文如下所示 跳跃图SkipGram给定一个单词尝试预测几个接近的单词连续词袋CBOW通过给定一组词来预测一个词从而跳过跳跃语法 下图说明了这些过程 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6vLgq4gy-1681567606697)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/2b34c3e0-28a8-4d55-8c1b-70ea045357c5.png)] 两种方法均显示出良好的结果。 单词在嵌入空间中转换为向量。 接下来我们将看到训练嵌入空间的详细信息。 训练嵌入 可以使用如下所示的模型来训练嵌入 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XYy4Whvi-1681567606697)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/82b25c21-48e2-4de6-b9c0-03e6e245a825.png)] 如上图所示目标词是根据上下文或历史预测的。 该预测基于 Softmax 分类器。 隐藏层将嵌入作为紧凑的表示形式学习。 请注意这不是完整的深度学习模型但它仍然可以正常工作。 这是嵌入的低维可视化 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A6PO8paY-1681567606698)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/1dc5ed0c-353d-4884-8251-522e97b6bc8e.png)] 使用 Softmax 分类器的嵌入的低维可视化 该可视化使用 TensorBoard 生成。 具有相似语义或不同词性的单词会一起出现。 我们已经学习了如何训练用于生成文本的紧凑表示。 接下来我们将看到图像字幕生成的方法。 图像字幕生成方法及相关问题 已经提出了几种对图像进行字幕的方法。 直观地将图像转换为视觉特征并从这些特征生成文本。 生成的文本将采用词嵌入的形式。 生成文本的一些主要方法涉及 LSTM 和关注。 让我们从使用旧的生成文本的方法开始。 使用条件随机场链接图像和文本 Kulkarni 等人在论文中提出了一种从图像中查找对象和属性并使用它来生成文本的方法。 条件随机场CRF。 传统上CRF 用于结构化预测例如文本生成。 生成文本的流程如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ujQTSszx-1681567606698)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/114a59b6-d1fe-4f78-b9c6-32c7d416cd3a.png)] 该图说明了使用 CRF 生成文本的过程摘自 Kulkarni 等人 CRF 的使用在以适当的前置词以连贯的方式生成文本方面存在局限性。 结果显示在这里 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vPLZ8X1U-1681567606699)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/29a03016-9c2c-4712-9dc8-cf412fb617b7.png)] 复制自 Kulkarni 等人 结果对对象和属性具有正确的预测但无法生成良好的描述。 在 CNN 特征上使用 RNN 生成字幕 Vinyals 等人在论文中提出了一种端到端可训练的深度学习用于图像字幕生成的方法该方法将 CNN 和 RNN 背靠背地堆叠在一起。 这是一个端到端的可训练模型。 结构如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-92mfWCiI-1681567606699)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/5bf3b8f9-fa55-4a3f-a84c-b0818fcc856a.png)] 转载自 Vinyals 等人2015 年 该模型可以生成以自然语言完成的句子。 CNN 和 LSTM 的展开图如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-abLLc9wt-1681567606699)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/04f54858-0741-427c-9c36-4c627f70ba34.png)] 该图说明了 CNN 和 LSTM 架构摘自 Vinyals 等人 这是 LSTM 的展开视图。 此处显示了一组选择性的结果 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BwJxC1jG-1681567606700)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/bc22e56f-e384-499e-be63-4e036405ee7c.png)] 转载自 Vinyals 等人2015 年 在此过程中CNN 将图像编码为特征RNN 从中生成句子。 使用图像排名创建字幕 Ordonez 等人在论文中提出了一种方法对图像进行排名然后生成标题。 此过程的流程如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pq75basb-1681567606700)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/5b285990-9992-4773-833a-720904a28188.png)] 复制自 Ordonez 等人2015 从排名图像中提取的高级信息可用于生成文本。 下图显示可用于排名的图像越多结果将越好 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vTugRRYP-1681567606701)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/fd60d31e-2040-4634-8f2b-245e258740ea.png)] 复制自 Ordonez 等人2015 从图像检索字幕和从字幕检索图像 Chen 等人在论文中提出了一种从文本中检索图像和从图像中检索文本的方法。 这是双向映射。 下图显示了一个用自然语言解释图像的人和另一个在视觉上思考它的人 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WoGpj4IB-1681567606701)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/226bae31-12c2-4ec6-aa6a-5f54db2f7d6e.png)] 转载自 Chen 等人2015 检索字幕可以通过以下方式通过潜在空间连接图像和文本的编码器来实现 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3HgiHaC7-1681567606701)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/f4ca10b9-38aa-46a9-9839-d7844a8401c1.png)] 转载自 Chen 等人2015 图像中的第一个模型是用于训练的完整模型。 如图中所示视觉特征也可以用于生成句子反之亦然。 密集字幕 Johnson 等人在论文中提出了一种用于密集字幕的方法。 首先让我们看一些结果以了解任务 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ha79Rxtp-1681567606702)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/29744e79-12f1-49c0-a1bb-cd99c44a87d2.png)] 转载自 Johnson 等人 如您所见为图像中的对象和动作生成了单独的标题 由此得名; 密集字幕。 这是 Johnson 等人提出的架构 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LgUYqaVm-1681567606702)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/b4d4bca7-5ea6-48a2-ad5c-c5063af9ebe5.png)] 转自 Johnson 等人 该架构实质上是 Faster-RCNN 和 LSTM 的组合。 产生该区域以产生对象检测结果并且使用该区域的视觉特征来产生字幕。 使用 RNN 的字幕生成 Donahue 等人在论文中提出了长期循环卷积网络LRCN 用于图像字幕生成的任务。 此模型的架构如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tMq9Hu9G-1681567606702)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/b0a60d74-0013-443b-b167-4cc77a74bfcb.png)] 转载自 Donahue 等人 图中显示了 CNN 和 LSTM 在整个时间上的权重这使得该方法可扩展到任意长序列。 使用多模态度量空间 Mao 等人在论文中提出了一种使用多模态嵌入空间生成字幕的方法。 下图说明了这种方法 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XMrQ2raW-1681567606703)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/11930a42-1972-4cbb-a1d7-417207484a6c.png)] 转自毛等人。 Kiros 等人在论文中提出了另一种生成字幕的多模态方法该方法可以将图像和文本嵌入同一多模态空间。 下图说明了这种方法 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AtnxS8sD-1681567606703)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/c7396971-eb91-40ba-8e8e-9ea6ed8eef77.png)] 复制自 Kiros 等人 两种多模式方法都给出了良好的结果。 使用注意力网络的字幕生成 Xu 等人在论文中提出了一种使用注意力机制进行图像字幕生成的方法。 注意力机制对图像的某些区域比其他区域赋予更多权重。 注意还可以实现可视化向我们展示模型生成下一个单词时所关注的位置。 建议的模型如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lZkYB4yZ-1681567606703)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/16daa7fa-b24c-4855-b677-fdb975865573.png)] 转载自徐等人。 首先从图像中提取 CNN 特征。 然后将关注的 RNN 应用于生成单词的图像。 知道什么时候看 Lu 等人提出了一种引起关注的方法可提供出色的结果。 知道何时看待注意力捕获的区域会产生更好的结果。 流程如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TYjXUHIX-1681567606704)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/94576f82-a74c-4394-bc55-78c027c88424.png)] 摘自 Lu 等人 注意力机制如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yxWJGZDW-1681567606704)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/15065730-7c08-4996-9a4d-efd4eaa6b377.png)] 摘自 Lu 等人 结果重点突出的区域如下 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xn7uIAvc-1681567606704)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/aeb23046-5281-48a0-8f43-19852a14bc89.png)] 摘自 Lu 等人 生成字幕时注意力的释放在此处可视化 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aDnpPSzO-1681567606705)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/5dc70bd2-6e0f-4e12-a79b-564d36959461.png)] 摘自 Lu 等人 我们已经看到用于生成字幕几种方法。 接下来我们将看到一个实现。 实现基于注意力的图像字幕生成 让我们使用以下代码从 VGG 和 LSTM 模型定义 CNN vgg_model tf.keras.applications.vgg16.VGG16(weightsimagenet,include_topFalse,input_tensorinput_tensor,input_shapeinput_shape)word_embedding tf.keras.layers.Embedding(vocabulary_size, embedding_dimension, input_lengthsequence_length) embbedding word_embedding(previous_words) embbedding tf.keras.layers.Activation(relu)(embbedding) embbedding tf.keras.layers.Dropout(dropout_prob)(embbedding)cnn_features_flattened tf.keras.layers.Reshape((height * height, shape))(cnn_features) net tf.keras.layers.GlobalAveragePooling1D()(cnn_features_flattened)net tf.keras.layers.Dense(embedding_dimension, activationrelu)(net) net tf.keras.layers.Dropout(dropout_prob)(net) net tf.keras.layers.RepeatVector(sequence_length)(net) net tf.keras.layers.concatenate()([net, embbedding]) net tf.keras.layers.Dropout(dropout_prob)(net)现在我们已经定义了 CNN接下来使用以下代码定义关注层 h_out_linear tf.keras.layers.Convolution1D(depth, 1, activationtanh, border_modesame)(h) h_out_linear tf.keras.layers.Dropout(dropout_prob)(h_out_linear) h_out_embed tf.keras.layers.Convolution1D(embedding_dimension, 1, border_modesame)(h_out_linear) z_h_embed tf.keras.layers.TimeDistributed(tf.keras.layers.RepeatVector(num_vfeats))(h_out_embed)Vi tf.keras.layers.Convolution1D(depth, 1, border_modesame, activationrelu)(V)Vi tf.keras.layers.Dropout(dropout_prob)(Vi) Vi_emb tf.keras.layers.Convolution1D(embedding_dimension, 1, border_modesame, activationrelu)(Vi)z_v_linear tf.keras.layers.TimeDistributed(tf.keras.layers.RepeatVector(sequence_length))(Vi) z_v_embed tf.keras.layers.TimeDistributed(tf.keras.layers.RepeatVector(sequence_length))(Vi_emb)z_v_linear tf.keras.layers.Permute((2, 1, 3))(z_v_linear) z_v_embed tf.keras.layers.Permute((2, 1, 3))(z_v_embed)fake_feat tf.keras.layers.Convolution1D(depth, 1, activationrelu, border_modesame)(s) fake_feat tf.keras.layers.Dropout(dropout_prob)(fake_feat)fake_feat_embed tf.keras.layers.Convolution1D(embedding_dimension, 1, border_modesame)(fake_feat) z_s_linear tf.keras.layers.Reshape((sequence_length, 1, depth))(fake_feat) z_s_embed tf.keras.layers.Reshape((sequence_length, 1, embedding_dimension))(fake_feat_embed)z_v_linear tf.keras.layers.concatenate(axis-2)([z_v_linear, z_s_linear]) z_v_embed tf.keras.layers.concatenate(axis-2)([z_v_embed, z_s_embed])z tf.keras.layers.Merge(modesum)([z_h_embed,z_v_embed]) z tf.keras.layers.Dropout(dropout_prob)(z) z tf.keras.layers.TimeDistributed(tf.keras.layers.Activation(tanh))(z) attention tf.keras.layers.TimeDistributed(tf.keras.layers.Convolution1D(1, 1, border_modesame))(z)attention tf.keras.layers.Reshape((sequence_length, num_vfeats))(attention) attention tf.keras.layers.TimeDistributed(tf.keras.layers.Activation(softmax))(attention) attention tf.keras.layers.TimeDistributed(tf.keras.layers.RepeatVector(depth))(attention) attention tf.keras.layers.Permute((1,3,2))(attention) w_Vi tf.keras.layers.Add()([attention,z_v_linear]) sumpool tf.keras.layers.Lambda(lambda x: K.sum(x, axis-2),output_shape(depth,)) c_vec tf.keras.layers.TimeDistributed(sumpool)(w_Vi) atten_out tf.keras.layers.Merge(modesum)([h_out_linear,c_vec]) h tf.keras.layers.TimeDistributed(tf.keras.layers.Dense(embedding_dimension,activationtanh))(atten_out) h tf.keras.layers.Dropout(dropout_prob)(h)predictions tf.keras.layers.TimeDistributed(tf.keras.layers.Dense(vocabulary_size, activationsoftmax))(h)在前面的代码的帮助下我们定义了一个深度学习模型该模型将 CNN 特征与 RNN 结合在一起并借助注意力机制。 目前这是生成字幕的最佳方法。 总结 在本章中我们已经了解了与图像标题相关的问题。 我们看到了一些涉及自然语言处理和各种word2vec模型例如GLOVE的技术。 我们了解了CNN2RNN度量学习和组合目标等几种算法。 后来我们实现了一个结合了 CNN 和 LSTM 的模型。 在下一章中我们就来了解生成模型。 我们将从头开始学习和实现样式算法并介绍一些最佳模型。 我们还将介绍很酷的生成对抗网络GAN及其各种应用。 八、生成模型 生成模型已经成为计算机视觉中的重要应用。 与前几章讨论的应用根据图像进行预测不同生成模型可以为特定目标创建图像。 在本章中我们将了解 生成模型的应用风格迁移算法训练超分辨率图像模型生成模型的实现和训练当前模型的缺点 在本章的最后您将能够实现一些出色的应用来传递样式并理解与生成模型相关的可能性和困难。 生成模型的应用 让我们从生成模型的可能应用开始本章。 应用是巨大的。 我们将看到其中一些应用以了解动机和可能性。 艺术风格迁移 艺术风格迁移是将艺术风格迁移到任何图像的过程。 例如可以使用一幅图像的艺术风格和另一幅图​​像的内容来创建图像。 Gatys 等人在此显示了一个结合了几种不同样式的图像示例。 图像 A 是应用了样式的照片其结果显示在其他图像中 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dvix6KmY-1681567606705)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/0e36da01-457e-4388-8cec-85994bf97af2.png)] 转载自盖蒂斯等。 此应用引起了公众的注意并且市场上有几种提供此功能的移动应用。 预测视频中的下一帧 可以使用生成模型从合成视频集中预测未来的帧。 在下面由 Lotter 等人提出的图像中左侧的图像是前一帧的模型而右侧有两种与基本事实比较的算法 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SFrN7BZu-1681567606705)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/af300a68-236d-43de-b849-f7fbad8dd6b8.png)] 复制自 Lotter 等人 生成模型生成的框架将是现实的。 图像超分辨率 超分辨率是从较小的图像创建高分辨率图像的过程。 传统上插值用于创建更大的图像。 但是插值通过提供平滑效果而错过了高频细节。 经过训练的生成模型针对此超分辨率的特定目的而创建的图像具有出色的细节。 以下是 Ledig 等人提出的此类模型的示例。 左侧是通过 4 倍缩放生成的看起来与右侧的原件没有区别 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GE7HVjmc-1681567606705)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/96bebdcb-ce44-486b-9b87-f3f48a39b789.png)] 转自 Ledig 等人 超分辨率对于在高质量的显示器或打印件上呈现低分辨率的图像很有用。 另一个应用可能是重建高质量的压缩图像。 交互式图像生成 生成模型可用于通过交互作用创建图像。 用户可以添加编辑内容并且可以生成图像以反映编辑内容如 Zhu 等人建议的那样 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Yyj5RcEB-1681567606706)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/76957f5e-d2e5-4573-a6c7-3aa162253546.png)] 复制自 Zhu 等人 如图所示图像是根据编辑的形状和颜色生成的。 底部的绿色笔触创建了草原矩形创建了摩天大楼依此类推。 图像将被生成并通过用户的进一步输入进行微调。 生成的图像还可以用于检索可以利用的最相似的真实图像。 提供交互式图像生成是一种直观搜索图像的全新方法。 图像到图像的转换 图像可用于生成具有特定目标的其他图像因此此过程称为图像到图像的转换。 此处显示了此类翻译的一些示例以及由 Isola 等人提出的相应标准 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aDpVLYHG-1681567606706)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/a289fe70-1518-455e-91f5-22ae6a0a1de4.png)] 复制自 Isola 等人 带有标签的图像可以转换为逼真的图像以用于创意目的。 黑白图像可以转换为彩色图像。 这样的翻译对于照片编辑应用为旧电影着色服装设计等非常有用。 文本到图像的生成 可以从文本描述中生成图像其步骤类似于图像到图像的翻译。 以下是一些由 Reed 等人展示的自然文本描述生成的示例 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OLjw6G9c-1681567606706)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/5f66cccf-b9c9-4609-b224-06e95897407b.png)] 复制自 Reed 等人 当前此模型仅适用于少数几个对象。 从文本生成图像还不够实际无法在应用中使用。 修复 修复是填充图像中的间隙的过程如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KcEnTvpl-1681567606706)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/c3919cea-ec35-4cff-b352-15975acdb6f9.jpg)] 资料来源https://www.flickr.com/photos/littleredelf/4756059924/ 左侧的图像是正常图像右侧的图像是经过处理的图像。 从图像中可以看到不需要的东西已从图片中删除。 修补对于从图像中删除不需要的对象以及填充扫描图稿的空间很有用。 融合 融合是将图像的一部分平滑地粘贴到另一个图像上而没有任何伪影的过程。 此处显示的图像表示一种图像放置在另一图像上的情况给人留下不好的印象。 图像 b 和 c 代表传统的混合技术例如修正的泊松方法和多样条方法。 最终图像或图像 d 显示了混合生成方法的结果该方法比 Wu 等人的其他方法提供了更好的结果 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zdwtGaOm-1681567606707)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/85081b77-9fc2-436d-8205-13ffb13b374a.png)] 摘自 Wu 等人 混合对于照片编辑和电影行业中的特殊效果非常有用。 转换属性 可以使用生成模型来更改图像的属性。 兰珀Lample等人在此显示可以修改人的人脸以反映不同的属性例如性别眼镜年龄等 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-32yZo7W2-1681567606707)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/e700b8c7-e5a1-4914-8f0a-afded0129609.png)] 转载于 Lample 等人。 更改属性既可以用于创意应用也可以用于娱乐也可以用于生成更多具有变化的训练数据。 创建训练数据 生成模型可用于大规模生成训练甚至可用于完善为训练而创建的合成图像。 这是使用 Wang 等人的生成模型为交通标志识别创建的合成图像 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GsTXrg8c-1681567606707)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/b4123a9e-ccd5-4c45-9348-0935c45e318f.png)] 转载自 Wang 等人 使用这些图像可以使分类更加准确。 创建新的动画角色 生成模型可用于创建具有各种条件的新动画角色例如人脸表情发型服装等如 Jin 等人所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ifiXJsCT-1681567606707)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/e92bfe6e-601b-49e4-a8df-72cb19f7c73e.png)] 转载自 Jin 等人 创建具有不同属性的新角色可以彻底改变动画产业。 照片的 3D 模型 我们可以使用生成模型从 2D 图像创建 3D 模型如 Wu 等人所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MgEdQJIj-1681567606708)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/08cdcdde-c328-4fec-84bc-42c38bd0a7d7.png)] 摘自 Wu 等人 从图像创建 3D 模型对于机器人技术增强现实和动画行业很有用。 在以下各节中我们将学习它们背后的算法。 在下一节中我们将实现神经艺术风格的转换。 神经艺术风格迁移 我们将要实现的第一个应用是神经艺术风格转换。 在这里我们将梵高艺术的风格迁移到图像上。 图像可以视为样式和内容的组合。 艺术风格转换技术将图像转换为看起来像具有特定绘画风格的绘画。 我们将看到如何编写这个想法。 loss函数将比较生成的图像与照片内容和绘画风格。 因此针对图像像素而不是针对网络权重执行优化。 通过将照片的内容与生成的图像相比较然后是绘画风格和生成的图像可以计算出两个值。 内容损失 由于像素不是一个好的选择我们将使用各个层的 CNN 特征因为它们可以更好地表示内容。 如第 3 章“图像检索” 所示初始层具有高频例如边缘拐角和纹理。 后面的层代表对象因此更适合内容。 后者可以比像素更好地将对象与对象进行比较。 但是为此我们需要先使用以下代码导入所需的库 import numpy as np from PIL import Image from scipy.optimize import fmin_l_bfgs_b from scipy.misc import imsave from vgg16_avg import VGG16_Avg from keras import metrics from keras.models import Model from keras import backend as K现在让我们使用以下命令加载所需的图像 content_image Image.open(work_dir bird_orig.png)我们将在此实例中使用以下图片 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ilzroxcz-1681567606708)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/c5f130bb-71bd-45ba-8bea-d224f13820de.png)] 当我们使用 VGG 架构提取特征时必须从所有图像中减去所有ImageNet图像的均值如以下代码所示 imagenet_mean np.array([123.68, 116.779, 103.939], dtypenp.float32)def subtract_imagenet_mean(image):return (image - imagenet_mean)[:, :, :, ::-1]请注意通道是不同的。 preprocess函数拍摄生成的图像并减去平均值然后反转通道。 deprocess函数由于进行了预处理步骤而使效果相反如以下代码所示 def add_imagenet_mean(image, s):return np.clip(image.reshape(s)[:, :, :, ::-1] imagenet_mean, 0, 255)首先我们将了解如何使用其他图像中的内容创建图像。 这是根据随机噪声创建图像的过程。 此处使用的内容是某层中激活的总和。 我们将使随机噪声和图像之间的内容损失最小化这被称为内容损失。 该损耗类似于逐像素损耗但应用于层激活因此将捕获内容而没有噪声。 任何 CNN 架构都可以用来转发内容图像和随机噪声。 比较这两个输出的激活进行激活并计算均方误差。 冻结 CNN 权重时将更新随机图像的像素。 在这种情况下我们将冻结 VGG 网络。 现在可以加载 VGG 模型。 生成图像对子采样技术例如最大池化非常敏感。 无法从最大池化中取回像素值。 因此平均池化比最大池化更平滑。 使用平均池化转换 VGG 模型的特征用于加载模型如下所示 vgg_model VGG16_Avg(include_topFalse)请注意即使合并类型已更改此模型的权重也与原始模型相同。 ResNet 和 Inception 模型不适合此操作因为它们无法提供各种抽象。 我们将从模型冻结的最后一个 VGG 模型的卷积层block_conv1中获取激活。 这是 VGG 的第三层具有广阔的接收范围。 这里给出了相同的代码供您参考 content_layer vgg_model.get_layer(block5_conv1).output现在使用截断的 VGG 创建新模型直到具有良好特征的层。 因此该图像现在可以加载并且可以用于执行前向推断以获得实际激活的层。 使用以下代码创建 TensorFlow 变量以捕获激活 content_model Model(vgg_model.input, content_layer) content_image_array subtract_imagenet_mean(np.expand_dims(np.array(content_image), 0)) content_image_shape content_image_array.shape target K.variable(content_model.predict(content_image_array))让我们定义一个评估器类以计算图像的损耗和梯度。 下列类在迭代的任意点返回损耗和梯度值 class ConvexOptimiser(object):def __init__(self, cost_function, tensor_shape):self.cost_function cost_functionself.tensor_shape tensor_shapeself.gradient_values None def loss(self, point):loss_value, self.gradient_values self.cost_function([point.reshape(self.tensor_shape)])return loss_value.astype(np.float64)def gradients(self, point):return self.gradient_values.flatten().astype(np.float64)损失函数可以定义为特定卷积层的激活值之间的均方误差。 损失将在生成的图像和原始内容照片的层之间进行计算如下所示 mse_loss metrics.mean_squared_error(content_layer, target)可以通过考虑模型的输入来计算损耗的梯度如下所示 grads K.gradients(mse_loss, vgg_model.input)函数的输入是模型的输入输出将是损耗和梯度值的数组如下所示 cost_function K.function([vgg_model.input], [mse_loss]grads)此函数是确定性的要优化的因此不需要 SGD optimiser ConvexOptimiser(cost_function, content_image_shape)可以使用简单的优化程序来优化此函数因为它是凸的因此是确定性的。 我们还可以在迭代的每个步骤中保存图像。 我们将以可访问梯度的方式进行定义就像我们使用 scikit-learn 的优化程序进行最终优化一样。 注意该损失函数是凸的因此简单的优化器足以满足计算要求。 可以使用以下代码定义优化器 def optimise(optimiser, iterations, point, tensor_shape, file_name):for i in range(iterations):point, min_val, info fmin_l_bfgs_b(optimiser.loss, point.flatten(),fprimeoptimiser.gradients, maxfun20)point np.clip(point, -127, 127)print(Loss:, min_val)imsave(work_dir gen_file_name_{i}.png, add_imagenet_mean(point.copy(), tensor_shape)[0])return point优化器采用loss函数点和梯度然后返回更新。 需要使用以下代码生成随机图像以使内容损失最小化 def generate_rand_img(shape):return np.random.uniform(-2.5, 2.5, shape)/1 generated_image generate_rand_img(content_image_shape)这是创建的随机图像 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dm2O9pgG-1681567606708)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/bb7d0bd4-7167-43d7-938f-163330b4bfa5.png)] 该优化可以运行 10 次迭代以查看结果如下所示 iterations 10 generated_image optimise(optimiser, iterations, generated_image, content_image_shape, content)如果一切顺利那么在迭代过程中损失应如下图所示 Current loss value: 73.2010421753 Current loss value: 22.7840042114 Current loss value: 12.6585302353 Current loss value: 8.53817081451 Current loss value: 6.64649534225 Current loss value: 5.56395864487 Current loss value: 4.83072710037 Current loss value: 4.32800722122 Current loss value: 3.94804215431 Current loss value: 3.66387653351这是生成的图像现在它看起来几乎像只鸟。 可以运行优化以进行进一步的迭代以完成此操作 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cBcelz1F-1681567606709)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/6f9d1c9b-34ce-4c4b-ab82-4a67f76fb906.png)] 优化器拍摄图像并更新像素以使内容相同。 虽然效果较差但可以在一定程度上重现图像内容。 通过迭代获得的所有图像都很好地说明了图像的生成方式。 此过程不涉及批量。 在下一节中我们将看到如何以绘画风格创建图像。 使用 Gram 矩阵的样式损失 创建具有原始图像内容的图像后我们将看到如何仅使用样式创建图像。 样式可以认为是图像颜色和纹理的混合。 为此我们将定义样式损失。 首先我们将覆盖图像并将其转换为数组如以下代码所示 style_image Image.open(work_dir starry_night.png) style_image style_image.resize(np.divide(style_image.size, 3.5).astype(int32))这是我们加载的样式图像 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ej2Hc56M-1681567606709)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/1f67b6de-e5e1-461d-b515-a96915351fd5.png)] 现在我们将使用以下代码通过更改通道对该图像进行预处理 style_image_array subtract_imagenet_mean(np.expand_dims(style_image, 0)[:, :, :, :3]) style_image_shape style_image_array.shape为此我们将考虑以下几层就像我们在以下代码中所做的那样 model VGG16_Avg(include_topFalse, input_shapeshp[1:]) outputs {l.name: l.output for l in model.layers}现在我们将使用以下代码将多层作为前四个块的数组输出 layers [outputs[block{}_conv1.format(o)] for o in range(1,3)]现在创建一个新模型该模型可以使用以下代码输出所有这些层并分配目标变量 layers_model Model(model.input, layers) targs [K.variable(o) for o in layers_model.predict(style_arr)]使用 Gram 矩阵计算样式损失。 革兰氏矩阵是矩阵及其转置的乘积。 激活值可以简单地转置和相乘。 然后将此矩阵用于计算样式和随机图像之间的误差。 Gram 矩阵会丢失位置信息但会保留纹理信息。 我们将使用以下代码定义 Gram 矩阵 def grammian_matrix(matrix):flattened_matrix K.batch_flatten(K.permute_dimensions(matrix, (2, 0, 1)))matrix_transpose_dot K.dot(flattened_matrix, K.transpose(flattened_matrix))element_count matrix.get_shape().num_elements()return matrix_transpose_dot / element_count您可能现在已经知道它是一对列之间的相关性的度量。 高度和宽度尺寸被展平。 这不包括任何本地信息因为坐标信息被忽略。 样式损失计算输入图像的 Gram 矩阵与目标之间的均方误差如以下代码所示 def style_mse_loss(x, y):return metrics.mse(grammian_matrix(x), grammian_matrix(y))现在我们使用以下代码通过汇总各层的所有激活来计算损失 style_loss sum(style_mse_loss(l1[0], l2[0]) for l1, l2 in zip(style_features, style_targets)) grads K.gradients(style_loss, vgg_model.input) style_fn K.function([vgg_model.input], [style_loss]grads) optimiser ConvexOptimiser(style_fn, style_image_shape)然后通过创建随机图像以与以前相同的方式解决它。 但是这次我们还将应用高斯过滤器如以下代码所示 generated_image generate_rand_img(style_image_shape)生成的随机图像如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KD2ZUk68-1681567606709)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/6bf68978-98b1-449a-a813-639c4bda8b31.png)] 优化可以运行 10 次迭代以查看结果如下所示 generated_image optimise(optimiser, iterations, generated_image, style_image_shape)如果一切顺利求解器应打印类似于以下的损耗值 Current loss value: 5462.45556641 Current loss value: 189.738555908 Current loss value: 82.4192581177 Current loss value: 55.6530838013 Current loss value: 37.215713501 Current loss value: 24.4533748627 Current loss value: 15.5914745331 Current loss value: 10.9425945282 Current loss value: 7.66888141632 Current loss value: 5.84042310715这是生成的图像 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xWqYYk2B-1681567606709)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/097eec9d-b9f7-42b3-81db-c4d68781126e.png)] 在这里我们从随机噪声中创建了具有特定绘画风格的图像而没有任何位置信息。 在下一节中我们将看到如何结合使用-内容损失和样式损失。 风格迁移 现在我们知道了如何重建图像以及如何构建捕获原始图像样式的图像。 显而易见的想法可能是通过加权并添加两个loss函数来将这两种方法结合起来如以下代码所示 w,h style.size src img_arr[:,:h,:w]和以前一样我们将获取一系列层输出以计算样式损失。 但是我们仍然只需要一层输出来计算内容损失。 我们如何知道要抓哪一层 如前所述层越低内容重构将越精确。 在将内容重建与样式相结合时我们可以预期对内容进行更宽松的重建将为样式带来更大的影响空间例如灵感。 此外即使没有相同的细节后面的层也可以确保图像看起来像相同的主题。 以下代码用于此过程 style_layers [outputs[block{}_conv2.format(o)] for o in range(1,6)] content_name block4_conv2 content_layer outputs[content_name]现在使用以下代码使用所需的输出层创建一个单独的样式模型 style_model Model(model.input, style_layers) style_targs [K.variable(o) for o in style_model.predict(style_arr)]我们还将使用以下代码为具有内容层的内容创建另一个模型 content_model Model(model.input, content_layer) content_targ K.variable(content_model.predict(src))现在两种方法的合并就像合并它们各自的损失函数一样简单。 请注意与我们之前的函数相反此函数将产生三种不同类型的输出 一个用于原始图像一个用于模仿我们风格的图片一个用于训练像素的随机图像 我们调整重建方式的一种方法是更改​​内容损失系数此处为 1/10。 如果增加分母则样式将对图像产生较大影响而如果太大则非结构化样式将掩盖图像的原始内容。 同样如果它太小则图像将没有足够的样式。 我们将在此过程中使用以下代码 style_wgts [0.05,0.2,0.2,0.25,0.3] loss函数同时包含样式和内容层如下所示 loss sum(style_loss(l1[0], l2[0])*wfor l1,l2,w in zip(style_layers, style_targs, style_wgts)) loss metrics.mse(content_layer, content_targ)/10 grads K.gradients(loss, model.input) transfer_fn K.function([model.input], [loss]grads) evaluator Evaluator(transfer_fn, shp)我们将使用以下代码像以前一样运行求解器 10 次迭代 iterations10 x rand_img(shp) x solve_image(evaluator, iterations, x)损耗值应按如下所示打印 Current loss value: 2557.953125 Current loss value: 732.533630371 Current loss value: 488.321166992 Current loss value: 385.827178955 Current loss value: 330.915924072 Current loss value: 293.238189697 Current loss value: 262.066864014 Current loss value: 239.34185791 Current loss value: 218.086700439 Current loss value: 203.045211792这些结果是惊人的。 他们每个人都以艺术家的风格来完成原始图像的复制工作。 生成的图像如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F5f3I1Ay-1681567606710)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/fe01f255-d682-4f67-8612-b692af48dd95.png)] 现在我们将结束样式转换部分。 此操作确实很慢但可以处理任何图像。 在下一节中我们将看到如何使用类似的想法来创建超分辨率网络。 有几种方法可以改善这种情况例如 将高斯滤镜添加到随机图像为层添加不同的权重可以使用不同的层和权重来满足初始化图像而不是随机图像颜色可以保存掩码可以用于指定所需的内容任何草图都可以转换为绘画绘制草图并创建图像 通过训练 CNN 输出任何图像都可以将其转换为艺术风格。 生成对抗网络 生成对抗网络GAN由 Ian Goodfellow 于 2014 年发明。这是一种无监督算法其中两个神经网络被训练为判别器和生成器。 同时。 该技术可以根据随机噪声生成图像判别器可以评估是否为原始图像。 经过进一步训练后生成器网络可以生成逼真的图像。 生成器网络通常是反卷积神经网络而判别器是卷积神经网络。 理解这一点的一个很好的类比是将生成器看作是伪造钱币的人而将判别器看作是确定钱币是否为假币的警察。 生成器会根据警察的反馈不断提高伪钞的质量直到警察无法区分伪钞和伪钞。 现在让我们从实现开始。 原始 GAN 原始 GAN 称为原始 GAN 。 在构建模型之前让我们定义一些对本章其余部分有用的层。 以下是convolutional_layers其中添加了泄漏激活和正则化 def convolution_layer(input_layer,filters,kernel_size[4, 4],activationtf.nn.leaky_relu):layer tf.layers.conv2d(inputsinput_layer,filtersfilters,kernel_sizekernel_size,activationactivation,kernel_regularizertf.nn.l2_loss,bias_regularizertf.nn.l2_loss,)add_variable_summary(layer, convolution)return layer接下来我们将使用以下代码定义与带有正则化的convolution_layer相反的transpose_convolution_layer def transpose_convolution_layer(input_layer,filters,kernel_size[4, 4],activationtf.nn.relu,strides2):layer tf.layers.conv2d_transpose(inputsinput_layer,filtersfilters,kernel_sizekernel_size,activationactivation,stridesstrides,kernel_regularizertf.nn.l2_loss,bias_regularizertf.nn.l2_loss,)add_variable_summary(layer, convolution)return layer接下来我们将使用以下代码定义一个具有非线性激活的密集层 def dense_layer(input_layer,units,activationtf.nn.relu):layer tf.layers.dense(inputsinput_layer,unitsunits,activationactivation)add_variable_summary(layer, dense)return layer现在我们将定义一个生成器该生成器将噪声作为输入并变为图像。 生成器由几个全连接层组成然后是转置卷积层以对噪声进行上采样。 最后提出了卷积层以使噪声成为单个通道。 每层之间都有批量归一化层以使梯度平滑流动。 我们将使用以下代码定义生成器 def get_generator(input_noise, is_trainingTrue):generator dense_layer(input_noise, 1024)generator tf.layers.batch_normalization(generator, trainingis_training)generator dense_layer(generator, 7 * 7 * 256)generator tf.layers.batch_normalization(generator, trainingis_training)generator tf.reshape(generator, [-1, 7, 7, 256])generator transpose_convolution_layer(generator, 64)generator tf.layers.batch_normalization(generator, trainingis_training)generator transpose_convolution_layer(generator, 32)generator tf.layers.batch_normalization(generator, trainingis_training)generator convolution_layer(generator, 3)generator convolution_layer(generator, 1, activationtf.nn.tanh)return generator现在我们将定义 GAN 的判别器部分该部分可拍摄图像并尝试区分假冒商品和真实形象。 判别器是一个规则的卷积网络上面有几个convolutional_layers其后是致密层。 批归一化层位于层之间。 我们将使用以下代码来定义鉴别符 def get_discriminator(image, is_trainingTrue):x_input_reshape tf.reshape(image, [-1, 28, 28, 1],nameinput_reshape)discriminator convolution_layer(x_input_reshape, 64)discriminator convolution_layer(discriminator, 128)discriminator tf.layers.flatten(discriminator)discriminator dense_layer(discriminator, 1024)discriminator tf.layers.batch_normalization(discriminator, trainingis_training)discriminator dense_layer(discriminator, 2)return discriminator创建判别器后我们将使用以下代码创建一个噪声向量该噪声向量将作为生成器的输入 input_noise tf.random_normal([batch_size, input_dimension])可以使用 TensorFlow 中的tf.contrib.gan模块创建 GAN 模型。 它采用了生成器和判别器方法及其相应的输入如下所示 gan tf.contrib.gan.gan_model(get_generator,get_discriminator,real_images,input_noise)现在可以使用以下代码从gan_train方法开始训练该方法将gan_train_ops方法带给生成器和判别器以损失并对优化器进行优化并使用以下代码 tf.contrib.gan.gan_train(tf.contrib.gan.gan_train_ops(gan,tf.contrib.gan.gan_loss(gan),tf.train.AdamOptimizer(0.001),tf.train.AdamOptimizer(0.0001)))通过运行此命令将创建可从随机向量输出图像的 GAN 模型。 生成的图像不受限制可以来自任何标签。 在下一节中我们将使用条件 GAN 生成所需的输出。 条件 GAN 有条件的 GAN 生成带有所需标签的图像。 例如我们可以要求模型生成数字 8而模型将生成数字 8。为此需要标签以及使用模型训练的噪声如下所示 gan tf.contrib.gan.gan_model(get_generator,get_discriminator,real_images,(input_noise, labels))其余的训练与原始 GAN 相似。 接下来我们将使用 GAN 压缩图像。 对抗损失 对抗性损失是来自生成器的损失。 该损失可以与伪图像和真实图像之间的逐像素损失相结合以形成组合的对抗性损失。 GAN 模型必须随real_images一起提供给生成器和判别器如下所示 gan tf.contrib.gan.gan_model(get_autoencoder,get_discriminator,real_images,real_images)生成器是一个自编码器。 可以在第 3 章“图像检索”中找到该实现。 此后我们将使用以下代码定义损失 loss tf.contrib.gan.gan_loss(gan, gradient_penalty1.0)l1_pixel_loss tf.norm(gan.real_data - gan.generated_data, ord1)loss tf.contrib.gan.losses.combine_adversarial_loss(loss, gan, l1_pixel_loss, weight_factor1)GAN 损失的梯度是不利的。 然后计算逐像素损失并将其添加到损失的损失中。 训练此模型将创建一个功能强大的自编码器可用于图像压缩。 图片转换 正如我们在应用部分中所了解的可以将一个图像转换为另一个图像。 输入图像被提供给判别器而目标图像被提供给生成器同时创建 GAN 模型如下所示 gan tf.contrib.gan.gan_model(get_generator,get_discriminator,real_images,input_images)除像素级损失外最小二乘损失也用于训练模型。 可以使用以下代码进行计算 loss tf.contrib.gan.gan_loss(gan,tf.contrib.gan.losses.least_squares_generator_loss,tf.contrib.gan.losses.least_squares_discriminator_loss)l1_loss tf.norm(gan.real_data - gan.generated_data, ord1)gan_loss tf.contrib.gan.losses.combine_adversarial_loss(loss, gan, l1_loss, weight_factor1)使用此技术可以将一个图像转换为另一个图像。 InfoGAN InfoGAN 无需任何明确的监督训练即可生成所需标签的图像。 infogan_model接受非结构化和结构化的输入如以下代码所示 info_gan tf.contrib.gan.infogan_model(get_generator,get_discriminator,real_images,unstructured_input,structured_input)loss tf.contrib.gan.gan_loss(info_gan,gradient_penalty_weight1,gradient_penalty_epsilon1e-10,mutual_information_penalty_weight1)由于训练不稳定因此将损失定义为罚款。 增加罚分可以在训练过程中提供更大的稳定性。 GAN 的缺点 GAN 生成的图像具有一些缺点例如计数透视图和全局结构。 当前正在广泛研究以改进模型。 视觉对话模型 视觉对话模型VDM可以基于图像进行聊天。 VDM 应用了计算机视觉自然语言处理NLP和聊天机器人的技术。 它发现了主要的应用例如向盲人解释图像向医生解释医学扫描虚拟伴侣等。 接下来我们将看到解决这一难题的算法。 VDM 算法 Lu 等人提出了此处讨论的算法。 Lu 等人提出了基于 GAN 的 VDM。 生成器生成答案判别器对这些答案进行排名。 以下是该过程的示意图 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RiBygKFW-1681567606710)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/d64d01f5-a996-4063-aac0-a64fec3d0e15.png)] 基于 GAN 技术的 VDM 架构[摘自 Lu 等人] 聊天历史当前问题和图像将作为输入提供给生成器。 接下来我们将看到生成器如何工作。 生成器 生成器具有编码器和解码器。 编码器将图像问题和历史记录作为输入。 编码器首先关注 LSTM 的历史记录并关注图像的输出。 流程如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-esRzbHjp-1681567606710)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/f1aed34d-d664-451a-a18e-50148eb5990b.png)] 转载自 Lu 等人 整个历史记录都可用并且 LSTM 记录了聊天的历史记录。 输出伴随有产生嵌入的图像。 编码器生成的嵌入被解码器用来创建答案。 解码器由 RNN 制成。 编码器和解码器一起形成生成器生成可能的答案。 接下来我们将了解判别器的工作原理。 判别器 判别器从生成器获取生成的序列并对其进行排序。 排名是通过对 n 对损失学习的嵌入完成的。 n 对损失类似于三元组损失不同之处在于使用几对正负对进行比较。 这是该模型产生的一些结果。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fkGtyoDC-1681567606711)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/981124a1-6d73-4233-a453-f44e7861a98e.png)] 转载自 Lu 等人 结果是合理的并且比简单的判别器产生的结果更好。 总结 在本章中我们了解了生成模型和大量应用。 我们实现它们是为了在保留内容的同时将样式从一种转换为另一种。 我们看到了 GAN 背后的直觉和经过训练的模型可以做到这一点。 最后我们了解了视觉对话系统。 在下一章中我们将学习用于视频分析的深度学习方法。 我们将看到如何通过摄像机文件等访问视频内容。 我们将通过在帧级别和整个视频上应用分类来实现视频分类。 稍后我们将看到如何跟踪视频中的对象。 九、视频分类 在本章中我们将看到如何训练视频数据的深度学习模型。 我们将开始按帧对视频进行分类。 然后我们将使用时间信息以获得更好的准确率。 稍后我们将图像的应用扩展到视频包括姿势估计字幕和生成视频。 在本章中我们将涵盖的以下主题 视频分类的数据集和算法将视频分成帧并分类在单个框架级别上训练视觉特征模型了解 3D 卷积及其在视频中的使用在视频上合并运动向量将时间信息用于目标跟踪人体姿势估计和视频字幕等应用 了解视频和分类 视频不过是一系列图像。 视频沿时间方向为图像带来了新的维度。 图像的空间特征和视频的时间特征可以放在一起比仅图像提供更好的结果。 额外的维度还导致大量空间因此增加了训练和推理的复杂性。 用于处理视频的计算需求非常高。 视频还改变了深度学习模型的架构因为我们必须考虑时间特征。 视频分类是用类别标记视频的任务。 类别可以在帧级别也可以在整个视频中。 视频中可能有执行的动作或任务。 因此视频分类可以标记视频中存在的对象或标记视频中发生的动作。 在下一部分中我们将看到用于视频分类任务的可用数据集。 探索视频分类数据集 视频分类是视频数据研究的主要问题。 拍摄了几个视频并标记了与数据相关的各种对象或动作。 数据集根据大小质量和标签类型而有所不同。 有些甚至包括多个视频标签。 这些视频通常很短。 长视频可能会执行各种操作因此可以在分别对剪切的视频片段或摘要进行分类之前在时间上进行分割。 接下来我们将考虑一些特定数据集的细节。 UCF101 佛罗里达中部大学UCF101是用于动作识别的数据集。 这些视频是在 YouTube 上收集的由逼真的动作组成。 此数据集中有 101 个操作类别。 还有另一个名为 UCF50 的数据集它具有 50 个类别。 整个动作中该数据集中有 13,320 个视频。 这些视频具有背景比例姿势遮挡和照明条件的多种变化。 动作类别分为 25 个它们具有相似的变化例如背景姿势比例视点照明等。 动作和每个动作的视频数显示如下 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZAvEJWHK-1681567606711)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/fa184ce6-4c4f-4e4e-9eb0-46906bd0b009.png)] 来源 所有 101 个动作都分为五种类型的动作如下所示人与对象的交互身体动作人与人的交互演奏乐器和运动。 数据集和标注可从这里下载。 接下来我们将了解 YouTube-8M 数据集。 YouTube-8M YouTube-8M 数据集用于视频分类问题。 数据集包含带有标签和视觉特征的视频 URL。 以下是有关数据集的一些统计信息 视频 URL 的数量700 万影片剪辑的时长450,000类标签的数量4,716每个视频的平均标签数3.4 以下是各种类型的数据集摘要 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-69ztyZV6-1681567606711)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/53ee0eb1-cef3-4906-84ef-e972b7792a36.png)] 来源 前面的图像可以让您一眼看出数据集中可用的标签类型。 视频数据很大因此视觉特征被计算并随数据集一起提供。 可以通过以下链接访问数据集。 其他数据集 还有更多的数据集可用于视频分类问题。 以下是更多数据集的详细信息 Sports-1M拥有 1,133,158 个具有 487 个类别的视频。 标注是自动完成的。 数据集可以从以下位置下载。UCF-11佛罗里达大学-11拥有 1,600 部视频包含 11 动作。 视频的速度为 29.97 fps每秒帧数。 数据集可以与UCF101一起下载。HMDB-51人体运动数据库-51包含 5,100 个具有 51 个动作的视频。 数据集在这里。Hollywood2拥有 12 个动作的 1,707 个视频。 数据集在这里。 我们已经看到了可用于视频分类任务的数据集以及描述和访问链接。 接下来我们将看到如何加载视频并将其拆分为帧以进行进一步处理。 将视频分成帧 视频可以转换为帧并保存在目录中以备将来使用。 分成帧可以通过在训练过程之前对视频进行解压缩来帮助我们节省时间。 首先让我们看一下将视频转换为帧的代码片段 import cv2 video_handle cv2.VideoCapture(video_path) frame_no 0 while True:eof, frame video_handle.read()if not eof:breakcv2.imwrite(frame%d.jpg % frame_no, frame)frame_no 1使用此代码段所有前面的数据集都可以转换为帧。 请注意这将需要大量的硬盘空间。 视频分类方法 视频必须针对几种应用进行分类。 由于视频中包含大量数据因此还必须考虑训练和推理计算。 所有视频分类方法均受图像分类算法启发。 VGGInception 等标准架构用于帧级别的特征计算然后进行进一步处理。 诸如 CNN注意先前章节中学习的和 LSTM 之类的概念将在此处有用。 直观地以下方法可用于视频分类 提取帧并使用在第 2 章“图像分类”中学习的模型以帧为基础进行分类。提取在第 3 章“图像检索”中学习的图像特征并且可以按照第 7 章“图像标题”中的描述使用这些特征训练 RNN。在整个视频上训练 3D 卷积网络。 3D 卷积是 2D 卷积的扩展 我们将在以下各节中详细了解 3D 卷积的工作原理。使用视频的光流可以进一步提高精度。 光流是对象运动的模式我们将在接下来的部分中详细介绍。 我们将看到几种算法它们在各种计算复杂性上都具有良好的准确率。 可以通过将数据集转换为帧并将其子采样为相同的长度来准备它。 一些预处理会有所帮助例如减去 Imagenet 的均值。 为视频分类融合并行 CNN 就帧而言由于图像的下采样视频的预测可能不会产生良好的结果从而丢失了精细的细节。 使用高分辨率的 CNN 将增加推理时间。 因此Karpathy 等人建议融合两个流它们并行运行视频分类。 进行逐帧预测有两个问题即 由于较大的 CNN 架构预测可能需要很长时间独立的预测会沿时间维度丢失信息 使用更少的参数和两个并行运行的较小编码器可以简化架构。 视频同时通过两个 CNN 编码器传递。 一个编码器需要较低的分辨率并要处理高分辨率。 编码器具有交替的卷积规范化和合并层。 两个编码器的最后一层通过全连接层连接。 另一个编码器具有相同的大小但仅进行中心裁剪如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L8065AVH-1681567606711)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/1f34b3d0-4e01-4ed2-a5fa-da513c7a1155.png)] 转载自 Karpathy 等人 帧的并行处理通过对视频进行下采样来加快运行时间。 CNN 架构的参数减半同时保持相同的精度。 这两个流称为中央凹和上下文。 以下代码段显示了流 high_resolution_input tf.placeholder(tf.float32, shape[None, input_size]) low_resolution_input tf.placeholder(tf.float32, shape[None, input_size]) y_input tf.placeholder(tf.float32, shape[None, no_classes]) high_resolution_cnn get_model(high_resolution_input) low_resolution_cnn get_model(low_resolution_input) dense_layer_1 tf.concat([high_resolution_cnn, low_resolution_cnn], 1) dense_layer_bottleneck dense_layer(dense_layer_1, 1024) logits dense_layer(dense_layer_bottleneck, no_classes)下图显示了跨时间维度进行处理的帧 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KwqFvPne-1681567606711)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/d2211390-ff79-43d4-9b7e-842c29b2b66c.png)] 转自 Karpathy 等人 可以在不同的时间观看视频而不是通过固定大小的剪辑。 在前面的图像中介绍了连接时间信息的三种方式。 后期融合需要更长的时间框架而早期融合则需要几个帧。 慢速融合将后期融合和早期融合结合在一起可获得良好效果。 该模型在Sports1M数据集上进行了训练该数据集具有 487 个类别并达到了 50% 的准确率。 将同一模型应用于UCF101时可达到 60% 的精度。 长时间视频的分类 融合方法适用于短视频片段。 分类较长的视频很困难因为必须计算和记住很多帧。 Ng 等人提出了两种对较长视频进行分类的方法 第一种方法是在时间上合并卷积特征。 最大池用作函数aggregation方法。第二种方法是使用 LSTM 连接处理各种可变长度视频的卷积特征。 下图显示了这两种方法 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2fi1NXt7-1681567606712)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/1fc508d4-5f43-4908-aa11-13d9e0a2b336.png)] 摘自 Ng 等人 可以提取 CNN 特征并将其馈送到小型 LSTM 网络如以下代码所示 net tf.keras.models.Sequential() net.add(tf.keras.layers.LSTM(2048,return_sequencesFalse,input_shapeinput_shape,dropout0.5)) net.add(tf.keras.layers.Dense(512, activationrelu)) net.add(tf.keras.layers.Dropout(0.5)) net.add(tf.keras.layers.Dense(no_classes, activationsoftmax))添加 LSTM 进行特征池化可提供更好的表现。 特征以各种方式合并如下图所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yHSxVrC4-1681567606712)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/72c1430c-6604-4c17-abe6-133fe2d4daa9.png)] 摘自 Ng 等人 如图所示卷积特征可以几种不同的方式聚合。 池在全连接层之前完成。 该方法在Sports1M数据集和UCF101数据集中的准确率分别为 73.1% 和 88.6%。 下图显示了 LSTM 方法 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MEcS08Qm-1681567606712)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/bc029064-479f-4788-8aec-077b933fe468.png)] 摘自 Ng 等人 该模型的计算量很高因为使用了多个 LSTM。 为动作识别流式连接两个 CNN 视频中对象的运动具有有关视频中执行的动作的非常好的信息。 对象的运动可以通过光流来量化。 Simonyan 和 Zisserman 提出了一种用于动作识别的方法该方法使用来自图像和光流的两个流。 光流通过量化观察者与场景之间的相对运动来测量运动。 可以在这里找到有关光流的详细讲座。 通过运行以下命令可以获得光流 p1, st, err cv2.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None, **lk_params)一个流采用单个帧并使用常规 CNN 预测动作。 另一个流获取多个帧并计算光流。 光流通过 CNN 进行预测。 下图显示了这两个预测 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2oGitwVS-1681567606713)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/ef8e4e07-e018-48ba-b82d-53613dddb8e8.png)] 转载自 Simonyan 和 Zisserman 两种预测都可以与最终预测结合。 使用 3D 卷积的时间学习 可以使用 3D 卷积对视频进行分类。 3D 卷积运算将体积作为输入并输出而 2D 卷积可以将 2D 或体积输出并输出 2D 图像。 区别如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zoqbp6o5-1681567606713)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/0e8faa5c-11ae-4631-b717-bcab34d2e075.png)] 复制自 Tran 等人 前两个图像属于 2D 卷积。 输出始终是图像。 同时3D 卷积输出一个体积。 区别在于内核在 3 个方向上进行卷积运算。 Tran 等人将 3D 卷积用于视频分类。 3D 卷积模型如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V6s0kUyv-1681567606713)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/f2f9bf9d-7ffd-4229-b5cf-0b90cbf076a1.png)] 复制自 Tran 等人 以下是使用 3D 卷积的模型代码片段 net tf.keras.models.Sequential() net.add(tf.keras.layers.Conv3D(32,kernel_size(3, 3, 3),input_shape(input_shape))) net.add(tf.keras.layers.Activation(relu)) net.add(tf.keras.layers.Conv3D(32, (3, 3, 3))) net.add(tf.keras.layers.Activation(softmax)) net.add(tf.keras.layers.MaxPooling3D()) net.add(tf.keras.layers.Dropout(0.25))net.add(tf.keras.layers.Conv3D(64, (3, 3, 3))) net.add(tf.keras.layers.Activation(relu)) net.add(tf.keras.layers.Conv3D(64, (3, 3, 3))) net.add(tf.keras.layers.Activation(softmax)) net.add(tf.keras.layers.MaxPool3D()) net.add(tf.keras.layers.Dropout(0.25))net.add(tf.keras.layers.Flatten()) net.add(tf.keras.layers.Dense(512, activationsigmoid)) net.add(tf.keras.layers.Dropout(0.5)) net.add(tf.keras.layers.Dense(no_classes, activationsoftmax)) net.compile(losstf.keras.losses.categorical_crossentropy,optimizertf.keras.optimizers.Adam(), metrics[accuracy])3D 卷积需要大量的计算能力。 3D 卷积在Sports1M数据集上达到 90.2% 的精度。 使用轨迹的分类 Wang 等人使用身体各部分的轨迹对所执行的动作进行分类。 这项工作结合了手工制作和深度学习的特征可以进行最终预测。 以下是分类的表示形式 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jNkiYSnD-1681567606713)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/fa390d0d-4a3e-48af-8fe6-4896c092d2e9.png)] 转载自 Wang 等人 手工制作的特征是 Fisher 向量这些特征来自 CNN。 下图演示了轨迹和特征图的提取 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2JnsP48z-1681567606719)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/389aa340-de61-4803-baaf-6e3b78b659f3.png)] 转载自 Wang 等人 轨迹和特征图都在时间上组合在一起以形成关于时间片段的最终预测。 多模态融合 杨等人提出了一种具有 4 个模型的多模态融合视频分类方法。 这四个模型分别是 3D 卷积特征2D 光流3D 光流和 2D 卷积特征。 该方法的数据流如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mG71Y5c4-1681567606719)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/9b6f98f2-2e75-4ebb-b40e-ac265467545f.png)] 转载自 Yang 等人 现在让我们了解 Convlet 。 Convlet 是来自单个内核的小卷积输出。 下图显示了 convlet 对卷积层中空间权重的学习 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1FJRcgDc-1681567606720)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/e258e5ea-f039-40f2-b79f-4fa0df3a7b55.png)] 转载自 Yang 等人 空间权重指示卷积层中局部空间区域的区分度或重要性。 下图是在多层卷积层和全连接层上完成的多层表示融合的图示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qzqKs7mh-1681567606720)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/b4160338-5686-48dd-a31a-f6c07404edcc.png)] 转载自 Yang 等人 增强机制用于组合预测。 提升是一种可以将多个模型预测组合为最终预测的机制。 用于分类的注意力区域 注意力机制可以用于分类。 注意力机制复制了人类专注于识别活动区域的行为。 注意力机制赋予某些区域比其他区域更多的权重。 训练时从数据中学习权重方法。 注意力机制主要有两种即 柔和注意力性质确定因此可以通过反向传播来学习。硬注意力性质随机这需要复杂的学习机制。 由于需要采样数据因此也很昂贵。 以下是软关注的可视化 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ADd1KFmT-1681567606720)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/5c514fb5-7f01-4436-90e9-65ced3ea1f90.png)] 转载自 Sharma 等人 根据注意计算并加权 CNN 特征。 对某些区域的关注或权重可以用于可视化。 Sharma 等人使用此想法对视频进行分类。 LSTM 被用作卷积特征。 LSTM 通过注意以下帧来预测区域如下图所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f2wCEe7Y-1681567606720)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/c835ef24-72c0-4144-9fd8-890500f2c8ac.png)] 转自 Sharma 等人。 每个 LSTM 栈都会预测位置和标签。 每个栈具有三个 LSTM 。 LSTM 栈的输入是卷积特征立方体和位置。 位置概率是注意权重。 注意的使用提高了准确率以及可视化预测的方法。 我们已经看到了各种视频分类方法。 接下来我们将学习视频中的其他应用。 将基于图像的方法扩展到视频 图像可用于姿势估计样式转换图像生成分割字幕等等。 同样这些应用也在视频中找到位置。 使用时间信息可以改善来自图像的预测反之亦然。 在本节中我们将看到如何将这些应用扩展到视频。 人体姿势回归 人体姿势估计是视频数据的重要应用可以改善其他任务例如动作识别。 首先让我们看一下可用于姿势估计的数据集的描述 PosesInTheWild 数据集包含 30 个带有人体姿势标注的视频。 数据集在这里。 该数据集带有人类上半身关节的标注。电影院中标记的帧FLIC从 30 部电影中获得的人体姿势数据集可在以下位置找到。 Pfister 等人提出了一种预测视频中人体姿势的方法。 以下是回归人体姿势的流水线 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eHArsFEx-1681567606721)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/59d379eb-94cf-453c-aeac-28b1a04e6e44.png)] 复制自 Pfister 等人 视频中的帧被获取并通过卷积网络。 融合层并获得姿势热图。 姿势热图与光流结合以获得扭曲的热图。 合并时间范围内的扭曲热图以生成合并的热图得到最终姿势。 跟踪人脸标志 视频中的人脸分析需要人脸检测界标检测姿势估计验证等。 计算地标对于捕获人脸动画人机交互和人类活动识别尤其重要。 除了在帧上进行计算外还可以在视频上进行计算。 Gu 等人提出了一种使用视频中的人脸标志的检测和跟踪的联合估计的 RNN 方法。 结果优于逐帧预测和其他先前模型。 地标由 CNN 计算时间方面在 RNN 中编码。 综合数据用于训练。 分割视频 使用时间信息时可以更好地分割视频。 加德Gadde等人提出了一种通过扭曲来组合时间信息的方法。 下图演示了该解决方案该方法将两个帧分段并且结合了变形 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h3VDACVw-1681567606721)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/0d1ae328-95c8-4794-b8a4-196046e5f578.png)] 转载自 Gadde 等人 下图显示了翘曲网 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dFPExXOg-1681567606721)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/8c759f74-da66-4844-a5d5-66369605ba25.png)] 转载自 Gadde 等人 在两个帧之间计算光流将它们与变形结合在一起。 变形模块获取光流对其进行转换然后将其与变形的表示相结合。 生成视频字幕 第 7 章“图像字幕生成”说明了几种组合文本和图像的方法。 同样可以为视频生成字幕以描述上下文。 让我们看一下可用于字幕视频的数据集列表 微软研究 - 视频转文本MSR-VTT具有 200,000 个视频剪辑和句子对。 可以从以下网站获取更多详细信息。MPII 电影描述语料库MPII-MD可以从以下网站获取。 它有 68,000 个句子和 94 部电影。蒙特利尔视频标注数据集M-VAD可从以下网站获得。它有 49,000 个剪辑。YouTube2Text 包含 1,970 个视频包含 80,000 个描述。 姚等人提出了一种为视频添加字幕的方法。 经过训练以进行动作识别的 3D 卷积网络用于提取局部时间特征。 然后在特征上使用注意力机制以使用 RNN 生成文本。 该过程如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VJSTuyeW-1681567606721)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/71cfe3d2-2787-4234-a683-8ca292510133.png)] 转载自 Yao 等人 Donahue 等人提出了另一种视频字幕或描述方法该方法将 LSTM 与卷积特征组合。 这类似于前面的方法除了我们在此处使用 2D 卷积特征如下图所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-56xaszzd-1681567606722)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/fe273a12-ded0-4027-b3d1-0657dee35178.png)] 摘自 Donahue 等人 我们有几种将文本与图像结合起来的方法例如活动识别图像描述和视频描述技术。 下图说明了这些技术 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eJl9W1Tr-1681567606722)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/37ba89c5-80e9-4655-8e8f-9e664ddd5b29.png)] 摘自 Donahue 等人 Venugopalan 等人提出了一种使用编码器-解码器方法进行视频字幕的方法。 以下是他提出的技术的可视化 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7SiuthUQ-1681567606722)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/6935b3c7-f3bb-4876-a3d5-f6f6559d7e05.png)] 复制自 Venugopalan 等人 对于此方法可以在图像的帧或光流上计算 CNN。 生成视频 可以使用生成模型以无监督的方式生成视频。 可以使用当前帧预测未来的帧。 Ranzato 等人提出了一种受语言模型启发的视频生成方法。 RNN 模型用于拍摄图像补丁并预测下一个补丁。 总结 在本章中我们涵盖了与视频分类有关的各种主题。 我们看到了如何将视频拆分为帧以及如何将图像中的深度学习模型用于各种任务。 我们介绍了一些特定于视频的算法例如跟踪对象。 我们看到了如何将基于视频的解决方案应用于各种场景例如动作识别手势识别安全应用和入侵检测。 在下一章中我们将学习如何将上一章中训练有素的模型部署到各种云和移动平台上的生产环境中。 我们将看到不同的硬件如何影响延迟和吞吐量方面的性能。 十、部署 在本章中我们将学习如何在各种平台上部署经过训练的模型以实现最大吞吐量和最小延迟。 我们将了解 GPU 和 CPU 等各种硬件的性能。 我们将遵循在 Amazon Web ServicesGoogle Cloud Platform 等平台以及 AndroidiOS 和 Tegra 等移动平台上部署 TensorFlow 的步骤。 我们将在本章介绍以下主题 了解影响深度学习模型训练和推理性能的因素通过各种方法提高性能查看各种硬件的基准并学习调整它们以实现最佳性能的步骤将各种云平台用于部署将各种移动平台用于部署 模型表现 性能对于深度学习模型的训练和部署都很重要。 由于大数据或大模型架构训练通常需要更多时间。 结果模型可能更大因此在 RAM 受限的移动设备中使用时会出现问题。 更多的计算时间导致更多的基础架构成本。 推理时间在视频应用中至关重要。 由于前面提到了性能的重要性因此在本节中我们将研究提高性能的技术。 降低模型复杂度是一个简单的选择但会导致精度降低。 在这里我们将重点介绍一些方法这些方法可以提高性能而准确率却没有明显的下降。 在下一节中我们将讨论量化选项。 量化模型 深度学习模型的权重具有 32 位浮点值。 当权重量化为 8 位时精度下降很小因此在部署中不会注意到。 结果权重的精度似乎对深度学习模型的精度性能影响较小。 这个想法对深度学习很有趣并且在模型大小变得至关重要时很有用。 通过用 8 位值替换 32 位浮点值可以显着减小模型大小并提高推理速度。 实现模型量化时有很多选择。 权重可以存储在 8 位中但推理操作可以以 32 位浮点值执行。 架构的每个组件在量化大小上的行为可能有所不同因此取决于层可以选择 32 或 16 或 8 位值。 量化工作有多种原因。 通常深度学习模型经过训练可以解决图像中的噪声因此可以被认为是健壮的。 推理计算可以具有冗余信息并且可以由于量化而去除冗余信息。 最新的 CPU 和 RAM 硬件已针对浮点计算进行了调整因此在此类硬件中量化效果可能不太明显。 随着为此目的引入越来越多的硬件这种情况正在改变。 在 GPU 中由于内存和速度现已适应较低的精确浮点运算因此它们在内存和速度上存在明显差异。 还有其他特殊硬件可用于运行不太精确的浮动操作。 MobileNet 霍华德Howard和其他人引入了一种称为 MobileNets 的新型模型可用于移动和嵌入式应用。 MobileNets 可以用于不同的应用例如对象检测地标识别人脸属性细粒度分类如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ths9OjWO-1681567606722)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/f363f9cf-4786-41e0-9812-d49b4c26039a.png)] 转载自霍华德等人 MobileNets 通过用深度b和点向卷积c替换标准卷积过滤器a和点卷积c来减少模型的大小和计算量如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qVagXF2P-1681567606723)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/dab9c6a5-cbd9-485e-8e96-832c17bedf0a.png)] 转载自霍华德等人 批量归一化和激活层被添加到深度和点积卷积中如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ElzbFibM-1681567606723)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/4ee8ae67-9658-480e-a775-5b6f45033be8.png)] 转载自霍华德等人 有两个参数会影响模型的选择 乘法和加法次数精度和多加法之间的权衡如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yNI3vvU1-1681567606723)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/9f6fad9e-9ab5-405c-a5ac-8958cb342906.png)] 转载自霍华德等人 模型中的参数数量此处显示权衡 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FM4xddUX-1681567606723)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/5a370687-9b2b-4f57-80fd-87792fdfae85.png)] 转载自霍华德等人 MobileNets 已显示可以在移动和嵌入式设备上使用的精度有所降低的情况下可以减少模型的计算和尺寸。 在霍华德等人的文章中可以看到模型与精度之间的确切权衡。 云端部署 必须将这些模型部署在云中以用于多个应用。 我们将为此目的寻找主要的云服务提供商。 AWS Amazon Web ServicesAWS将支持扩展到基于 TensorFlow 的模型的开发和部署。 在 Amazon 上注册 AWS然后选择 Amazon 机器映像AMI之一。 AMI 是安装了所有必需软件的计算机的映像。 您不必担心安装包。 AWS 提供了深度学习 AMIDLAMI以简化训练和部署深度学习模型。 有几种选择。 在这里我们将使用 Conda因为它带有运行 TensorFlow 所需的几个包。 Python 有两个选项版本 2 和版本 3。以下代码将在 CUDA 8 的 Python 3 上使用 Keras 2 激活 TensorFlow source activate tensorflow_p36以下代码将在 CUDA 8 的 Python 2 上使用 Keras 2 激活 TensorFlow source activate tensorflow_p27您可以访问这里了解更多详细信息和教程。 还可以通过执行以下给定的步骤来启动虚拟机VM 转到 Amazon AWS然后使用您的 Amazon 帐户登录。从登录页面选择虚拟机来启动 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hHm8i3X7-1681567606723)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/d8d35771-0127-4f5f-9f7a-37edc6eb0c1c.png)] 在下一个窗口中单击入门选择 EC2 实例如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vIN0d8ti-1681567606724)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/cf4ce914-ae52-4a17-968d-206854461304.png)] 为 EC2 实例命名 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iZZdthQS-1681567606724)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/afc41e92-9559-4fb0-9214-91b3d9902bf4.png)] 选择操作系统的类型 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5miBjFxx-1681567606724)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/5d91face-5671-4648-93fd-69708c41002b.png)] 选择实例类型。 实例类型指示 RAM 和 CPU 大小不同的配置类型。 也有两个选项可供选择。 选择实例类型然后单击“下一步”按钮 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KqV7TVJr-1681567606724)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/39eeaa24-3a0a-47d7-8e72-87048ae2d5f3.png)] 创建一个隐私增强型邮件安全证书PEM文件该文件将用于登录如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IU90M2MA-1681567606724)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/25ab45d2-9f98-4720-a642-03263e11295b.png)] 创建实例将花费一些时间最后将显示完成状态 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Udy6KsmY-1681567606725)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/06ba2432-c401-46c9-9046-5097bad8cbfc.png)] 接下来单击进入 EC2 控制台按钮 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ryQ3dFLL-1681567606725)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/973f1291-4651-47fd-b924-e999c5f583a6.png)] 现在将创建实例 单击连接按钮如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kHMoWQ7h-1681567606725)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/9c23756d-5135-44af-9f23-d59513e9d581.png)] 接下来必须将实例连接到虚拟机的命令提示符。 连接所需的说明在此步骤中给出。 您需要在之前的步骤中下载 PEM 文件。 按照显示的说明连接到系统 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5ZSmOvcl-1681567606725)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/13ef9b43-6bd6-4ef3-a9e9-526f0a69c84e.png)] 完成后通过单击操作|实例状态|终止来终止实例 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-arowLqhP-1681567606726)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/c7b106a4-3f86-44a5-94fb-e8795643e0d2.png)] 安装和执行步骤可以遵循第 1 章“入门”。 Google Cloud Platform Google Cloud PlatformGCP是 Google 提供的云平台具有与 AWS 类似的功能。 通过执行以下步骤可以使用一个简单的虚拟机来训练诸如 AWS 之类的模型 使用 cloud.google.com 转到 Google Cloud Platform然后使用您的 Gmail 帐户登录到该平台。现在通过单击“转到控制台”按钮进入控制台 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3WszSMOn-1681567606726)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/b38e13e2-2b2a-45e4-841c-fc5feed34fcd.png)] 进入控制台后通过单击计算引擎进入 VM 创建页面。 右上角菜单中的 VM 实例如以下屏幕截图所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y1TQ3oz2-1681567606726)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/0a5622e5-c108-4b28-8960-1eab8e3d9574.png)] 然后单击CREATE INSTANCE按钮以创建所需的实例 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zV5Dmboz-1681567606726)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/0671e492-4e4b-4edd-8622-8208b096056e.png)] 接下来可以通过配置选择实例类型。 Zone 参数通知区域将部署实例。 通过选择靠近用户的区域可以节省等待时间。 可以使用所需的 RAM 和 CPU 定制机器类型。 还可以选择 GPU以进行更快的训练。 选择实例的大小然后单击“创建”按钮如以下屏幕截图所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0UaAmzjT-1681567606727)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/ae5b0924-3d17-4afa-9e63-baa8859245ba.png)] 创建实例将需要几分钟。 然后单击实例的 SSH 下拉列表然后选择“在浏览器窗口中打开”选项如下所示以在浏览器中打开控制台 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wL1nWEhF-1681567606727)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/783c512d-4692-4eeb-914d-9ff3f2d430b1.png)] 使用该外壳您可以安装 TensorFlow 并可以训练或部署模型。 有许多选项可从虚拟机的配置中选择。 根据成本和时间的权衡可以选择配置。 GCP 具有云机器学习引擎可在使用 TensorFlow 时为我们提供帮助。 GCP 的三个组件可以一起用于构建训练和部署基础架构 用于预处理图像的 Cloud DataFlow用于训练和部署模型的云机器学习引擎用于存储训练数据代码和结果的 Google Cloud Storage 可以在这个页面上找到使用云机器学习引擎建立自定义图像分类模型的出色教程。 在设备中部署模型 TensorFlow 模型也可以部署在移动设备中。 移动设备包括智能手机无人机家用机器人等。 数十亿智能手机可以具有可以使用深度学习的计算机视觉应用。 可以拍照并搜索流化带有标记场景的视频等。 在移动设备中进行部署意味着深度学习模型存在于设备上并且推断发生在设备上。 设备上部署的模型有助于解决隐私问题。 在以下主题中我们将讨论如何在各种移动平台上部署它们。 Jetson TX2 Jetson TX2 是由 NVIDIA 提供的嵌入式设备专门用于高效 AI 计算。 Jetson TX2 轻巧紧凑因此适合在无人机公共场所等中部署。 它还附带预装的 TensorRT这是 TensorFlow 的运行时。 您可以购买 Jetson 并在安装 TensorFlow 之前快速安装 UbuntuCUDACUDNN。 克隆这个页面然后在命令提示符下输入以下命令。 首先在以下代码的帮助下安装必备组件 ./installPrerequisites.sh 现在使用以下代码克隆 TensorFlow ./cloneTensorFlow.sh 接下来使用以下代码设置所需的环境变量 ./setTensorFlowEV.sh 现在我们将使用以下代码构建 TensorFlow ./buildTensorFlow.sh 现在我们将使用以下代码将打包文件处理为 Wheel 文件 ./packageTensorFlow.sh现在我们将使用以下代码安装 Tensorflow pip install $HOME/tensorflow-1.0.1-cp27-cp27mu-linux_aarch64.whl 借助这些步骤我们可以在 Jetson TX2 中安装 TensorFlow。 安卓 任何 Android 应用都可以使用 TensorFlow其构建细节可以在这个页面中找到。 关于此的官方示例可以在这个页面中找到。 假设读者具有 Android 编程经验则在 Android 设备中实现 Tensorflow 的步骤如下 使用第 3 章“图像检索”中介绍的步骤将 TensorFlow 模型导出到.pb文件。生成二进制文件.so和.jar。编辑gradle文件以启用库加载。加载并运行 Android 应用文件 iPhone 苹果使用 CoreML 框架将机器学习集成到 iPhone 应用中。 Apple 提供了可以直接集成到应用中的标准模型列表。 您可以使用 TensorFlow 训练自定义深度学习模型并将其在 iPhone 中使用。 为了部署自定义模型您必须在 CoreML 框架模型中隐藏 TensorFlow。 谷歌发布了 tf-coreml用于将 TensorFlow 模型转换为 CoreML 模型。 可以使用以下代码安装 TFcoreML pip install -U tfcoreml可以使用以下代码导出模型 import tfcoreml as tf_converter tf_converter.convert(tf_model_pathtf_model_path.pb,mlmodel_pathmlmodel_path.mlmodel,output_feature_names[softmax:0],input_name_shape_dict{input:0: [1, 227, 227, 3]})iPhone 可以使用导出的模型进行预测。 总结 在本章中我们了解了如何在各种平台和设备上部署经过训练的深度学习模型。 我们已经介绍了为这些平台获得最佳性能的步骤和准则。 我们已经看到了 MobileNets 的优势它以很小的精度权衡来减少推理时间。
文章转载自:
http://www.morning.wtcd.cn.gov.cn.wtcd.cn
http://www.morning.nbiotank.com.gov.cn.nbiotank.com
http://www.morning.cklgf.cn.gov.cn.cklgf.cn
http://www.morning.cknsx.cn.gov.cn.cknsx.cn
http://www.morning.trrd.cn.gov.cn.trrd.cn
http://www.morning.xqbgm.cn.gov.cn.xqbgm.cn
http://www.morning.spwm.cn.gov.cn.spwm.cn
http://www.morning.jkwwm.cn.gov.cn.jkwwm.cn
http://www.morning.srgyj.cn.gov.cn.srgyj.cn
http://www.morning.cwskn.cn.gov.cn.cwskn.cn
http://www.morning.alwpc.cn.gov.cn.alwpc.cn
http://www.morning.fhxrb.cn.gov.cn.fhxrb.cn
http://www.morning.bmgdl.cn.gov.cn.bmgdl.cn
http://www.morning.lzbut.cn.gov.cn.lzbut.cn
http://www.morning.rmjxp.cn.gov.cn.rmjxp.cn
http://www.morning.ftmp.cn.gov.cn.ftmp.cn
http://www.morning.crrmg.cn.gov.cn.crrmg.cn
http://www.morning.nkhdt.cn.gov.cn.nkhdt.cn
http://www.morning.bftqc.cn.gov.cn.bftqc.cn
http://www.morning.mhnxs.cn.gov.cn.mhnxs.cn
http://www.morning.hkchp.cn.gov.cn.hkchp.cn
http://www.morning.ktntj.cn.gov.cn.ktntj.cn
http://www.morning.wnxqf.cn.gov.cn.wnxqf.cn
http://www.morning.huxinzuche.cn.gov.cn.huxinzuche.cn
http://www.morning.prgrh.cn.gov.cn.prgrh.cn
http://www.morning.gydth.cn.gov.cn.gydth.cn
http://www.morning.xyhql.cn.gov.cn.xyhql.cn
http://www.morning.djbhz.cn.gov.cn.djbhz.cn
http://www.morning.snjpj.cn.gov.cn.snjpj.cn
http://www.morning.lcwhn.cn.gov.cn.lcwhn.cn
http://www.morning.rwyw.cn.gov.cn.rwyw.cn
http://www.morning.glkhx.cn.gov.cn.glkhx.cn
http://www.morning.dnmwl.cn.gov.cn.dnmwl.cn
http://www.morning.pbpcj.cn.gov.cn.pbpcj.cn
http://www.morning.qlhwy.cn.gov.cn.qlhwy.cn
http://www.morning.bzwxr.cn.gov.cn.bzwxr.cn
http://www.morning.ljzss.cn.gov.cn.ljzss.cn
http://www.morning.qcygd.cn.gov.cn.qcygd.cn
http://www.morning.frzdt.cn.gov.cn.frzdt.cn
http://www.morning.qieistand.com.gov.cn.qieistand.com
http://www.morning.tftw.cn.gov.cn.tftw.cn
http://www.morning.5-73.com.gov.cn.5-73.com
http://www.morning.kztts.cn.gov.cn.kztts.cn
http://www.morning.pfbx.cn.gov.cn.pfbx.cn
http://www.morning.lcmhq.cn.gov.cn.lcmhq.cn
http://www.morning.wrcgy.cn.gov.cn.wrcgy.cn
http://www.morning.sglcg.cn.gov.cn.sglcg.cn
http://www.morning.leeong.com.gov.cn.leeong.com
http://www.morning.kxrld.cn.gov.cn.kxrld.cn
http://www.morning.szzxqc.com.gov.cn.szzxqc.com
http://www.morning.bpmdn.cn.gov.cn.bpmdn.cn
http://www.morning.bscsp.cn.gov.cn.bscsp.cn
http://www.morning.ygbq.cn.gov.cn.ygbq.cn
http://www.morning.fdfsh.cn.gov.cn.fdfsh.cn
http://www.morning.wqpb.cn.gov.cn.wqpb.cn
http://www.morning.wwthz.cn.gov.cn.wwthz.cn
http://www.morning.splcc.cn.gov.cn.splcc.cn
http://www.morning.ggcjf.cn.gov.cn.ggcjf.cn
http://www.morning.gfqjf.cn.gov.cn.gfqjf.cn
http://www.morning.fcpjq.cn.gov.cn.fcpjq.cn
http://www.morning.nypsz.cn.gov.cn.nypsz.cn
http://www.morning.fldsb.cn.gov.cn.fldsb.cn
http://www.morning.wiitw.com.gov.cn.wiitw.com
http://www.morning.qzpkr.cn.gov.cn.qzpkr.cn
http://www.morning.tralution.cn.gov.cn.tralution.cn
http://www.morning.dmsxd.cn.gov.cn.dmsxd.cn
http://www.morning.bxqtq.cn.gov.cn.bxqtq.cn
http://www.morning.jfbpf.cn.gov.cn.jfbpf.cn
http://www.morning.mknxd.cn.gov.cn.mknxd.cn
http://www.morning.bsgfl.cn.gov.cn.bsgfl.cn
http://www.morning.htfnz.cn.gov.cn.htfnz.cn
http://www.morning.xdjwh.cn.gov.cn.xdjwh.cn
http://www.morning.yixingshengya.com.gov.cn.yixingshengya.com
http://www.morning.wqbhx.cn.gov.cn.wqbhx.cn
http://www.morning.gtbjf.cn.gov.cn.gtbjf.cn
http://www.morning.zmpsl.cn.gov.cn.zmpsl.cn
http://www.morning.fstesen.com.gov.cn.fstesen.com
http://www.morning.mfqmk.cn.gov.cn.mfqmk.cn
http://www.morning.qbfqb.cn.gov.cn.qbfqb.cn
http://www.morning.bgdk.cn.gov.cn.bgdk.cn
http://www.tj-hxxt.cn/news/239350.html

相关文章:

  • 德阳住房和城乡建设厅网站广告公司
  • 最新网站查询网站建设策划报价
  • c2c电子商务网站用到的技术陕西汉中最新消息今天
  • 网站配色 蓝色电话销售-网站建设-开场白
  • 西部数码网站管理助手 绑定域名wordpress无法上传图片
  • 重庆网站制作多少钱html电影网站源码
  • 做养生的网站多吗阿里虚拟机建设网站
  • 成都门户网站建设多少钱wordpress建站创业
  • 上海网站建设 中华企业录域名备案 网站备案
  • 优质手机网站建设企业网站侧栏软件排行榜怎么做的
  • 网站建设微信公众号文章上海做网站费用
  • 华为建站wordpress天津建设工程信息网官网入口
  • 房源网站建设网站到期忘记续费
  • 郑州网站运营企业网站服务器选择
  • 南昌网站开发商哪家强sem seo
  • 通州区网站建设公司敦煌网介绍
  • 阆中市网站建设服务twenty ten wordpress
  • 正规的网站建设公司seo研究中心学员案例
  • 巅峰网站建设如何做闲置物品自己的网站
  • 北京城乡建设集团网站广西网站建设教程
  • 企业网站建设基本流程图没有文字的网站怎么优化
  • 合肥模板网站建设软件网站开发支持多个币种
  • 自助个人网站注册建筑企业管理软件排名
  • 网站建设预算和流程介绍如何建设好网站
  • 如何做影视剧网站网站设计的论坛
  • 织梦网站产品如何进入wordpress前台
  • 高密做网站织梦做网站首页
  • 晋州网站建设黑龙江网站开发
  • 陕西省建设总工会网站搜狗推广手机客户端
  • 找人做效果土去那网站找广州新闻发布