面向计算机视觉的深度学习:1~5(2)

简介: 面向计算机视觉的深度学习:1~5(2

面向计算机视觉的深度学习:1~5(1)https://developer.aliyun.com/article/1426858

定义的密集层具有用于激活的默认参数,并且还添加了变量摘要。 pooling_layer从卷积层获取特征图,并通过使用池大小和跨距进行跳过来将其缩小为一半。 所有这些层均以图方式连接,并且已被定义。 没有一个值被初始化。 可以添加另一个卷积层,以将采样特征从第一卷积层转换为更好的特征。 合并后,我们可以将激活重塑为线性形式,以便通过密集的层进行馈送:

convolution_layer_1 = convolution_layer(x_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],
  name='flattened_pool')
dense_layer_bottleneck = dense_layer(flattened_pool, 1024)

卷积层之间的唯一区别是过滤器的大小。 重要的是,各层之间的尺寸必须适当地变化。 选择内核和步幅的参数是任意的,这些数字是根据经验选择的。 定义了两个卷积层,然后可以是一个全连接层。 密集层 API 可以采用单个维的任何向量并将其映射到任意数量的隐藏单元,如本例中的1024。 隐藏层之后是 ReLU 激活 ,以使其成为非线性计算。 也为此层添加了变量摘要。 接下来是具有退出率的退出层。 保持较高水平将阻止网络学习。 根据使用的时间,可以将训练模式设置为TrueFalse。 在训练中,我们将其设置为True(默认为False)。 在计算准确率时,我们将不得不更改此设置。 因此,为此保留了一个布尔值,将在训练过程中喂入:

dropout_bool = tf.placeholder(tf.bool)
dropout_layer = tf.layers.dropout(
        inputs=dense_layer_bottleneck,
        rate=0.4,
        training=dropout_bool
    )

丢弃层再次被馈送到一个密实层,这称为对率。 对率是最后一层,激活会导致类数增加。 激活将针对特定类别(即目标类别)加标,并且最多可以获得这 10 个激活的最大值:

logits = dense_layer(dropout_layer, no_classes)

对率的输出与上一节中创建的模型非常相似。 现在,对数可以通过 softmax 层传递,然后像以前一样进行交叉熵计算。 在这里,我们添加了一个作用域名称,以在 TensorBoard 中获得更好的可视化效果,如下所示:

with tf.name_scope('loss'):
    softmax_cross_entropy = tf.nn.softmax_cross_entropy_with_logits(
        labels=y_input, logits=logits)
    loss_operation = tf.reduce_mean(softmax_cross_entropy, name='loss')
    tf.summary.scalar('loss', loss_operation)

可以使用tf.train API 的方法优化此loss函数。 在这里,我们将使用Adamoptimiser。 学习率无需定义,并且在大多数情况下效果良好:

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)

还添加了精度的标量摘要。 下一步是启动会话并初始化变量,如上一节所述。 这些行在这里不再重复。 必须合并这些摘要,并且必须定义用于编写训练和测试摘要的文件:

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')

注意,该图只用summary_writer写入一次。 训练与之前非常相似,除了训练时的精度计算和值被添加到摘要中。 接下来,可以批量加载数据并可以开始训练:

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={
        x_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={
            x_input: test_images,
            y_input: test_labels,
            dropout_bool: False
        })
        test_summary_writer.add_summary(merged_summary, batch_no)

每次迭代都会返回摘要以获取训练数据,并将其添加到编写器中。 对于第十次迭代,将添加测试摘要。 请注意,仅在训练期间而不是在测试期间启用丢弃。 我们已经完成了定义以及网络摘要,可以运行该网络。 要查看训练过程,我们可以按照第 1 章,“入门”中所述前往 TensorBoard。

在深度学习中使用 TensorBoard

在浏览器中打开 TensorBoard 后,转到图表选项卡。 应该显示我们定义并接受训练的图。 右键单击节点,我们可以选择要从主图中删除的操作。 对齐后,图应如下所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GyQa5cVl-1681567519361)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/c07978e2-e383-4124-9f9a-2be7bf0c7899.png)]

该图说明了在先前实例中经过训练和定义的图

注意我们定义的所有层的显示效果如何。 这对于检查架构的定义非常有用。 图的方向与所有细节都很好地可视化了。 通过单击每个节点,您可以看到该节点的详细信息,例如输入和输出张量形状,如下所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-okCjiykD-1681567519362)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/e96a21f1-a15b-4962-8aec-62216cd004e1.png)]

这些值可用于交叉检查层参数的定义。 请注意左下方的图例,以使自己熟悉此页面,如下所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EInE3Spt-1681567519362)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/58e1619e-46b3-4d78-9076-dfcfad01b5be.png)]

名称范围已分组,可以通过单击节点上的加号来查看各个组件。 节点按颜色排列。 现在我们可以移至标量页面。 通过在页面上四处移动,可以发现精度图,如下图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rQMbVfeC-1681567519362)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/dc143414-d4bc-471b-ae2f-f6831f6030db.png)]

橙色线用于训练数据,蓝色线用于测试数据。 他们大致遵循相同的模式。 表示原始值的亮线稍微少一些,而亮线是平滑的曲线。 可以在 UI 中选择平滑系数。 测试数据的准确率已达到 97% 以上。 以下是损失摘要中的图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J1j9JCoT-1681567519363)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/590361f9-9421-41be-b2a2-d2aafe0e1d6d.png)]

在训练过程中,训练和测试数据的损失都在稳步减少,这是一个好兆头。 在训练过程中将刷新所有摘要的数据,我们可以见证准确率的提高和损失的减少,从而获得 97.38% 的出色测试精度。

这可以帮助您查看模型是否正在学习并且正在朝着更好的方向发展。 其他汇总(例如最小值,最大值,平均值和标准差)也很有用。 以下是密集层的图形:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SzMpMpAt-1681567519363)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/c57d3b2a-1f10-49e0-9daf-08e6ce170d0b.png)]

这些摘要对于注意权重的变化很有用。 这些分布也可以显示为直方图,如下所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AY2EwxAv-1681567519363)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/04d8485e-8078-4516-8203-27c99d3f2e66.png)]

这些是对数的权重分布。 这些是 TensorBoard 可能提供的美丽可视化效果,并且在训练中非常有帮助。 通过使模型更深入,我们可以见证准确率的巨大提高。 在下一节中,我们将看到如何使用 Keras API 训练相同的模型。 现在您可以看到 TensorBoard 在检查深度学习模型和训练过程中的特征。

在 Keras 中训练 MNIST 模型

在本节中,我们将使用通过 tf.keras API 定义的与上一节相同的模型。 最好从 TensorFlow 学习 Keras 和Layer包,因为它们可以在几个开源代码中看到。 本书的目的是使您了解 TensorFlow 的各种产品,以便您可以在其之上构建产品。

“读取代码的次数多于写入代码的次数。”

牢记前面的引用,向您展示了如何使用各种 API 实现相同的模型。 任何最新算法实现的开放源代码都将是这些 API 的组合。 接下来,我们将从 Keras 实现开始。

准备数据集

Keras 提供MNIST数据。 首先,导入tensorflow。 然后定义一些常量,例如批量大小,类和周期数。 可以根据计算机上可用的 RAM 选择批次大小。 批量大小越大,所需的 RAM 越多。 批次大小对准确率的影响很小。 此处的类数等于 10,并且针对不同的问题而有所不同。 周期的数量决定了训练必须经过整个数据集的次数。 如果在所有周期结束时减少损失,则可以将其设置为较高的数字。 在某些情况下,训练时间较长可以提高准确率。 现在让我们看一下创建数据集的步骤:

  1. 设置输入图像的尺寸,如下所示:
batch_size = 128
        no_classes = 10
        epochs = 2
        image_height, image_width = 28, 28
  1. 使用 Keras 工具将数据从磁盘加载到内存:
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
  1. 将向量重塑为图像格式,并使用给定的代码定义卷积的输入尺寸:
x_train = x_train.reshape(x_train.shape[0], image_height, image_width, 1)
        x_test = x_test.reshape(x_test.shape[0], image_height, image_width, 1)
        input_shape = (image_height, image_width, 1)
  1. 如下将数据类型转换为float
x_train = x_train.astype('float32')
        x_test = x_test.astype('float32')
  1. 通过减去数据均值来归一化数据:
x_train /= 255
        x_test /= 255
  1. 将分类标签转换为单热编码:
y_train = tf.keras.utils.to_categorical(y_train, no_classes)
        y_test = tf.keras.utils.to_categorical(y_test, no_classes)

这与 TensorFlow 编写代码的方式非常不同。 数据已加载到内存中,此处Placeholders的概念均不存在。

建立模型

在本节中,我们将使用一些卷积层,然后是全连接层,以训练前面的数据集。 构造一个简单的顺序模型,该模型具有两个卷积层,然后是池化层,丢弃层和密集层。 顺序模型具有add方法,可以将多个层堆叠在一起。 第一层具有 64 个过滤器,第二层具有 128 个过滤器。 所有过滤器的内核大小均为 3。 在卷积层之后应用最大池。 卷积层的输出被展平,并通过丢包连接连接到一对全连接层。

最后一层连接到 softmax,因为这是一个多类分类问题。 以下代码显示了如何定义模型:

def simple_cnn(input_shape):
    model = tf.keras.models.Sequential()
    model.add(tf.keras.layers.Conv2D(
        filters=64,
        kernel_size=(3, 3),
        activation='relu',
        input_shape=input_shape
    ))
    model.add(tf.keras.layers.Conv2D(
        filters=128,
        kernel_size=(3, 3),
        activation='relu'
    ))
    model.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2)))
    model.add(tf.keras.layers.Dropout(rate=0.3))
    model.add(tf.keras.layers.Flatten())
    model.add(tf.keras.layers.Dense(units=1024, activation='relu'))
    model.add(tf.keras.layers.Dropout(rate=0.3))
    model.add(tf.keras.layers.Dense(units=no_classes, activation='softmax'))
    model.compile(loss=tf.keras.losses.categorical_crossentropy,
                  optimizer=tf.keras.optimizers.Adam(),
                  metrics=['accuracy'])
    return model
simple_cnn_model = simple_cnn(input_shape)

该模型刚刚定义,必须进行编译。 在编译损失期间,必须定义优化器和指标。 损失将是交叉熵,并通过 Adam 算法进行了优化,我们将以准确率作为度量标准。 使用加载的数据,训练和评估数据。 使用训练参数加载训练数据并拟合模型:

simple_cnn_model.fit(x_train, y_train, batch_size, epochs, (x_test, y_test))
train_loss, train_accuracy = simple_cnn_model.evaluate(
    x_train, y_train, verbose=0)
print('Train data loss:', train_loss)
print('Train data accuracy:', train_accuracy)

使用 Keras API 时,不会创建会话。 然后按以下方式评估测试数据:

test_loss, test_accuracy = simple_cnn_model.evaluate(
    x_test, y_test, verbose=0)
print('Test data loss:', test_loss)
print('Test data accuracy:', test_accuracy)

评估也可以在不显式创建会话的情况下创建。 运行完成后,结果应类似于以下内容:

Loss for train data: 0.0171295607952
Accuracy of train data: 0.995016666667
Loss for test data: 0.0282736890309
Accuracy of test data: 0.9902

这样可以使测试数据的准确率达到 99%。 请注意,训练精度高于测试数据,并且始终打印它们都是一个好习惯。 精度的差异是由于迭代次数造成的。 由于数据集的差异,准确率比 TensorFlow 中创建的先前模型要高一些。

其他流行的图像测试数据集

MNIST数据集是用于测试算法的最常用数据集。 但是还有其他数据集可用于测试图像分类算法。

CIFAR 数据集

加拿大高级研究机构CIFAR-10)数据集包含 60,000 张图像,其中 50,000 张图像用于训练,10,000 张图像用于测试。 类的数量是 10。图像尺寸是 32 像素 x 32 像素。 以下是从每个类别中随机选择的图像:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZYZ8hU5j-1681567519363)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/50a4ca9c-f6dc-413c-9cb1-1691ccc0680c.png)]

这些图像很小,仅包含一个对象。 CIFAR-100数据集包含相同数量的图像,但具有 100 个类别。 因此,每个类别只有 600 张图像。 每个图像都带有一个超级标签和一个精美标签。 如果您想进行实验,可以在tf.keras.datasets上找到此数据集。

Fashion-MNIST 数据集

Fashion-MNIST是替代MNIST数据集而创建的数据集。 创建为MNIST的此数据集被认为太简单了,可以直接用MNIST代替。

以下是在执行主成分分析PCA)之后从数据集中随机选择的示例:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hEy0UYdC-1681567519364)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/da904c50-2447-4537-833a-d31218cbfe5a.png)]

数据集大小,标签数量和图像大小类似于MNIST。 可以在这个页面上找到更多详细信息。 您可以运行先前学习的模型并检查准确率。

ImageNet 数据集和竞赛

ImageNet 是具有 14,197,122 图像,21,841 个同义词集索引的计算机视觉数据集。 同义词集是 WordNet 层次结构中的一个节点,而节点又是一组同义词。 每年都会举办一次比赛,其中有 1000 个此类数据集。 它已成为评估图像分类算法表现的标准基准。

在 2013 年,基于深度学习的计算机视觉模型获得了第一名。 从那时起,只有深度学习模型赢得了竞争。 以下是多年来在比赛中排名前五位的错误率:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qN6vsGHQ-1681567519364)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/06f1198b-fb2d-44ab-baed-b2cff9e113ed.png)]

您会注意到,多年来精度以及层的深度一直在增加。 接下来,我们将了解该图中存在的模型。

更大的深度学习模型

我们将审视几种模型定义,这些模型定义在 ImageNet 竞赛中取得了最新的成果。 我们将在以下主题中单独研究它们。

AlexNet 模型

Krizhevsky 等人提出了 AlexNet(是第一个引起人们对计算机视觉深度学习的广泛兴趣的作品),它一直是这个领域里的先驱和影响力。 该模型赢得了 ImageNet 2013 挑战。 错误率是 15.4%,明显优于下一个。 该模型是具有五个卷积层的相对简单的架构。 面临的挑战是对 1,000 种对象进行分类。 图像和数据包含 1500 万条带标注的图像,其中包含 22,000 多个类别。 其中,只有 1,000 个类别用于比赛。 AlexNet 使用 ReLU 作为激活函数,发现它的训练速度比其他激活函数快几倍。 该模型的架构如下所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yHr6Ducz-1681567519364)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/ee056ac4-3d0d-47df-ac96-5e2f6988c91b.png)]

复制自 Krizhevsky 等人。

本文还使用了数据增强技术,例如图像翻译,水平翻转和随机裁剪。 漏失层防止过拟合 。 该模型使用原始随机梯度下降SGD)进行训练。 仔细选择 SGD 的参数进行训练。 学习率在一组固定的训练迭代中变化。 动量和权重衰减采用固定值进行训练。 本文介绍了一种称为局部响应规范化LRN)的概念。 LRN 层对滤镜上的每个像素进行归一化,以避免在特定滤镜中发生巨大的激活。

不再使用该层,因为最近的研究表明,由于 LRN,没有太大的改进。 AlexNet 总共有 6000 万个参数。

VGG-16 模型

VGG 模型代表牛津大学的, 视觉几何组 。 该模型非常简单,并且比 AlexNet 具有更大的深度。 该纸有两个模型,深度分别为 16 和 19 层。 所有的 CNN 层都使用3 x 3步幅的滤镜和 1 尺寸的垫,以及 2 步幅的最大合并尺寸 2。这导致参数数量减少。 尽管由于最大池化而减小了大小,但过滤器的数量却随着层的增加而增加。 16 层深度模型的架构如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vOtdWKKG-1681567519364)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/776596c6-d2f7-4656-bb91-85d84253f33c.png)]

该模型具有 1.38 亿个参数,是此处描述的所有模型中最大的。 但是参数的一致性很好。 其特征是,随着网络的深入,图像的尺寸越小,过滤器的数量就越多。 所使用的数据增强技术之一是规模抖动。 比例抖动是一种增强技术,其中具有随机大小的一侧被认为会改变比例。

Google Inception-V3 模型

Inception-V3 是 Szegedy 等人提出的,并介绍了具有更好泛化方法的初始概念。 该架构在 2014 年赢得了 ImageNet 竞赛的冠军。它旨在提高速度和尺寸的效率。 它的参数比 AlexNet 小 12 倍。 初始阶段是构建宏架构的微架构。 每个隐藏层都有一个较高级别的图像表示。 在每一层,我们可以选择使用池化或其他层。 初始使用多个内核,而不是使用一种类型的内核。 平均池之后是各种大小的卷积,然后将它们合并在一起。

可以基于数据学习内核参数。 使用多个内核,该模型可以检测较小的特征以及较高的抽象度。 1 x 1卷积将减少特征,从而减少计算量。 这将在推理过程中占用较少的 RAM。 以下是最简单形式的启动模块,其中包含具有各种内核大小和池化的卷积选项:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DghbPfcl-1681567519364)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/e38ca5d2-f9c5-4581-b5be-1a5a30c5d57b.png)]

请注意,与 AlexNet 或 VGG 相反,操作是并行进行的。 输出量巨大,因此引入了1 x 1的过滤器以降低尺寸。 将缩小的尺寸添加到架构后,它将变为:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vCXpYQpR-1681567519365)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/cc7e385f-0826-4d07-99d7-9116a649e402.png)]

该模型的整个架构如下,包括所有的风吹草动:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LZtcTDpa-1681567519365)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/bef2324f-3a22-4f92-8af9-a6e90300e66c.png)]

该图说明了 Google Inception V3 模型架构[经 Szegedy 等人的许可复制]

有 9 个初始模块,共 100 层,它们具有良好的表现。

Microsoft ResNet-50 模型

ResNet 是 He 等人提出的,并在 2015 年赢得了 ImageNet 竞赛。此方法表明可以训练更深的网络。 网络越深,精度变得越饱和。 这甚至不是由于过拟合或由于存在大量参数,而是由于减少了训练误差。 这是由于无法反向传播梯度。 可以通过以下方法将梯度直接发送到带有残差块的更深层来克服:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bExL1IuH-1681567519365)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/ff1c06f1-c254-4602-9b50-91cf9402df05.png)]

每两层相连,形成一个残留块。 您可以看到训练是在各层之间传递的。 通过这种技术,反向传播会将误差带到较早的层。

可以使用来自这里的模型定义,它定义了模型中的每一层,并且提供ImageNet数据集上的预训练权重。

SqueezeNet 模型

Iandola 等人介绍了 SqueezeNet 模型,以减少模型尺寸和参数数量。

通过使用1 x 1过滤器替换3 x 3过滤器,使网络变得更小,如下所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1mgGbC2a-1681567519365)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/61941eba-0b03-4a6d-93ce-69132bedbe96.png)]

经 Iandola 等人许可复制。

3 x 3过滤器的输入数量也减少了在较高级别发生时各层的下采样,从而提供了较大的激活图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2UNrsTeu-1681567519366)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/12771464-5c49-48ae-b9e4-f512ed8f42aa.png)]

经 Iandola 等人许可复制

空间转换器网络

Jaderberg 等人提出的空间转换器网络尝试在传递到 CNN 之前对图像进行转换。 这与其他网络不同,因为它尝试在卷积之前修改图像。 该网络学习参数以变换图像。 学习用于仿射变换的参数。 通过应用仿射变换,可以实现空间不变性。 在以前的网络中,空间不变性是通过最大池化层实现的。 空间转换器网络的位置如下所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JYj9KOv1-1681567519367)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/177e14e5-4bc8-4b5c-9e0f-754188739941.png)]

经 Jaderberg 等人许可复制

DenseNet 模型

DenseNet 是 Huang 等人提出的 ResNet 的扩展。 在 ResNet 块中,上一层通过求和合并到下一层。 在 DenseNet 中,上一层通过连接合并到下一层。 DenseNet 将所有层连接到上一层,将当前层连接到下一层。

在下图中,可以看出特征图是如何作为输入提供给其他层的:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iTepA1c8-1681567519367)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/2ff8e417-48ae-491e-9abc-78bccdcdc61a.png)]

经 Huang 等人许可复制

这样,它提供了多个优点,例如更平滑的梯度,特征变换等。 这也减少了参数的数量:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k4XgLR16-1681567519367)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/feec4f72-5ef2-4eb0-a647-21f56d254fef.png)]

经 Huang 等人许可复制

我们已经介绍了图像分类任务的所有最新算法。 任何架构均可用于图像分类任务。 在下一节中,我们将看到如何使用这些先进的架构训练模型来预测宠物,并提高准确率。

训练猫与狗的模型

在本部分中,我们将准备和训练用于预测猫与狗的模型,并了解一些可提高准确率的技术。 大多数图像分类问题都属于这种范例。 本节介绍的技术,例如扩充和迁移学习,对于一些问题很有用。

准备数据

为了进行分类,我们将从 kaggle 下载数据并以适当的格式存储。 注册并登录 Kaggle 并转到猫狗大战。 从该页面下载train.ziptest1.zip文件。 train.zip文件包含 25,000 张宠物数据图像。 我们将仅使用部分数据来训练模型。 具有更多计算能力的读者,例如图形处理单元GPU),可以使用比建议的更多的数据。 运行以下脚本以重新排列图像并创建必要的文件夹:

import os
import shutil
work_dir = '' # give your correct directory
image_names = sorted(os.listdir(os.path.join(work_dir, 'train')))
def copy_files(prefix_str, range_start, range_end, target_dir):
    image_paths = [os.path.join(work_dir, 'train', prefix_str + '.' + str(i) + '.jpg')
                   for i in range(range_start, range_end)]
    dest_dir = os.path.join(work_dir, 'data', target_dir, prefix_str)
    os.makedirs(dest_dir)
    for image_path in image_paths:
        shutil.copy(image_path, dest_dir)
copy_files('dog', 0, 1000, 'train')
copy_files('cat', 0, 1000, 'train')
copy_files('dog', 1000, 1400, 'test')
copy_files('cat', 1000, 1400, 'test')

对于我们的实验,我们将仅使用 1000 张猫和狗的图像。 因此,将图像 0–999 从下载的文件夹复制到cats下新创建的train 文件夹。 同样,将 1,000–1,400 复制到data/test/cat,将train/dogs中的 0–999 和data/test/dog中的 1,000–1,400 复制,这样我们每个类别都有 1,000 个训练示例和 400 个验证示例。

使用简单的 CNN 进行基准测试

让我们在该数据集上运行先前的simple_cnn模型,并查看其表现。 该模型的表现将成为我们判断其他技术的基本基准。 我们将为数据加载和训练定义一些变量,如下所示:

image_height, image_width = 150, 150
train_dir = os.path.join(work_dir, 'train')
test_dir = os.path.join(work_dir, 'test')
no_classes = 2
no_validation = 800
epochs = 2
batch_size = 200
no_train = 2000
no_test = 800
input_shape = (image_height, image_width, 3)
epoch_steps = no_train // batch_size
test_steps = no_test // batch_size

该常数用于本节中的训练猫和狗模型的讨论中讨论的技术。 在这里,我们正在使用 2,800 张图像进行训练和测试,这对于个人计算机的 RAM 是合理的。 但这对于更大的数据集是不可持续的。 最好一次只加载一批图像进行训练和测试。 为此,tf.keras具有称为ImageDataGenerator的类,可在必要时读取图像。 假定从上一节中导入了simple_cnn模型。 以下是使用生成器加载图像的示例:

generator_train = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1\. / 255)
generator_test = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1\. / 255)

加载时,此定义还会重新缩放图像。 接下来,我们可以使用flow_from_directory方法从目录中读取图像,如下所示:

train_images = generator_train.flow_from_directory(
    train_dir,
    batch_size=batch_size,
    target_size=(image_width, image_height))
test_images = generator_test.flow_from_directory(
    test_dir,
    batch_size=batch_size,
    target_size=(image_width, image_height))

加载图像的目录,批量大小和图像的目标大小作为参数传递。 此方法执行重新缩放,并分批传递数据以拟合模型。 该生成器可直接用于拟合模型。 该模型的方法 fit_generator可以按以下方式使用:

simple_cnn_model.fit_generator(
    train_images,
    steps_per_epoch=epoch_steps,
    epochs=epochs,
    validation_data=test_images,
    validation_steps=test_steps)

该模型适合来自训练图像生成器的数据。 从训练中定义周期数,并传递验证数据以获取模型过度训练的表现。 该fit_generator支持并行处理数据和模型训练。 CPU 执行重新缩放,而 GPU 可以执行模型训练。 这使得计算资源的效率很高。 经过 50 个周期后,该模型的准确率应为 60%。 接下来,我们将看到如何扩充数据集以获得改进的表现。

扩充数据集

数据扩充提供了增加数据集大小的方法。 数据扩充会在训练期间引入噪声,从而在模型中为各种输入生成鲁棒性。 该技术在数据集较小且可以组合并与其他技术一起使用的情况下很有用。 接下来,我们将看到不同类型的扩充。

增强技术

可以通过多种方式来增强图像,如下所述:

  • 翻转:图像在水平或垂直方向上被镜像或翻转
  • 随机裁剪:裁剪随机部分,因此该模型可以处理遮挡
  • 剪切:变形图像来影响对象的形状
  • 缩放:训练图像的缩放部分来处理不同比例的图像
  • 旋转:旋转对象来处理对象中各种程度的变化
  • 增白:增白是通过仅保留重要数据的主成分分析完成的
  • 归一化:通过标准化均值和方差来归一化像素
  • 通道偏移:更改颜色通道来使模型对各种伪像引起的颜色变化具有鲁棒性

所有这些技术都在ImageDataGenerator中实现,以增加数据集的大小。 以下是generator_train的修改版本,其中包含前面讨论的一些增强技术:

generator_train = tf.keras.preprocessing.image.ImageDataGenerator(
    rescale=1\. / 255,
    horizontal_flip=True,
    zoom_range=0.3,
    shear_range=0.3,)

替换前面代码中的generator_train将使精度提高到 90%。 更改扩充的参数,并注意更改。 在下一节中,我们将讨论一种称为迁移学习的技术,该技术有助于以更少的数据训练更大的模型。

模型的迁移学习或微调

迁移学习是从预先训练的模型中学习的过程,该模型在较大的数据集上进行了训练。 用随机初始化训练模型通常需要时间和精力才能获得结果。 使用预训练的模型初始化模型可以加快收敛速度,并节省时间和能源。 这些经过预训练的模型通常使用精心选择的超参数进行训练。

可以直接使用预训练模型的几层,而无需进行任何修改,也可以对其进行位训练以适应变化。 在本节中,我们将学习如何对在ImageNet数据集上具有数百万个类别的模型进行调整或迁移学习。

瓶颈特征训练

上一节中介绍的模型很简单,因此准确率可能较低。 应该从它们构建复杂的模型。 它们不能从头开始构建。 因此,提取瓶颈特征并对它们进行分类器训练。 瓶颈特征是训练数百万张图像的复杂架构所产生的特征。 图像是通过前进完成的,并存储了最终层的特征。 从这些中,训练了一个简单的逻辑分类器进行分类。 提取瓶颈层,如下所示:

generator = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1\. / 255)
model = tf.keras.applications.VGG16(include_top=False)
train_images = generator.flow_from_directory(
    train_dir,
    batch_size=batch_size,
    target_size=(image_width, image_height),
    class_mode=None,
    shuffle=False
)
train_bottleneck_features = model.predict_generator(train_images, epoch_steps)
test_images = generator.flow_from_directory(
    test_dir,
    batch_size=batch_size,
    target_size=(image_width, image_height),
    class_mode=None,
    shuffle=False
)
test_bottleneck_features = model.predict_generator(test_images, test_steps)

将采用 VGG 模型并将其用于预测图像。 标签分配如下:

train_labels = np.array([0] * int(no_train / 2) + [1] * int(no_train / 2))
test_labels = np.array([0] * int(no_test / 2) + [1] * int(no_test / 2))

使用瓶颈特征构建,编译和训练具有两层的顺序模型,并且可以使用以下给出的代码来实现:

model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Flatten(input_shape=train_bottleneck_features.shape[1:]))
model.add(tf.keras.layers.Dense(1024, activation='relu'))
model.add(tf.keras.layers.Dropout(0.3))
model.add(tf.keras.layers.Dense(1, activation='softmax'))
model.compile(loss=tf.keras.losses.categorical_crossentropy,
              optimizer=tf.keras.optimizers.Adam(),
              metrics=['accuracy'])

使用以下所示的代码对这些瓶颈特征进行模型训练:

model.fit(
    train_bottleneck_features,
    train_labels,
    batch_size=batch_size,
    epochs=epochs,
    validation_data=(test_bottleneck_features, test_labels))

这提供了一种不同的方法来训练模型,并且在训练数据较少时很有用。 这通常是训练模型的更快方法。 仅使用预训练模型的最终激活来适应新任务。 这个想法可以扩展为微调几层,如下所示:

在深度学习中微调几层

可以加载预训练的模型,并且仅可以训练几层。 当给定的问题与模型所训练的图像非常不同时,此方法会更好地工作。 微调是深度学习中的常见做法。 当数据集较小时,这具有优势。 优化也可以更快地获得。

在小型数据集上训练深度网络会导致过拟合。 使用微调程序也可以避免这种过拟合。 在较大的数据集上训练的模型也应该相似,因为我们希望激活和特征与较小的数据集相似。 您可以从存储的权重路径开始,如下所示:

top_model_weights_path = 'fc_model.h5'

加载视觉几何组VGG)模型,并将初始层设置为不可训练。 下一部分将详细介绍 VGG 模型。 目前,将 VGG 视为适用于图像数据的大型深度学习模型。 使用以下给出的代码,用新的可训练层替换全连接层:

model = tf.keras.applications.VGG16(include_top=False)

可以在 VGG 模型的顶部构建一个小型的两层前馈网络,通常具有隐藏的单元,激活和退出,如下所示:

model_fine_tune = tf.keras.models.Sequential()
model_fine_tune.add(tf.keras.layers.Flatten(input_shape=model.output_shape))
model_fine_tune.add(tf.keras.layers.Dense(256, activation='relu'))
model_fine_tune.add(tf.keras.layers.Dropout(0.5))
model_fine_tune.add(tf.keras.layers.Dense(no_classes, activation='softmax'))

顶级模型还必须装有经过充分训练的砝码。 然后可以将顶级模型添加到卷积基础中:

model_fine_tune.load_weights(top_model_weights_path)
model.add(model_fine_tune)

我们可以将前 25 个层设置为不可训练,直到最后一个卷积块,这样它们的权重才会被更新。 仅其余层将被更新:

for vgg_layer in model.layers[:25]:
    vgg_layer.trainable = False

使用梯度下降优化器以缓慢的学习率(4 量级)编译模型:

model.compile(loss='binary_crossentropy',
  optimizer=tf.keras.optimizers.SGD(lr=1e-4, momentum=0.9),
  metrics=['accuracy'])

我们可以将之前介绍的增强技术与剪切,缩放和翻转结合使用。 可以从目录中将流与训练和验证数据集一起添加到生成器。 现在可以将模型与数据增强结合起来进行微调。 这种训练方式比以前的所有方法都具有更好的准确率。 以下是转学的指南:

数据大小 相似数据集 不同的数据集
较小的数据 微调输出层 微调更深层
更大的数据 微调整个模型 从头开始训练

根据数据大小,可以确定要微调的层数。 数据越少,需要调整的层数就越少。 我们已经看到了如何使用迁移学习技术来提高模型的准确率。

开发实际应用

识别猫和狗是一个很酷的问题,但不太可能是重要的问题。 产品中使用的图像分类的实际应用可能会有所不同。 您可能有不同的数据,目标等。 在本节中,您将学习解决这些不同设置的提示和技巧。 解决新问题时应考虑的因素如下:

  • 目标数量。 是 10 类问题还是 10,000 类问题?
  • 类内差异有多大? 例如,是否必须在一个类别标签下标识不同类型的猫?
  • 类间差异有多大? 例如,是否需要识别不同的猫?
  • 数据有多大?
  • 数据的平衡程度如何?
  • 是否已经有一个用很多图像训练的模型?
  • 部署推断时间和模型大小需要什么? 在 iPhone 上是 50 毫秒还是在 Google Cloud Platform 上是 10 毫秒? 可以消耗多少 RAM 来存储模型?

处理图像分类问题时,请尝试回答这些问题。 根据答案,您可以设计训练架构并提高准确率,如下一节所述。

选择合适的模型

架构有很多选择。 根据部署的灵活性,可以选择模型。 请记住,卷积较小且较慢,但是密集层较大且较快。 在大小,运行时间和准确率之间需要权衡。 建议在最终决定之前测试所有架构。 根据应用,某些模型可能比其他模型更好。 您可以减小输入大小以加快推理速度。 可以根据以下部分所述的指标来选择架构。

解决欠拟合和过拟合的方案

对于该问题,模型有时可能太大或太小。 可以将其分别分类为欠拟合或过拟合。 当模型太小时会发生拟合不足,而在训练精度较低时可以进行测量。 当模型太大并且训练和测试精度之间存在较大差距时,就会发生过拟合。 拟合不足可以通过以下方法解决:

  • 获取更多数据
  • 尝试更大的模型
  • 如果数据很小,请尝试使用迁移学习技术或进行数据扩充

过拟合可以通过以下方法解决:

  • 将丢弃法和批量规范化等技术用于正则化
  • 扩充数据集

时刻提防损失。 损耗应随着迭代次数的减少而减少。 如果损失没有减少,则表明训练已停止。 一种解决方案是尝试使用其他优化器。 类别失衡可以通过加权损失函数来解决。 始终使用 TensorBoard 观看摘要。 很难估计需要多少数据。 本部分是训练任何深度学习模型的最佳课程。 接下来,我们将介绍一些特定于应用的指南。

人脸性别和年龄检测

应用可能需要从人脸检测性别和年龄。 人脸图像可以是通过人脸检测器获取的 。 可以将经过裁剪的人脸图像作为训练数据提供,并且应该给出相似的经过裁剪的人脸以进行推断。 根据所需的推理时间,可以选择 OpenCV 或 CNN 人脸检测器。 对于训练,可以使用 Inception 或 ResNet。 如果由于是视频而所需的推理时间要少得多,则最好使用三个卷积,然后是两个全连接层。 请注意,年龄数据集通常存在巨大的类别失衡,因此使用不同的度量标准(如准确率和召回率)将有所帮助。

自定义模型的微调

自定义模型的微调是一个不错的选择。 在这里,具有多个对属性进行分类的 softmax 层将很有用。 这些属性可以是图案,颜色等。

品牌安全

使用支持向量机SVM)来训练瓶颈层是一个不错的选择,因为各个类别的图像可能会完全不同。 通常将其用于内容审核,以帮助避免显示露骨的图像。 您已经了解了如何解决图像分类中的新问题。

总结

我们已经介绍了用于训练分类任务的基本但有用的模型。 我们看到了使用 Keras 和 TensorFlow API 的 MNIST 数据集的简单模型。 我们还看到了如何利用 TensorBoard 观看训练过程。 然后,我们讨论了一些特定应用的最新架构。 还介绍了几种提高准确率的方法,例如数据增强,瓶颈层训练和微调预训练模型。 还介绍了为新模型训练模型的提示和技巧。

在下一章中,我们将看到如何可视化深度学习模型。 我们还将在本章中部署经过训练的模型以进行推断。 我们还将看到如何将训练有素的层用于通过应用进行图像搜索。 然后,我们将了解自编码器的概念并将其用于特征的维数。

三、图像检索

深度学习也可以称为表示学习,因为模型的特征或表示是在训练期间学习的。 在隐藏层的训练过程中生成的视觉特征可用于计算距离度量。 这些模型学习如何根据分类任务在各个层上检测边缘,图案等。 在本章中,我们将研究以下内容:

  • 如何从经过分类训练的模型中提取特征
  • 如何使用 TensorFlow Serving 在生产系统中进行更快的推断
  • 如何使用这些特征计算查询图像和目标集之间的相似度
  • 将分类模型用于排名
  • 如何提高检索系统的速度
  • 从整体上看系统的架构
  • 当目标图像过多时,使用自编码器学习紧凑的描述
  • 训练去噪自编码器

了解视觉特征

深度学习模型经常因无法解释而受到批评。 基于神经网络的模型通常被认为像黑匣子,因为人类很难推理出深度学习模型的工作原理。 由于激活函数,深度学习模型对图像进行的层转换是非线性的,因此不容易可视化。 已经开发出了通过可视化深层网络的层来解决对不可解释性的批评的方法。 在本节中,我们将研究可视化深层的尝试,以便了解模型的工作原理。

可视化可以使用模型的激活和梯度来完成。 可以使用以下技术可视化激活:

  • 最近邻:可以对图像进行层激活,并且可以一起看到该激活的最近图像。
  • 降维:激活的尺寸可以通过主成分分析PCA)或 T 分布随机邻居嵌入t-SNE),可在二维或三维中可视化。 PCA 通过将值投影到最大方差方向来减小尺寸。 t-SNE 通过将最接近的点映射到三个维度来减小维度。 降维的使用及其技术超出了本书的范围。 建议您参考基本的机器学习材料,以了解有关降维的更多信息。

维基百科是了解降维技术的良好来源。 您可以参考以下链接:

在以下各节中,我们将看到如何实现这些特征的可视化。

可视化深度学习模型的激活

任何层的过滤器都可以可视化任何模型架构。 使用该技术只能理解初始层。 最后一层对于最近邻方法很有用。 当ImageNet数据集与最近邻排列在一起时,其外观如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-goSZJ7mv-1681567519367)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/f13aef48-ee95-48ba-a9d8-87149edc5ea7.jpg)]

查看此图像,您可以看到相同的对象一起出现。 有趣的事情之一是,诸如狗,猴子和猎豹之类的动物虽然没有经过一个标签的训练却同时出现。 当对象相似时,图像的最近邻可视化非常有用,因此,我们可以了解模型的预测。 最后一层也可以通过降维技术(例如主成分分析和 t-SNE)进行可视化。 在下一节中,我们将看到使用降维的可视化实现。

嵌入可视化

可以使用 TensorBoard 以二维或三维可视化嵌入层(即预最终层)。 假定本节中的代码段位于图像分类一章中训练的卷积神经网络模型之后。 首先,我们需要一个元数据文件,它是一个制表符分隔的文件。 元数据文件的每一行都应具有将要可视化的图像标签。 需要一个新变量来存储在会话创建和初始化之间定义的嵌入,如以下代码所示:

no_embedding_data = 1000 embedding_variable = tf.Variable(tf.stack(
    mnist.test.images[:no_embedding_data], axis=0), trainable=False)

我们将获取 MNIST 测试数据,并创建用于可视化的元数据文件,如下所示:

metadata_path = '/tmp/train/metadata.tsv'   with open(metadata_path, 'w') as metadata_file:
 for i in range(no_embedding_data):
 metadata_file.write('{}\n'.format(
 np.nonzero(mnist.test.labels[::1])[1:][0][i]))

如上代码所示,应通过设置参数使嵌入变量不可训练。 接下来,必须定义投影仪配置。 它必须具有tensor_name,它是嵌入变量名称,元数据文件的路径和子画面图像。 子画面图像是一个带有小图像的图像,表示要通过嵌入可视化的标签。 以下是用于定义嵌入投影的代码:

from tensorflow.contrib.tensorboard.plugins import projector
projector_config = projector.ProjectorConfig()
embedding_projection = projector_config.embeddings.add()
embedding_projection.tensor_name = embedding_variable.name
embedding_projection.metadata_path = metadata_path
embedding_projection.sprite.image_path = os.path.join(work_dir + '/mnist_10k_sprite.png')
embedding_projection.sprite.single_image_dim.extend([28, 28])

必须指定子画面图像尺寸。 然后,可以使用投影机通过摘要编写器和配置来可视化嵌入,如以下代码所示:

projector.visualize_embeddings(train_summary_writer, projector_config)
tf.train.Saver().save(session, '/tmp/train/model.ckpt', global_step=1)

然后,将模型与会话一起保存。 然后转到 TensorBoard 查看以下可视化效果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tozBkczK-1681567519368)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-cv/img/12a15ca8-cf56-4557-8f9c-6ee86903ed4f.png)]

TensorBoard 说明了代码的输出

您必须通过按钮选择 T-SNE 和颜色,如屏幕截图所示,以获得类似的可视化效果。 您可以看到数字如何一起出现。 该可视化对于检查数据和经过训练的嵌入非常有用。 这是 TensorBoard 的另一个强大功能。 在下一部分中,我们将实现可视化的引导反向传播。

面向计算机视觉的深度学习:1~5(3)https://developer.aliyun.com/article/1426860

相关文章
|
3月前
|
机器学习/深度学习 算法 数据可视化
计算机视觉+深度学习+机器学习+opencv+目标检测跟踪+一站式学习(代码+视频+PPT)-2
计算机视觉+深度学习+机器学习+opencv+目标检测跟踪+一站式学习(代码+视频+PPT)
100 0
|
3月前
|
机器学习/深度学习 Ubuntu Linux
计算机视觉+深度学习+机器学习+opencv+目标检测跟踪+一站式学习(代码+视频+PPT)-1
计算机视觉+深度学习+机器学习+opencv+目标检测跟踪+一站式学习(代码+视频+PPT)
56 1
|
4月前
|
机器学习/深度学习 人工智能 监控
探索深度学习在计算机视觉领域的应用
计算机视觉是人工智能领域的重要分支之一,而深度学习技术在这个领域中的应用已经成为了一个热门话题。深度学习的出现,不仅使得计算机视觉的准确性得到了极大的提升,还为我们提供了更多的可能性。本文将探讨深度学习技术在计算机视觉领域中的应用,并讨论其未来的发展前景。
32 0
|
4月前
|
机器学习/深度学习 人工智能 算法
深度学习引领计算机视觉革命
随着深度学习技术的快速发展,计算机视觉领域迎来了一场革命。本文将探讨深度学习在计算机视觉中的应用,包括图像分类、目标检测、图像生成等方面。通过深度学习的强大能力,计算机视觉正在实现更高精度、更广泛的应用,为人们的生活带来了巨大的影响。
|
4月前
|
机器学习/深度学习 算法 TensorFlow
面向计算机视觉的深度学习:6~10
面向计算机视觉的深度学习:6~10
123 0
|
4月前
|
机器学习/深度学习 算法 TensorFlow
面向计算机视觉的深度学习:1~5(4)
面向计算机视觉的深度学习:1~5(4
61 0
|
4月前
|
机器学习/深度学习 数据可视化 算法
面向计算机视觉的深度学习:1~5(3)
面向计算机视觉的深度学习:1~5(3
65 0
|
4月前
|
机器学习/深度学习 TensorFlow 算法框架/工具
面向计算机视觉的深度学习:1~5(1)
面向计算机视觉的深度学习:1~5(1
130 0
|
4月前
|
机器学习/深度学习 编解码 监控
深度学习掀起计算机视觉革命
计算机视觉是一门涵盖了图像处理、模式识别、机器学习等多个领域的交叉学科。近年来,随着深度学习技术的发展,计算机视觉得到了飞速的发展,取得了令人瞩目的成果。本文将探讨深度学习在计算机视觉中的应用,以及它所带来的变革。
|
9月前
|
机器学习/深度学习 自然语言处理 算法
深度学习在计算机视觉和自然语言处理中的应用
深度学习在计算机视觉和自然语言处理领域的应用为我们带来了更多可能性,不断推动着人工智能技术的发展。无论是从理论还是实际应用来看,深度学习都在为计算机视觉和自然语言处理领域的发展注入了无限的活力。随着技术的不断创新,我们有理由相信,深度学习将在未来继续刷新我们的认知和想象。
145 0
深度学习在计算机视觉和自然语言处理中的应用