参与蒋思源

TensorEditor :一个小白都能快速玩转的神经网络搭建工具

近日,机器之心发现一个非常有意思的工具,可以用可视化的方式轻松添加卷积层、全连接层和池化层等层级,然后生成可执行的 TensorFlow 代码。此外,我们也尝试搭建一个简单的卷积架构,并在本地 TensorFlow 环境下测试生成的代码。

工具地址:https://www.tensoreditor.com/

TensorEditor 是一个强大的机器学习工具,甚至小白都能以可视化的方式快速生成整个模型的代码。通过 TensorEditor,小白可以连接卷积层、全连接层和池化层等可视化结点创建整个模型,且我们可以将它们转化为 TensorFlow 和 Python 代码,并进一步在自己的环境中运行。

基本上,TensorEditor 的步骤即定义我们的数据集、图像或特征,然后创建深度神经网络并下载 Python 2.7 的代码,最后就需要在我们自己的 TensorFLow 环境下运行就好了。

通过 TensorEditor,我们不仅可以创建深度网络并避免一些常见的代码问题,同时还能生成基于 TensorFlow Estimator 的高效代码。如下所示,机器之心尝试构建了一个简单的卷积网络,我们使用了两个卷积层、两个池化层和一个全连接层,并在最后的 Estimator 使用了交叉熵损失函数和 Adagrad 最优化方法。

上述简单搭建的卷积网络同样可以生成完全可执行的代码,这样可以避免大量的一般代码问题与重复性工作。

  1. import tensorflow as tf

  2. import pandas as pd

  3. tf.logging.set_verbosity(tf.logging.INFO)

  4. project_name="CNN"

  5. train_csv_file=""

  6. test_csv_file=""

  7. image_resize=[28,28]

  8. def model_fn(features, labels, mode, params):

  9.    convolutional_2d_1 = tf.layers.conv2d(

  10.            inputs=features,

  11.            filters=32,

  12.            kernel_size=[3,3],

  13.            strides=(1,1),

  14.            padding="same",

  15.            data_format="channels_last",

  16.            dilation_rate=(1,1),

  17.            activation=tf.nn.relu,

  18.            use_bias=True)

  19.    max_pool_2d_1 = tf.layers.max_pooling2d(

  20.        inputs=convolutional_2d_1,

  21.        pool_size=[2,2],

  22.        strides=[2,2],

  23.        padding='same',

  24.        data_format='channels_last')

  25.    convolutional_2d_2 = tf.layers.conv2d(

  26.            inputs=max_pool_2d_1,

  27.            filters=64,

  28.            kernel_size=[3,3],

  29.            strides=(1,1),

  30.            padding="same",

  31.            data_format="channels_last",

  32.            dilation_rate=(1,1),

  33.            activation=tf.nn.relu,

  34.            use_bias=True)

  35.    max_pool_2d_2 = tf.layers.max_pooling2d(

  36.        inputs=max_pool_2d_1,

  37.        pool_size=[2,2],

  38.        strides=[2,2],

  39.        padding='same',

  40.        data_format='channels_last')

  41.    convolutional_2d_3 = tf.layers.conv2d(

  42.            inputs=max_pool_2d_2,

  43.            filters=128,

  44.            kernel_size=[3,3],

  45.            strides=(1,1),

  46.            padding="same",

  47.            data_format="channels_last",

  48.            dilation_rate=(1,1),

  49.            activation=tf.nn.relu,

  50.            use_bias=True)

  51.    max_pool_2d_3 = tf.layers.max_pooling2d(

  52.        inputs=convolutional_2d_3,

  53.        pool_size=[2,2],

  54.        strides=[2,2],

  55.        padding='same',

  56.        data_format='channels_last')

  57.    flatten_1 = tf.reshape(max_pool_2d_3, [-1, 2048])

  58.    dense_1 = tf.layers.dense(inputs=flatten_1, units=1024, activation=tf.nn.relu)

  59.    dropout_1= tf.layers.dropout(inputs=dense_1, rate=0.4, training=mode == tf.estimator.ModeKeys.TRAIN)

  60.    dense_2 = tf.layers.dense(inputs=dropout_1, units=256, activation=tf.nn.relu)

  61.    logits=dense_2

  62.    predictions = {

  63.        "classes": tf.argmax(input=logits, axis=1),

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

  65.    }

  66.    #Prediction and training

  67.    if mode == tf.estimator.ModeKeys.PREDICT:

  68.        return tf.estimator.EstimatorSpec(mode=mode, predictions=predictions)

  69.    # Calculate Loss (for both TRAIN and EVAL modes)

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

  71.    loss = tf.losses.softmax_cross_entropy(

  72.        onehot_labels=onehot_labels, logits=logits)

  73.    # Compute evaluation metrics.

  74.    accuracy = tf.metrics.accuracy(labels=labels,

  75.                                   predictions=predictions["classes"],

  76.                                   name='acc_op')

  77.    metrics = {'accuracy': accuracy}

  78.    tf.summary.scalar('accuracy', accuracy[1])

  79.    # Configure the Training Op (for TRAIN mode)

  80.    if mode == tf.estimator.ModeKeys.TRAIN:

  81.        optimizer = tf.train.AdagradOptimizer(learning_rate=0.001)

  82.        train_op = optimizer.minimize(

  83.            loss=loss,

  84.            global_step=tf.train.get_global_step())

  85.        return tf.estimator.EstimatorSpec(mode=mode, loss=loss, train_op=train_op)

  86.    # Add evaluation metrics (for EVAL mode)

  87.    eval_metric_ops = {

  88.        "accuracy": tf.metrics.accuracy(

  89.            labels=labels, predictions=predictions["classes"])}

  90.    return tf.estimator.EstimatorSpec(

  91.        mode=mode, loss=loss, eval_metric_ops=eval_metric_ops)

  92. # Parse CSV input file and resize image

  93. def _parse_csv(line):

  94.    parsed_line= tf.decode_csv(line, [[""], []])

  95.    filename = parsed_line[0]

  96.    label = parsed_line[1]

  97.    image_string = tf.read_file(filename)

  98.    image_decoded = tf.image.decode_jpeg(image_string, channels=3)

  99.    image_resized = tf.image.resize_images(image_decoded, image_resize)

  100.    image_gray = tf.image.rgb_to_grayscale(image_resized)

  101.    return image_gray, label

  102. def data_train_estimator():

  103.    dataset = tf.data.TextLineDataset(train_csv_file).map(_parse_csv)  # Map each line to convert the data

  104.    dataset = dataset.batch(100)

  105.    dataset = dataset.shuffle(1000)

  106.    dataset = dataset.repeat()

  107.    iterator = dataset.make_one_shot_iterator()  # create one shot iterator

  108.    feature, label = iterator.get_next()

  109.    return feature, label

  110. def data_test_estimator():

  111.    dataset = tf.data.TextLineDataset(test_csv_file).map(_parse_csv)  # Map each line to convert the data

  112.    dataset = dataset.batch(100)

  113.    iterator = dataset.make_one_shot_iterator()  # create one shot iterator

  114.    feature, label = iterator.get_next()

  115.    return feature, label

  116. def main(unused_argv):

  117.    # MAIN ENTRY

  118.    # Create the Estimator

  119.    classifier = tf.estimator.Estimator(

  120.        model_fn=model_fn,

  121.        model_dir="/tmp/"+project_name,

  122.        params={

  123.            # PARAMS

  124.        }

  125.    )

  126.    classifier.train(input_fn=data_train_estimator, steps=30000)

  127.    eval_results = classifier.evaluate(input_fn=data_test_estimator)

  128.    tf.summary.scalar("Accuracy", eval_results["accuracy"])

  129.    print(eval_results)

  130. if __name__ == "__main__":

  131.     tf.app.run()

TensorEditor 主要有以下特点:

  • 易于使用:我们只需要添加模块、连接模块并在最后加入评估模块,就能完成搭建。

  • 由易到难:只需要叠加不同的模块,我们就能创建如 VGG 那样的复杂深度网络。

  • 参数直观:可以轻松修改各结点的配置与参数,从而搭建定制化的深度网络。

  • 生成代码:搭建完深度架构,我们就能直接生成可执行的 TensorFlow 代码(Python 2.7)。

90 秒的 MNIST 教程

在上面的视频中,开发者展示了如何使用 TensorEditor 在 90 秒内快速搭建一个可用于 MNIST 手写数字识别的简单网络。对于 TensorEditor 这种构建序贯 CNN 模型的简单工具,我们只需要准备两件事就能开始搭建模型模型:

  • 下载 MNIST 手写数据集:https://github.com/damiles/TensorEditor_SampleData/raw/master/mnist_png.tar.gz

  • 确定网络架构:https://www.tensorflow.org/tutorials/layers#building_the_cnn_mnist_classifier

TensorEditor 接受 CSV 格式的特征数据集或具有 CSV 标签的图像数据集作为数据输入,并且需要训练和测试/评估两个 CSV 文件。当我们从上面的链接下载数据集并提取图像数据时,我们会有两个 CSV 文件和两个包含所有图像的文件夹(测试和训练)。

现在我们就可以在 TensorEditor 中创建将要用于手写数字识别的卷积网络架构,下面展示的架构和 TensorFlow 文档中保持一致。

  • 卷积层 1:使用 32 个 5x5 大小的卷积核和 ReLU 激活函数

  • 池化层 1:使用 2x2 滤波器和步幅为 2 的最大池化运算(池化区域不重叠)

  • 卷积层 2:使用 64 个 5x5 大小的卷积核和 ReLU 激活函数

  • 池化层 2:同样使用 2x2 滤波器和步幅为 2 的最大池化运算

  • 全连接层 1:1024 个神经元,Dropout 正则化率为 0.4

  • 分类层:10 个神经元,每个神经元表示 0 到 9 这十个数字。

我们只需要按步骤先添加一个输入 csv 数据集模块,并设置 train.csv 和 test.csv 的地址。然后依次添加上述的卷积和全连接等模块,并设置好对应的参数,如卷积核大小、卷积核数量和激活函数等。最后主需要添加 Estimator 模块,并设置损失函数、最优化方法和学习率等配置就能完成架构上的搭建。如下所示为使用可视化方法搭建的架构:

最后上面的网络就能生成对应的代码,我们可直接复制到本地代码编辑器中并执行:

工程TensorFlow
22
相关数据
池化技术

池化(Pooling)是卷积神经网络中的一个重要的概念,它实际上是一种形式的降采样。有多种不同形式的非线性池化函数,而其中“最大池化(Max pooling)”是最为常见的。它是将输入的图像划分为若干个矩形区域,对每个子区域输出最大值。直觉上,这种机制能够有效的原因在于,在发现一个特征之后,它的精确位置远不及它和其他特征的相对位置的关系重要。池化层会不断地减小数据的空间大小,因此参数的数量和计算量也会下降,这在一定程度上也控制了过拟合。通常来说,CNN的卷积层之间都会周期性地插入池化层。

激活函数技术

在 计算网络中, 一个节点的激活函数定义了该节点在给定的输入或输入的集合下的输出。标准的计算机芯片电路可以看作是根据输入得到"开"(1)或"关"(0)输出的数字网络激活函数。这与神经网络中的线性感知机的行为类似。 一种函数(例如 ReLU 或 S 型函数),用于对上一层的所有输入求加权和,然后生成一个输出值(通常为非线性值),并将其传递给下一层。

交叉熵技术

交叉熵(Cross Entropy)是Loss函数的一种(也称为损失函数或代价函数),用于描述模型预测值与真实值的差距大小

机器学习技术

机器学习是人工智能的一个分支,是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、计算复杂性理论等多门学科。机器学习理论主要是设计和分析一些让计算机可以自动“学习”的算法。因为学习算法中涉及了大量的统计学理论,机器学习与推断统计学联系尤为密切,也被称为统计学习理论。算法设计方面,机器学习理论关注可以实现的,行之有效的学习算法。

参数技术

在数学和统计学裡,参数(英语:parameter)是使用通用变量来建立函数和变量之间关系(当这种关系很难用方程来阐述时)的一个数量。

学习率技术

在使用不同优化器(例如随机梯度下降,Adam)神经网络相关训练中,学习速率作为一个超参数控制了权重更新的幅度,以及训练的速度和精度。学习速率太大容易导致目标(代价)函数波动较大从而难以找到最优,而弱学习速率设置太小,则会导致收敛过慢耗时太长

损失函数技术

在数学优化,统计学,计量经济学,决策理论,机器学习和计算神经科学等领域,损失函数或成本函数是将一或多个变量的一个事件或值映射为可以直观地表示某种与之相关“成本”的实数的函数。

TensorFlow技术

TensorFlow是一个开源软件库,用于各种感知和语言理解任务的机器学习。目前被50个团队用于研究和生产许多Google商业产品,如语音识别、Gmail、Google 相册和搜索,其中许多产品曾使用过其前任软件DistBelief。

张量技术

张量是一个可用来表示在一些矢量、标量和其他张量之间的线性关系的多线性函数,这些线性关系的基本例子有内积、外积、线性映射以及笛卡儿积。其坐标在 维空间内,有 个分量的一种量,其中每个分量都是坐标的函数,而在坐标变换时,这些分量也依照某些规则作线性变换。称为该张量的秩或阶(与矩阵的秩和阶均无关系)。 在数学里,张量是一种几何实体,或者说广义上的“数量”。张量概念包括标量、矢量和线性算子。张量可以用坐标系统来表达,记作标量的数组,但它是定义为“不依赖于参照系的选择的”。张量在物理和工程学中很重要。例如在扩散张量成像中,表达器官对于水的在各个方向的微分透性的张量可以用来产生大脑的扫描图。工程上最重要的例子可能就是应力张量和应变张量了,它们都是二阶张量,对于一般线性材料他们之间的关系由一个四阶弹性张量来决定。

准确率技术

分类模型的正确预测所占的比例。在多类别分类中,准确率的定义为:正确的预测数/样本总数。 在二元分类中,准确率的定义为:(真正例数+真负例数)/样本总数

规范化技术

规范化:将属性数据按比例缩放,使之落入一个小的特定区间,如-1.0 到1.0 或0.0 到1.0。 通过将属性数据按比例缩放,使之落入一个小的特定区间,如0.0到1.0,对属性规范化。对于距离度量分类算法,如涉及神经网络或诸如最临近分类和聚类的分类算法,规范化特别有用。如果使用神经网络后向传播算法进行分类挖掘,对于训练样本属性输入值规范化将有助于加快学习阶段的速度。对于基于距离的方法,规范化可以帮助防止具有较大初始值域的属性与具有较小初始值域的属相相比,权重过大。有许多数据规范化的方法,包括最小-最大规范化、z-score规范化和按小数定标规范化。

神经元技术

(人工)神经元是一个类比于生物神经元的数学计算模型,是神经网络的基本组成单元。 对于生物神经网络,每个神经元与其他神经元相连,当它“兴奋”时会向相连的神经元发送化学物质,从而改变这些神经元的电位;神经元的“兴奋”由其电位决定,当它的电位超过一个“阈值”(threshold)便会被激活,亦即“兴奋”。 目前最常见的神经元模型是基于1943年 Warren McCulloch 和 Walter Pitts提出的“M-P 神经元模型”。 在这个模型中,神经元通过带权重的连接接处理来自n个其他神经元的输入信号,其总输入值将与神经元的阈值进行比较,最后通过“激活函数”(activation function)产生神经元的输出。

深度神经网络技术

深度神经网络(DNN)是深度学习的一种框架,它是一种具备至少一个隐层的神经网络。与浅层神经网络类似,深度神经网络也能够为复杂非线性系统提供建模,但多出的层次为模型提供了更高的抽象层次,因而提高了模型的能力。

优化器技术

优化器基类提供了计算梯度loss的方法,并可以将梯度应用于变量。优化器里包含了实现了经典的优化算法,如梯度下降和Adagrad。 优化器是提供了一个可以使用各种优化算法的接口,可以让用户直接调用一些经典的优化算法,如梯度下降法等等。优化器(optimizers)类的基类。这个类定义了在训练模型的时候添加一个操作的API。用户基本上不会直接使用这个类,但是你会用到他的子类比如GradientDescentOptimizer, AdagradOptimizer, MomentumOptimizer(tensorflow下的优化器包)等等这些算法。

推荐文章
你好~我 有些问题想请教 你可以嘛
机器之心(北京)科技有限公司・编辑
请说