教程 | TensorEditor :一個小白都能快速玩轉的神經網路搭建工具
機器之心整理
參與:思源
近日,機器之心發現一個非常有意思的工具,可以用可視化的方式輕鬆添加卷積層、全連接層和池化層等層級,然後生成可執行的 TensorFlow 代碼。此外,我們也嘗試搭建一個簡單的卷積架構,並在本地 TensorFlow 環境下測試生成的代碼。
工具地址:https://www.tensoreditor.com/
TensorEditor 是一個強大的機器學習工具,甚至小白都能以可視化的方式快速生成整個模型的代碼。通過 TensorEditor,小白可以連接卷積層、全連接層和池化層等可視化結點創建整個模型,且我們可以將它們轉化為 TensorFlow 和 Python 代碼,並進一步在自己的環境中運行。
基本上,TensorEditor 的步驟即定義我們的數據集、圖像或特徵,然後創建深度神經網路並下載 Python 2.7 的代碼,最後就需要在我們自己的 TensorFLow 環境下運行就好了。
通過 TensorEditor,我們不僅可以創建深度網路並避免一些常見的代碼問題,同時還能生成基於 TensorFlow Estimator 的高效代碼。如下所示,機器之心嘗試構建了一個簡單的卷積網路,我們使用了兩個卷積層、兩個池化層和一個全連接層,並在最後的 Estimator 使用了交叉熵損失函數和 Adagrad 最優化方法。
上述簡單搭建的卷積網路同樣可以生成完全可執行的代碼,這樣可以避免大量的一般代碼問題與重複性工作。
import
tensorflow as tf
import
pandas as pd
tf
.
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 image
def _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
,
label
def 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
,
label
def 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
,
label
def 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 模塊,並設置損失函數、最優化方法和學習率等配置就能完成架構上的搭建。如下所示為使用可視化方法搭建的架構:
最後上面的網路就能生成對應的代碼,我們可直接複製到本地代碼編輯器中並執行:
本文為機器之心整理,
轉載請聯繫本公眾號獲得授權
。?------------------------------------------------
加入機器之心(全職記者/實習生):hr@jiqizhixin.com
投稿或尋求報道:
content
@jiqizhixin.com廣告&商務合作:bd@jiqizhixin.com
※想入門設計卷積神經網路?這是一份綜合設計指南
※無需額外硬體,全卷積網路讓機器學習學會夜視能力
TAG:機器之心 |