教程 | TensorEditor :一個小白都能快速玩轉的神經網路搭建工具

機器之心發表於2019-03-02

近日,機器之心發現一個非常有意思的工具,可以用視覺化的方式輕鬆新增摺積層、全連線層和池化層等層級,然後生成可執行的 TensorFlow 程式碼。此外,我們也嘗試搭建一個簡單的卷積架構,並在本地 TensorFlow 環境下測試生成的程式碼。


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


TensorEditor 是一個強大的機器學習工具,甚至小白都能以視覺化的方式快速生成整個模型的程式碼。通過 TensorEditor,小白可以連線卷積層、全連線層和池化層等視覺化結點建立整個模型,且我們可以將它們轉化為 TensorFlow 和 Python 程式碼,並進一步在自己的環境中執行。


基本上,TensorEditor 的步驟即定義我們的資料集、影象或特徵,然後建立深度神經網路並下載 Python 2.7 的程式碼,最後就需要在我們自己的 TensorFLow 環境下執行就好了。


通過 TensorEditor,我們不僅可以建立深度網路並避免一些常見的程式碼問題,同時還能生成基於 TensorFlow Estimator 的高效程式碼。如下所示,機器之心嘗試構建了一個簡單的卷積網路,我們使用了兩個卷積層、兩個池化層和一個全連線層,並在最後的 Estimator 使用了交叉熵損失函式和 Adagrad 最優化方法。


教程 | TensorEditor :一個小白都能快速玩轉的神經網路搭建工具


上述簡單搭建的卷積網路同樣可以生成完全可執行的程式碼,這樣可以避免大量的一般程式碼問題與重複性工作。


import tensorflow as tfimport pandas as pdtf.logging.set_verbosity(tf.logging.INFO)project_name="CNN"train_csv_file=""test_csv_file=""image_resize=[28,28]def model_fn(features, labels, mode, params):    convolutional_2d_1 = tf.layers.conv2d(            inputs=features,            filters=32,            kernel_size=[3,3],            strides=(1,1),            padding="same",            data_format="channels_last",            dilation_rate=(1,1),            activation=tf.nn.relu,            use_bias=True)    max_pool_2d_1 = tf.layers.max_pooling2d(        inputs=convolutional_2d_1,        pool_size=[2,2],        strides=[2,2],        padding='same',        data_format='channels_last')    convolutional_2d_2 = tf.layers.conv2d(            inputs=max_pool_2d_1,            filters=64,            kernel_size=[3,3],            strides=(1,1),            padding="same",            data_format="channels_last",            dilation_rate=(1,1),            activation=tf.nn.relu,            use_bias=True)    max_pool_2d_2 = tf.layers.max_pooling2d(        inputs=max_pool_2d_1,        pool_size=[2,2],        strides=[2,2],        padding='same',        data_format='channels_last')    convolutional_2d_3 = tf.layers.conv2d(            inputs=max_pool_2d_2,            filters=128,            kernel_size=[3,3],            strides=(1,1),            padding="same",            data_format="channels_last",            dilation_rate=(1,1),            activation=tf.nn.relu,            use_bias=True)    max_pool_2d_3 = tf.layers.max_pooling2d(        inputs=convolutional_2d_3,        pool_size=[2,2],        strides=[2,2],        padding='same',        data_format='channels_last')    flatten_1 = tf.reshape(max_pool_2d_3, [-1, 2048])    dense_1 = tf.layers.dense(inputs=flatten_1, units=1024, activation=tf.nn.relu)    dropout_1= tf.layers.dropout(inputs=dense_1, rate=0.4, training=mode == tf.estimator.ModeKeys.TRAIN)    dense_2 = tf.layers.dense(inputs=dropout_1, units=256, activation=tf.nn.relu)    logits=dense_2    predictions = {        "classes": tf.argmax(input=logits, axis=1),        "probabilities": tf.nn.softmax(logits, name="softmax_tensor")    }    #Prediction and training    if mode == tf.estimator.ModeKeys.PREDICT:        return tf.estimator.EstimatorSpec(mode=mode, predictions=predictions)    # Calculate Loss (for both TRAIN and EVAL modes)    onehot_labels = tf.one_hot(indices=tf.cast(labels, tf.int32), depth=256)    loss = tf.losses.softmax_cross_entropy(        onehot_labels=onehot_labels, logits=logits)    # Compute evaluation metrics.    accuracy = tf.metrics.accuracy(labels=labels,                                   predictions=predictions["classes"],                                   name='acc_op')    metrics = {'accuracy': accuracy}    tf.summary.scalar('accuracy', accuracy[1])    # Configure the Training Op (for TRAIN mode)    if mode == tf.estimator.ModeKeys.TRAIN:        optimizer = tf.train.AdagradOptimizer(learning_rate=0.001)        train_op = optimizer.minimize(            loss=loss,            global_step=tf.train.get_global_step())        return tf.estimator.EstimatorSpec(mode=mode, loss=loss, train_op=train_op)    # Add evaluation metrics (for EVAL mode)    eval_metric_ops = {        "accuracy": tf.metrics.accuracy(            labels=labels, predictions=predictions["classes"])}    return tf.estimator.EstimatorSpec(        mode=mode, loss=loss, eval_metric_ops=eval_metric_ops)# Parse CSV input file and resize imagedef _parse_csv(line):    parsed_line= tf.decode_csv(line, [[""], []])    filename = parsed_line[0]    label = parsed_line[1]    image_string = tf.read_file(filename)    image_decoded = tf.image.decode_jpeg(image_string, channels=3)    image_resized = tf.image.resize_images(image_decoded, image_resize)    image_gray = tf.image.rgb_to_grayscale(image_resized)    return image_gray, labeldef data_train_estimator():    dataset = tf.data.TextLineDataset(train_csv_file).map(_parse_csv)  # Map each line to convert the data    dataset = dataset.batch(100)    dataset = dataset.shuffle(1000)    dataset = dataset.repeat()    iterator = dataset.make_one_shot_iterator()  # create one shot iterator    feature, label = iterator.get_next()    return feature, labeldef data_test_estimator():    dataset = tf.data.TextLineDataset(test_csv_file).map(_parse_csv)  # Map each line to convert the data    dataset = dataset.batch(100)    iterator = dataset.make_one_shot_iterator()  # create one shot iterator    feature, label = iterator.get_next()    return feature, labeldef main(unused_argv):    # MAIN ENTRY    # Create the Estimator    classifier = tf.estimator.Estimator(        model_fn=model_fn,         model_dir="/tmp/"+project_name,        params={            # PARAMS        }    )    classifier.train(input_fn=data_train_estimator, steps=30000)    eval_results = classifier.evaluate(input_fn=data_test_estimator)    tf.summary.scalar("Accuracy", eval_results["accuracy"])    print(eval_results)if __name__ == "__main__":    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 模組,並設定損失函式、最優化方法和學習率等配置就能完成架構上的搭建。如下所示為使用視覺化方法搭建的架構:


教程 | TensorEditor :一個小白都能快速玩轉的神經網路搭建工具


最後上面的網路就能生成對應的程式碼,我們可直接複製到原生程式碼編輯器中並執行:


教程 | TensorEditor :一個小白都能快速玩轉的神經網路搭建工具


本文為機器之心整理,轉載請聯絡本公眾號獲得授權


相關文章