TF图层指南:构建卷积神经网络

TensorFlow layers模块提供了一个高级API,可以轻松构建神经网络。它提供了便于创建密集(完全连接)层和卷积层,添加激活函数以及应用缺陷正则化的方法。在本教程中,您将学习如何layers构建卷积神经网络模型来识别MNIST数据集中的手写数字。

所述MNIST数据集包括60000个训练样例和手写数字0-9,格式为28x28像素的单色图像万个测试实施例。

入门

我们设计TensorFlow程序的骨架。创建一个调用的文件 cnn_mnist.py,并添加以下代码:

from __future__ import absolute_import from __future__ import division from __future__ import print_function   # Imports import numpy as np import tensorflow as tf   from tensorflow.contrib import learn from tensorflow.contrib.learn.python.learn.estimators import model_fn as model_fn_lib   tf.logging.set_verbosity(tf.logging.INFO)   # Our application logic will be added here   if __name__ == "__main__":   tf.app.run()

在您完成本教程时,您将添加代码来构建,训练和评估卷积神经网络。完整的最终代码可以在 这里找到。

卷积神经网络简介

卷积神经网络(CNN)是用于图像分类任务的当前最先进的模型架构。CNN将一系列过滤器应用于图像的原始像素数据,以提取和学习较高级别的功能,然后模型可用于分类。CNN包含三个组成部分:

  • 卷积层,将图像的指定数量的卷积滤波器应用。对于每个子区域,层执行一组数学运算,以在输出特征图中产生单个值。卷积层通常将 ReLU激活功能应用于输出,以将非线性引入到模型中。
  • 汇集层,其  由卷积层提取的图像数据进行下采样,以降低特征图的维度,以减少处理时间。通常使用的池化算法是最大池,其提取特征映射的子区域(例如,2×2像素块),保持其最大值,并丢弃所有其他值。
  • 密集(完全连接)层,对卷积层提取的特征进行分类,并由池层进行下采样。在密集层中,层中的每个节点连接到上一层中的每个节点。

通常,CNN由执行特征提取的卷积模块组成。每个模块由一个卷积层组成,后面是一个池层。最后一个卷积模块后面是一个或多个执行分类的密集层。CNN中的最终密集层包含模型中每个目标类的单个节点(模型可以预测的所有可能的类),其中 softmax激活函数为每个节点生成0-1之间的值这些softmax值等于1)。我们可以将给定图像的softmax值解释为图像落入每个目标类的可能性的相对度量。

注意:对于CNN架构的更全面的演练,请参阅斯坦福大学的 视觉识别卷积神经网络课程材料

构建CNN MNIST分类器

我们使用以下CNN架构构建一个模型来对MNIST数据集中的图像进行分类:

  1. 卷积层#1:应用32个5x5滤镜(提取5x5像素的子区域),具有ReLU激活功能
  2. 池化层#1:使用2x2过滤器执行最大池化,步长为2(指定池区域不重叠)
  3. 卷积层#2:应用64个5x5滤镜,具有ReLU激活功能
  4. 集合层#2:再次,使用2x2过滤器执行最大池,并且步长为2
  5. 密集层#1:1,024个神经元,脱落正则化率为0.4(在训练期间任何给定元素的概率为0.4)
  6. 密集层#2(Logit Layer):10个神经元,每个数字目标类(0-9)一个。

tf.layers模块包含创建上述三种类型中的每一种的方法:

  • conv2d()。构造二维卷积层。获取过滤器的数量,过滤内核大小,填充和激活功能作为参数。
  • max_pooling2d()。使用max-pooling算法构建二维池化层。将过滤器大小合并为一个参数。
  • dense()。构造一个致密层。将神经元数量和激活函数作为参数。

这些方法中的每一个都接受张量作为输入,并将转换的张量作为输出返回。这样可以轻松地将一层连接到另一层:只需从一个层创建方法获取输出,并将其作为输入提供给另一层。

打开cnn_mnist.py并添加以下cnn_model_fn功能,它符合TensorFlow的Estimator API预期的界面(稍后在创建估计器中)。cnn_mnist.py取MNIST特征数据,标签和 模型模式TRAINEVAL, INFER)作为参数; 配置CNN; 并返回预测,损失和培训操作:

def cnn_model_fn(features, labels, mode):   """Model function for CNN."""   # Input Layer   input_layer = tf.reshape(features, [-1, 28, 28, 1])     # Convolutional Layer #1   conv1 = tf.layers.conv2d(       inputs=input_layer,       filters=32,       kernel_size=[5, 5],       padding="same",       activation=tf.nn.relu)     # Pooling Layer #1   pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)     # Convolutional Layer #2 and Pooling Layer #2   conv2 = tf.layers.conv2d(       inputs=pool1,       filters=64,       kernel_size=[5, 5],       padding="same",       activation=tf.nn.relu)   pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2)     # Dense Layer   pool2_flat = tf.reshape(pool2, [-1, 7 * 7 * 64])   dense = tf.layers.dense(inputs=pool2_flat, units=1024, activation=tf.nn.relu)   dropout = tf.layers.dropout(       inputs=dense, rate=0.4, training=mode == learn.ModeKeys.TRAIN)     # Logits Layer   logits = tf.layers.dense(inputs=dropout, units=10)     loss = None   train_op = None     # Calculate Loss (for both TRAIN and EVAL modes)   if mode != learn.ModeKeys.INFER:     onehot_labels = tf.one_hot(indices=tf.cast(labels, tf.int32), depth=10)     loss = tf.losses.softmax_cross_entropy(         onehot_labels=onehot_labels, logits=logits)     # Configure the Training Op (for TRAIN mode)   if mode == learn.ModeKeys.TRAIN:     train_op = tf.contrib.layers.optimize_loss(         loss=loss,         global_step=tf.contrib.framework.get_global_step(),         learning_rate=0.001,         optimizer="SGD")     # Generate Predictions   predictions = {       "classes": tf.argmax(           input=logits, axis=1),       "probabilities": tf.nn.softmax(           logits, name="softmax_tensor")   }     # Return a ModelFnOps object   return model_fn_lib.ModelFnOps(       mode=mode, predictions=predictions, loss=loss, train_op=train_op)

以下部分(与上面的每个代码块对应的标题)深入了解tf.layers用于创建每个图层的代码,以及如何计算损失,配置训练操作和生成预测。如果您已经有CNN和TensorFlow的Estimator经验,并且直观地找到上述代码,您可能需要略过这些部分,或者跳过“训练和评估CNN MNIST分类器”。

输入层

layers用于为二维图像数据创建卷积和合并图层的模块中的方法期望输入张量具有如下定义的形状 :[batch_size,image_widthimage_heightchannels]

  • batch_size。在训练期间执行梯度下降时使用的示例子集的大小。
  • image_width。示例图像的宽度。
  • image_height。示例图像的高度。
  • channels。示例图像中的颜色通道数。对于彩色图像,通道数为3(红,绿,蓝)。对于单色图像,只有1个通道(黑色)。

在这里,我们的MNIST数据集由单色的28x28像素图像组成,因此我们的输入层所需的形状是。[batch_size, 28, 28, 1]

要将我们的输入要素map(features)转换为此形状,我们可以执行以下reshape操作:

input_layer = tf.reshape(features, [-1, 28, 28, 1])

请注意,我们已经指出-1了批量大小,其中规定了此维度应根据输入值的数量进行动态计算 features,并保持所有其他维度的大小不变。这允许我们将其视为batch_size可以调谐的超参数。例如,如果我们以5的批次向我们的模型中提供示例,features将包含3,920个值(每个图像中每个像素的一个值),并且input_layer将具有一个形状 [5, 28, 28, 1]。同样地,如果我们以100个批次的方式提供示例,features 将包含78,400个值,并且input_layer将具有一个形状[100, 28, 28, 1]。

卷积层#1

在我们的第一个卷积层中,我们要对输入层应用32个5x5滤波器,并具有一个ReLU激活功能。我们可以使用模块中的conv2d()方法 layers来创建这个层,如下所示:

conv1 = tf.layers.conv2d(     inputs=input_layer,     filters=32,     kernel_size=[5, 5],     padding="same",     activation=tf.nn.relu)

该inputs参数指定了输入张量,其中必须有形状 。在这里,我们将我们的第一个卷积层连接起来,它具有形状。[batch_size, image_width, image_height, channels] input_layer [batch_size, 28, 28, 1] 

注意:将接受传递参数时 的形状 。 conv2d() [channelsbatch_sizeimage_width,image_height] data_format=channels_first

所述filters参数指定的过滤器,以应用(这里,32)的数量,并且 kernel_size指定了作为过滤器的尺寸(此处,)。[widthheight] [5, 5]

提示:如果过滤器宽度和高度具有相同的值,则可以指定kernel_size-eg 的单个整数kernel_size=5

padding参数指定两个枚举值之一(不区分大小写):(valid默认值)或same。要指定输出张量应该与输入张量具有相同的宽度和高度值,我们padding=same在这里设置,它指示TensorFlow向输出张量的边缘添加0个值,以保持宽度和高度28.(无填充,a通过28x28张量的5x5卷积将产生24x24张量,因为有24x24个位置从28x28网格中提取5x5瓦。)

activation参数指定应用于卷积输出的激活函数。在这里,我们指定ReLU激活 tf.nn.relu

我们的输出张力conv2d()具有与输入相同的宽度和高度尺寸的形状 ,但现在有32个通道保持每个滤镜的输出。[batch_size, 28, 28, 32]

集合层#1

接下来,我们将我们的第一个池层连接到刚创建的卷积层。我们可以使用该max_pooling2d()方法layers来构建一个使用2x2过滤器执行最大池的层,并且步长为2:

pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)

再次inputs指定输入张量,形状为 。这里,我们的输入张量是来自第一卷积层的输出,其具有形状。[batch_size,image_width, image_height, channels] conv1 [batch_size, 28, 28, 32] 

注意:与此相反conv2d()max_pooling2d()将接受传递参数 的形状。[channelsbatch_sizeimage_width,image_height] data_format=channels_first

pool_size参数指定了最大池过滤器的大小 (这里)。如果两个维度的值都相同,则可以指定一个整数(例如, )。[widthheight] [2, 2] pool_size=2

strides参数指定步幅的大小。在这里,我们设置一个步长2,这表明由滤波器提取的子区域应在宽度和高度维度上分开2个像素(对于2x2滤镜,这意味着所提取的区域都不会重叠)。如果要为宽度和高度设置不同的步幅值,可以指定一个元组或列表(例如,stride=[3,6])。

我们的max_pooling2d()pool1)产生的输出张量具有以下形状 :2x2过滤器将宽度和高度降低了50%。[batch_size, 14, 14, 1]

卷积层#2和Pooling Layer#2

我们可以使用conv2d()max_pooling2d()之前一样将第二个卷积和汇集层连接到我们的CNN 。对于卷积层#2,我们使用ReLU激活配置64个5x5滤波器,对于池#2,我们使用与池化层1相同的规格(2 2×2最大池过滤器,步幅为2):

conv2 = tf.layers.conv2d(     inputs=pool1,     filters=64,     kernel_size=[5, 5],     padding="same",     activation=tf.nn.relu)   pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2)

注意,卷积层#2将第一个合并层(pool1)的输出张量作为输入,并产生张量h_conv2作为输出。conv2 具有与(由于)相同的宽度和高度的形状,并且应用64个滤波器的64个通道。[batch_size, 14, 14, 64] pool1 padding="same" 

汇集层#2 conv2作为输出,产生pool2输出。pool2 具有形状(宽度和高度减少50%)。[batch_size, 7, 7, 64] conv2

密集层

接下来,我们要为我们的CNN添加一个密集层(有1,024个神经元和ReLU激活),以对卷积/池层提取的特征进行分类。然而,在连接图层之前,我们将对我们的特征图(pool2)进行平坦化,使其张量只有两个维度:

[batch_size,features] pool2_flat = tf.reshape(pool2, [-1, 7 * 7 * 64])

reshape()上述操作中,-1该表示batch_size 尺寸将被动态地计算根据在我们的输入数据样本的数目。每个例子都有7(pool2宽)* 7(pool2高)* 64(pool2通道)功能,所以我们希望features维度的值为7 * 7 * 64(总共3136)。输出张量pool2_flat具有形状 。[batch_size, 3136]

现在我们可以使用这种dense()方法layers连接我们的密集层,如下所示:

dense = tf.layers.dense(inputs=pool2_flat, units=1024, activation=tf.nn.relu)

该inputs参数指定输入张:我们的扁平化特征图, pool2_flat。该units参数指定在致密层(1024)神经元的数目。该activation参数可使用的激活函数; 再次,我们将tf.nn.relu用来添加ReLU激活。

为了帮助改进我们的模型的结果,我们也应用了缺陷正则化到我们的密集层,使用下面的dropout方法layers

dropout = tf.layers.dropout(     inputs=dense, rate=0.4, training=mode == learn.ModeKeys.TRAIN)

再次,inputs指定输入张量,它是我们的密层(dense)的输出张量。

rate参数指定辍学率; 在这里,我们使用0.4,这意味着40%的元素将在训练期间随机退出。

training参数使用一个布尔值,指定模型当前是否正在训练模式下运行; 如果将只执行差 trainingTrue。在这里,我们检查mode传递给我们的模型函数 cnn_model_fn是否是TRAIN模式。

我们的输出张量dropout具有形状。[batch_size, 1024]

逻辑层

神经网络中的最后一层是逻辑层,它将返回我们预测的原始值。我们创建一个具有10个神经元的密集层(每个目标类别为0-9的一个),具有线性激活(默认):

logits = tf.layers.dense(inputs=dropout, units=10)

CNN的最终输出张量logits有所变化 。[batch_size, 10] 

计算损失

对于训练和评估,我们需要定义一个 损失函数 来衡量模型的预测与目标类的匹配程度。对于像MNIST这样的多类分类问题,通常将 交叉熵用作损失度量。以下代码在模型以任一模式运行TRAINEVAL模式运行时计算交叉熵:

loss = None train_op = None   # Calculate loss for both TRAIN and EVAL modes if mode != learn.ModeKeys.INFER:   onehot_labels = tf.one_hot(indices=tf.cast(labels, tf.int32), depth=10)   loss = tf.losses.softmax_cross_entropy(       onehot_labels=onehot_labels, logits=logits)

我们来仔细看看上面发生了什么。

我们的labels张量包含了我们的例子的预测列表,例如[1, 9, ...]。为了计算交叉熵,首先我们需要转换labels 为相应的 单热编码

[[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],  [0, 0, 0, 0, 0, 0, 0, 0, 0, 1],  ...]

我们使用该tf.one_hot功能来执行此转换。tf.one_hot()有两个必需的参数:
  • indices。在一个热张力中将具有“on值”的位置,即1上述张量中的值的位置。
  • depth。一个热张量的深度,即目标类的数量。在这里,深度是10

以下代码为我们的标签创建单张热张量onehot_labels

onehot_labels = tf.one_hot(indices=tf.cast(labels, tf.int32), depth=10)

因为labels包含从0-9的一系列值,indices只是我们的 labels张量,值被转换为整数。这depth是10因为我们有10个可能的目标类,每个数字一个。

接下来,我们onehot_labels从我们的逻辑层计算预测的交叉熵和softmax。tf.losses.softmax_cross_entropy()采取 onehot_labelslogits作为参数,执行softmax激活 logits,计算交叉熵,并将我们loss作为标量返回Tensor

loss = tf.losses.softmax_cross_entropy(         onehot_labels=onehot_labels, logits=logits)

配置训练操作

在上一节中,我们将CNN的损失定义为逻辑层和我们的标签的softmax交叉熵。让我们配置我们的模型,以便在训练过程中使用tf.contrib.layers.optimize_loss 方法来优化这个损失值 tf.contrib.layers。我们将使用0.001的学习率和 随机梯度下降 作为优化算法:

# Configure the Training Op (for TRAIN mode) if mode == learn.ModeKeys.TRAIN:     train_op = tf.contrib.layers.optimize_loss(         loss=loss,         global_step=tf.contrib.framework.get_global_step(),         learning_rate=0.001,         optimizer="SGD")

注意:有关对Estimator模型函数配置训练操作的更深入的了解,请参阅tf.contrib.learn中创建估计”教程中的“ 定义模型的训练操作

产生预测

我们的模型的逻辑层将我们的预测作为原始值在一 维张量中返回。让我们将这些原始值转换成我们的模型函数可以返回的两种不同格式:[batch_size, 10]

  • 每个例子的预测类:从0-9的数字。
  • 概率为每个实施例的每个可能的目标类:该示例是0的概率,是1,是2等

对于一个给定的例子,我们预测的类是具有最高原始值的对数张量的相应行中的元素。我们可以使用以下tf.argmax 函数找到该元素的索引:

tf.argmax(input=logits, axis=1)

input参数指定提取最大值的张量 - 这里logits。该axis参数指定的轴input 张量沿找到最大的价值。在这里,我们想要找到索引为1的维度上的最大值,这对应于我们的预测(回想我们的对数张量具有形状)。[batch_size, 10]

我们可以通过使用softmax激活从我们的对数层导出概率tf.nn.softmax

tf.nn.softmax(logits, name="softmax_tensor")

注意:我们使用name参数来明确地命名此操作 softmax_tensor,所以我们稍后可以引用它。(我们将在“设置日志钩”中为softmax值设置日志记录

我们在一个dict中编译我们的预测如下:

predictions = {     "classes": tf.argmax(         input=logits, axis=1),     "probabilities": tf.nn.softmax(         logits, name="softmax_tensor") }

最后,现在我们已经得到了我们predictions,loss和train_op我们能回报他们,与我们一起mode的说法,在一个tf.contrib.learn.ModelFnOps对象:

# Return a ModelFnOps object return model_fn_lib.ModelFnOps(     mode=mode, predictions=predictions, loss=loss, train_op=train_op)

训练和评估CNN MNIST分类器

我们编码了我们的MNIST CNN模型函数; 现在我们准备好训练和评估了。

负载训练和测试数据

首先,我们加载我们的培训和测试数据。使用以下代码添加一个main()函数 cnn_mnist.py

def main(unused_argv):   # Load training and eval data   mnist = learn.datasets.load_dataset("mnist")   train_data = mnist.train.images # Returns np.array   train_labels = np.asarray(mnist.train.labels, dtype=np.int32)   eval_data = mnist.test.images # Returns np.array   eval_labels = np.asarray(mnist.test.labels, dtype=np.int32)

我们存储和训练标记(从0-9的相应值对每个图像)作为训练特征数据(的手绘数字55000个图像的原始像素值)numpy的阵列 中train_data和train_labels分别。同样,我们的evalulation特征数据(10,000张)和评价的标签存储eval_data 和eval_labels分别。

创建估算器

接下来,我们Estimator为我们的模型创建一个(TensorFlow类来执行高级模型训练,评估和推断)。将以下代码添加到main()

# Create the Estimator mnist_classifier = learn.Estimator(       model_fn=cnn_model_fn, model_dir="/tmp/mnist_convnet_model")

该model_fn参数指定用于训练,评估和推断的模型函数; 我们通过cnn_model_fn我们在 “建立CNN MNIST分类器”中创建的。该 model_dir参数指定将保存模型数据(检查点)的目录(这里,我们指定临时目录/tmp/mnist_convnet_model,但随意更改为您选择的另一个目录)。

注意:有关TensorFlow EstimatorAPI 的深入了解,请参阅“在tf.contrib.learn中创建估计器”教程

设置日志钩

由于CNN可能需要一段时间才能进行培训,我们设置一些日志记录,以便跟踪培训过程中的进度。我们可以使用TensorFlow tf.train.SessionRunHook来创建一个 tf.train.LoggingTensorHook 将记录CNN的softmax层的概率值。将以下内容添加到main()

# Set up logging for predictions   tensors_to_log = {"probabilities": "softmax_tensor"}   logging_hook = tf.train.LoggingTensorHook(       tensors=tensors_to_log, every_n_iter=50)

我们存储我们要登录的张量的字母tensors_to_log。每个键是我们选择的标签,将打印在日志输出中,相应的标签是TensorTensorFlow图中的a的名称。在这里,我们 probabilities可以找到softmax_tensor,当我们生成概率时,我们早期提供了我们的softmax操作的名字cnn_model_fn。

注意:如果您没有通过name 参数明确指定操作的名称,TensorFlow将分配一个默认名称。几个简单的方法来发现应用于操作的名称是在TensorBoard上可视化图形 )或启用TensorFlow Debugger(tfdbg)

接下来,我们创建LoggingTensorHook,传递tensors_to_log给 tensors参数。我们设定every_n_iter=50,其中规定了每50个训练步骤后记录概率。

训练模型

现在,我们已经准备好训练我们的模型,我们可以通过调用做fit()的 mnist_classifier。将以下内容添加到main()

# Train the model mnist_classifier.fit(     x=train_data,     y=train_labels,     batch_size=100,     steps=20000,     monitors=[logging_hook])

在fit通话中,我们的训练特征数据和标签传递到x和y分别。我们设置batch_size的100(这意味着该模型将在每个步骤上的100个例子minibatches培养),和steps的20000 (这意味着该模型将20,000步骤的总训练)。我们通过我们logging_hook的monitors论证,以便在培训期间触发。

评估模型

培训完成后,我们要评估我们的模型,以确定其在MNIST测试集上的准确性。要设置我们的模型的精度指标,我们需要创建一个计量tf.contrib.learn.MetricSpec 精度的指标。将以下内容添加到main()

# Configure the accuracy metric for evaluation metrics = {     "accuracy":         learn.MetricSpec(             metric_fn=tf.metrics.accuracy, prediction_key="classes"), }

我们创建了我们MetricSpec的以下两个参数:
  • metric_fn。计算和返回度量值的函数。在这里,我们可以使用模块中的预定义accuracy功能 tf.metrics
  • prediction_key。包含模型函数返回的预测的张量的关键。在这里,因为我们正在建立分类模型"classes",所以我们在“生成预测”中指定了预测键

现在我们已经设置了我们的metricsdict,我们可以评估模型。添加以下代码,执行评估并打印结果:

# Evaluate the model and print results eval_results = mnist_classifier.evaluate(     x=eval_data, y=eval_labels, metrics=metrics) print(eval_results)

我们通过我们的评估特征数据和标签来evaluate()在x和 y分别论据。这个metrics论点取决于我们刚刚定义的指标。

运行模型

我们编写了CNN模型函数Estimator,以及训练/评估逻辑; 现在我们来看看结果。运行cnn_mnist.py

注意:训练CNN是相当计算密集型的。预计完成时间cnn_mnist.py将根据您的处理器而有所不同,但CPU可能会长达1小时。要更快地训练,您可以减少steps传递的数量fit(),但请注意,这将影响精度。

作为模型列车,您将看到如下所示的日志输出:

INFO:tensorflow:loss = 2.36026, step = 1 INFO:tensorflow:probabilities = [[ 0.07722801  0.08618255  0.09256398, ...]] ... INFO:tensorflow:loss = 2.13119, step = 101 INFO:tensorflow:global_step/sec: 5.44132 ... INFO:tensorflow:Loss for final step: 0.553216.   INFO:tensorflow:Restored model from /tmp/mnist_convnet_model INFO:tensorflow:Eval steps [0,inf) for training step 20000. INFO:tensorflow:Input iterator is exhausted. INFO:tensorflow:Saving evaluation summary for step 20000: accuracy = 0.9733, loss = 0.0902271 {'loss': 0.090227105, 'global_step': 20000, 'accuracy': 0.97329998}

在这里,我们的测试数据集达到了97.3%的准确度。

其他资源

要了解有关TensorFlow中TensorFlow估计器和CNN的更多信息,请参阅以下资源:

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏梦里茶室

Google机器学习笔记(七)TF.Learn 手写文字识别

mnist问题 计算机视觉领域的Hello world 给定55000个图片,处理成28*28的二维矩阵,矩阵中每个值表示一个像素点的灰度,作为feature...

2389
来自专栏人工智能LeadAI

一文初探Tensorflow高级API使用(初学者篇)

今天我们要向Tensorflow高级API的学习门槛迈进一步。别听到高级API就觉得是难度高的意思,其实高级API恰恰是为了降低大家的编码难度而设置的。Tens...

4237
来自专栏人工智能LeadAI

TF.Learn 手写文字识别

minist问题 计算机视觉领域的Hello world 给定55000个图片,处理成28*28的二维矩阵,矩阵中每个值表示一个像素点的灰度,作为feature...

3456
来自专栏WD学习记录

2016-7-3 webGL

ctx.fillRect(120,10,150,150);前两个为x、y坐标后边为长和宽

672
来自专栏fangyangcoder

tensorflow笔记(五)之MNIST手写识别系列二

http://www.cnblogs.com/fydeblog/p/7455233.html

642
来自专栏计算机视觉与深度学习基础

计算机视觉与图像处理学习笔记(一)

写在前面:因学习需要,本人根据章毓晋的《计算机视觉教程》和冈萨雷斯的《数字图像处理》两本书进行学习,中间会穿插相关实践,会有对opencv的学习,以此笔记记录学...

2036
来自专栏人工智能LeadAI

TF使用例子-情感分类

这次改写一下,做一个简单的分类模型和探讨一下hidden layer在聚类的应用场景下会有什么效果。为了能写的尽可能让读者理解,本文也会写一下keras来实现(...

4363
来自专栏目标检测和深度学习

从零开始PyTorch项目:YOLO v3目标检测实现

在过去几个月中,我一直在实验室中研究提升目标检测的方法。在这之中我获得的最大启发就是意识到:学习目标检测的最佳方法就是自己动手实现这些算法,而这正是本教程引导你...

20211
来自专栏机器之心

从零开始PyTorch项目:YOLO v3目标检测实现

选自Medium 作者:Ayoosh Kathuria 机器之心编译 目标检测是深度学习近期发展过程中受益最多的领域。随着技术的进步,人们已经开发出了很多用于目...

8995
来自专栏数据结构与算法

T7315 yyy矩阵折叠(长)

题目背景 全场基本暴零 题目描述 ? 输入输出格式 输入格式: 如图 输出格式: 如图 输入输出样例 输入样例#1: 2 2 1 -2 3 -4 输出样例...

2646

扫码关注云+社区