《我的PaddlePaddle學習之路》筆記十二——視覺化工具VisualDL的使用
目錄
前言
VisualDL是一個面向深度學習任務設計的視覺化工具,包含了scalar、引數分佈、模型結構、影象視覺化等功能。可以這樣說:“所見即所得”。我們可以藉助VisualDL來觀察我們訓練的情況,方便我們對訓練的模型進行分析,改善模型的收斂情況。
之前我們使用的paddle.v2.plot
介面,也可以觀察訓練的情況,但是隻是支援CSOT的折線圖而已。而VisualDL可以支援一下這個功能:
scalar
,趨勢圖,可用於訓練測試誤差的展示
image
, 圖片的視覺化,可用於卷積層或者其他引數的圖形化展示
histogram
, 用於引數分佈及變化趨勢的展示
graph
,用於訓練模型結構的視覺化
以上的影象來自VisualDL的Github
既然那麼方便,那麼我們就來嘗試一下吧。VisualDL底層採用C++編寫,但是它在提供C++ SDK的同時,也支援Python SDK,我們主要是使用Python的SDK。順便說一下,VisualDL除了支援PaddlePaddle,之外,還支援pytorch, mxnet在內的大部分主流DNN平臺。
VisualDL的安裝
本章只講述在Ubuntu系統上的安裝和使用,Mac的操作應該也差不多。
使用pip安裝
使用pip安裝非常簡單,只要一條命令就夠了,如下:
pip install --upgrade visualdl
測試一下是否安裝成功了,執行一個例子下載日誌檔案:
# 在當前位置下載一個日誌
vdl_create_scratch_log
# 如果提示命令不存在,那就使用下面這條命令
vdl_scratch.py
然後再輸入,啟動VisualDL並載入這個日誌資訊:
visualdl --logdir ./scratch_log --port 8080
這裡說明一下,visualDL的引數:
host
設定IPport
設定埠model_pb
指定 ONNX 格式的模型檔案,這木方我們還沒要用到
注意: 如果是報以下的錯誤,那是因為protobuf版本過低的原因。
root@test:/home/test/VisualDL# visualdl --logdir ./scratch_log --port 8080
Traceback (most recent call last):
File "/usr/local/bin/visualdl", line 29, in <module>
import visualdl.server.graph as vdl_graph
File "/usr/local/lib/python2.7/dist-packages/visualdl/server/graph.py", line 23, in <module>
from . import onnx
File "/usr/local/lib/python2.7/dist-packages/visualdl/server/onnx/__init__.py", line 8, in <module>
from .onnx_pb2 import ModelProto
File "/usr/local/lib/python2.7/dist-packages/visualdl/server/onnx/onnx_pb2.py", line 213, in <module>
options=None, file=DESCRIPTOR),
TypeError: __init__() got an unexpected keyword argument 'file'
protobuf的版本要不小於3.5.0,如何小於這個版本可以使用以下命令升級:
pip install protobuf -U
然後在瀏覽器上輸入:
http://127.0.0.1:8080
即可看到一個視覺化的介面,如下:
使用原始碼安裝
如果讀者出於各種情況,使用pip安裝不能滿足需求,那可以考慮使用原始碼安裝VisualDL,操作如下:
首先要安裝依賴庫:
# 安裝npm
apt install npm
# 安裝node
apt install nodejs-legacy
# 安裝cmake
apt install cmake
# 安裝unzip
apt install unzip
然後在GitHub上clone最新的原始碼並開啟:
git clone https://github.com/PaddlePaddle/VisualDL.git
cd VisualDL
之後是編譯生成whl
安裝包:
python setup.py bdist_wheel
生成whl
安裝包之後,就可以使用pip命令安裝這個安裝包了,*
號對應的是visualdl版本號,讀者要根據實際情況來安裝:
pip install --upgrade dist/visualdl-*.whl
安裝完成之後,同樣可以使用在上一部分的使用pip安裝的測試方法測試安裝是否成功。
簡單使用VisualDL
我們編寫下面這一小段的程式碼來學習VisualDL的使用,程式碼如下:
# coding=utf-8
# 匯入VisualDL的包
from visualdl import LogWriter
# 建立一個LogWriter,第一個引數是指定存放資料的路徑,
# 第二個引數是指定多少次寫操作執行一次記憶體到磁碟的資料持久化
logw = LogWriter("./random_log", sync_cycle=10000)
# 建立訓練和測試的scalar圖,
# mode是標註線條的名稱,
# scalar標註的是指定這個元件的tag
with logw.mode('train') as logger:
scalar0 = logger.scalar("scratch/scalar")
with logw.mode('test') as logger:
scalar1 = logger.scalar("scratch/scalar")
# 讀取資料
for step in range(1000):
scalar0.add_record(step, step * 1. / 1000)
scalar1.add_record(step, 1. - step * 1. / 1000)
執行Python程式碼之後,在終端上輸入,從上面的程式碼可以看到我們定義的路徑是./random_log
:
visualDL --logdir ./random_log --port 8080
然後在瀏覽器上輸入:
http://127.0.0.1:8080
然後就可以看到剛才編寫Python程式碼生成的影象了:
經過這個例子,讀者對VisualDL有了進一步的瞭解了,那麼在接下來的我們就在實際的PaddlePaddle例子中使用我們的VisualDL。
在PaddlePaddle使用VisualDL
定義VisualDL元件
建立三個元件:scalar
,image
,histogram
,並指定存放日誌的路徑
# 建立VisualDL,並指定當前該專案的VisualDL的路徑
logdir = "../data/tmp"
logwriter = LogWriter(logdir, sync_cycle=10)
# 建立loss的趨勢圖
with logwriter.mode("train") as writer:
loss_scalar = writer.scalar("loss")
# 建立acc的趨勢圖
with logwriter.mode("train") as writer:
acc_scalar = writer.scalar("acc")
# 定義沒多少次重新輸出一遍
num_samples = 4
# 建立卷積層和輸出影象的圖形化展示
with logwriter.mode("train") as writer:
conv_image = writer.image("conv_image", num_samples, 1)
input_image = writer.image("input_image", num_samples, 1)
# 建立視覺化的訓練模型結構
with logwriter.mode("train") as writer:
param1_histgram = writer.histogram("param1", 100)
編寫PaddlePaddle程式碼
然後建立PaddlePaddle程式碼,我們使用的是PaddlePaddle的Fluid版本,如果對Fluid版本不熟悉的話,可以閱讀筆者的上一篇文章新版本Fluid的使用,瞭解Fluid版本之後再繼續閱讀下面的程式碼,如果讀者已經很熟悉Fluid版本的使用了,那就往下看。
定義data
和label
,程式碼如下:
# 定義影象的類別數量
class_dim = 10
# 定義影象的通道數和大小
image_shape = [3, 32, 32]
# 定義輸入資料大小,指定影象的形狀,資料型別是浮點型
image = fluid.layers.data(name='image', shape=image_shape, dtype='float32')
# 定義標籤,型別是整型
label = fluid.layers.data(name='label', shape=[1], dtype='int64')
然後是獲取分類器,這裡跟上一篇有點不一樣,這裡還要提供第一層卷積,這是在訓練的時候要使用到,使用它來獲得卷積層的輸出。
# 獲取神經網路
net, conv1 = vgg16_bn_drop(image)
# 獲取全連線輸出,獲得分類器
predict = fluid.layers.fc(
input=net,
size=class_dim,
act='softmax',
param_attr=ParamAttr(name="param1", initializer=NormalInitializer()))
之後獲取損失函式和batch_acc,在這些之後才能定義優化方法。
# 獲取損失函式
cost = fluid.layers.cross_entropy(input=predict, label=label)
# 定義平均損失函式
avg_cost = fluid.layers.mean(x=cost)
# 每個batch計算的時候能取到當前batch裡面樣本的個數,從而來求平均的準確率
batch_size = fluid.layers.create_tensor(dtype='int64')
print batch_size
batch_acc = fluid.layers.accuracy(input=predict, label=label, total=batch_size)
# 定義優化方法
optimizer = fluid.optimizer.Momentum(
learning_rate=learning_rate,
momentum=0.9,
regularization=fluid.regularizer.L2Decay(5 * 1e-5))
opts = optimizer.minimize(avg_cost)
然後就開始建立偵錯程式,並讓其初始化。
# 是否使用GPU
place = fluid.CUDAPlace(0) if use_cuda else fluid.CPUPlace()
# 建立偵錯程式
exe = fluid.Executor(place)
# 初始化偵錯程式
exe.run(fluid.default_startup_program())
在訓練之前,還有獲取訓的資料,這裡沒有使用到測試,所以就沒有獲取測試的資料。
# 獲取訓練資料
train_reader = paddle.batch(
paddle.dataset.cifar.train10(), batch_size=BATCH_SIZE)
# 指定資料和label的對於關係
feeder = fluid.DataFeeder(place=place, feed_list=[image, label])
這裡多了一步,這是為了讓偵錯程式在訓練的時候也輸出引數的分佈和變化趨勢。
step = 0
sample_num = 0
start_up_program = framework.default_startup_program()
param1_var = start_up_program.global_block().var("param1")
現在就可以開始訓練了,一共輸出的四個值:loss
, conv1_out
, param1
, acc
, weight
,這些在影象輸出上,我們都是用到的。
accuracy = fluid.average.WeightedAverage()
# 開始訓練,使用迴圈的方式來指定訓多少個Pass
for pass_id in range(num_passes):
# 從訓練資料中按照一個個batch來讀取資料
accuracy.reset()
for batch_id, data in enumerate(train_reader()):
loss, conv1_out, param1, acc, weight = exe.run(fluid.default_main_program(),
feed=feeder.feed(data),
fetch_list=[avg_cost, conv1, param1_var, batch_acc,
batch_size])
accuracy.add(value=acc, weight=weight)
pass_acc = accuracy.eval()
把資料都新增到VisualDL
載入卷積層和輸入影象的資料載入到VisualDL中
# 重新啟動圖形化展示元件
if sample_num == 0:
input_image.start_sampling()
conv_image.start_sampling()
# 獲取taken
idx1 = input_image.is_sample_taken()
idx2 = conv_image.is_sample_taken()
# 保證它們的taken是一樣的
assert idx1 == idx2
idx = idx1
if idx != -1:
# 載入輸入影象的資料資料
image_data = data[0][0]
input_image_data = np.transpose(
image_data.reshape(image_shape), axes=[1, 2, 0])
input_image.set_sample(idx, input_image_data.shape,
input_image_data.flatten())
# 載入卷積資料
conv_image_data = conv1_out[0][0]
conv_image.set_sample(idx, conv_image_data.shape,
conv_image_data.flatten())
# 完成輸出一次
sample_num += 1
if sample_num % num_samples == 0:
input_image.finish_sampling()
conv_image.finish_sampling()
sample_num = 0
載入趨勢圖的資料,這裡包括了loss和平均錯誤率。
# 載入趨勢圖的資料
loss_scalar.add_record(step, loss)
acc_scalar.add_record(step, acc)
載入引數變化的資料
# 新增模型結構資料
param1_histgram.add_record(step, param1.flatten())
然後是執行專案,在執行專案的時候,會輸出一下的日誌資訊:
loss:[16.7996] acc:[0.0703125] pass_acc:[0.0703125]
loss:[15.192436] acc:[0.1171875] pass_acc:[0.09375]
loss:[14.519127] acc:[0.109375] pass_acc:[0.09895833]
loss:[15.262356] acc:[0.125] pass_acc:[0.10546875]
loss:[13.626783] acc:[0.078125] pass_acc:[0.1]
loss:[11.8960285] acc:[0.09375] pass_acc:[0.09895833]
同時執行我們的VisualDL,筆者把VisualDL的日誌都存放在data
目錄下,所以我們要去到該目錄,然後輸入以下命令:
visualDL --logdir ./tmp --port 8080
然後在瀏覽器上輸入:
http://127.0.0.1:8080
即可看到我們專案的影象了:
我們訓練的趨勢圖
卷積和輸入影象的視覺化頁面
訓練引數的變化情況
專案程式碼
參考資料
相關推薦
《我的PaddlePaddle學習之路》筆記十二——視覺化工具VisualDL的使用
目錄 前言 VisualDL是一個面向深度學習任務設計的視覺化工具,包含了scalar、引數分佈、模型結構、影象視覺化等功能。可以這樣說:“所見即所得”。我們可以藉助VisualDL來觀察我們訓練的情況,方便我們對訓練的模型進行分析,改善模型的
python學習之路(十二)
pack 分享 psi python 模塊 shp 詳解 階段 new from 這節主要介紹一下import!很實用的調用模塊的功能。 導入模塊 是導入真實的代碼 而導入包 是導入包下面的 __init__() 文件 這兩個是不一樣的 先說模塊定義 模塊 它就是一個
Spark學習之路 (十二)SparkCore的調優之資源調優JVM的基本架構
程序員 存儲 src ron 指示器 引用 double strong 功能 一、JVM的結構圖 1.1 Java內存結構 JVM內存結構主要有三大塊:堆內存、方法區和棧。 堆內存是JVM中最大的一塊由年輕代和老年代組成,而年輕代內存又被分成三部分,Eden空間、
Spark學習之路 (十二)SparkCore的調優之資源調優
限制 無法 數據 block 可能 executors 頻繁 通過 操作 摘抄自:https://tech.meituan.com/spark-tuning-basic.html 一、概述 在開發完Spark作業之後,就該為作業配置合適的資源了。Spark的資源參數,基
JAVA基礎學習之路(十二)鏈表
args 是否為空 鏈表 == lin 一個 ava int 數據類型 定義鏈表的基本結構: class Link {//外部類 //內部類,只為鏈表類服務 private class Node {//定義節點類 private
Android破解學習之路(十二)—— GP錄影漢化過程及添加布局
## 前言 最近閒著發慌,想起了很久之前就想漢化的一款錄影APP,APP大小不到1MB,但是好用,本期就給大家帶來漢化的基本步驟以及如何在APP中新增我們漢化的資訊 ## 漢化思路 1. **查詢關鍵字** 關鍵字挺好找的,由於APP本身就是英文,我們找到某個英文單詞進行搜尋即可 2. **找到string.
java學習之路————第十二天
今天我們接觸到final關鍵字,抽象類和抽象方法,遞迴演算法以及介面 一、final關鍵字 1.final修飾類,該類不能被繼承 如:String 2.final修飾方法,該方法不能被重寫 3.final修飾變數,該變數為常量。往往和stat
java學習之路——第二十二天
File類 這個類是java用來操作檔案屬性的類,使用這個類操作檔案的屬性,但是不能操作檔案裡面的內容。 這個構造的引數指向的是預設當前專案的根目錄 File f = new File(String pathName); boolean exists():判斷File指向的檔案是否存
opengl學習之路三十二,視差貼圖
本節暫未進行完全的重寫,錯誤可能會很多。如果可能的話,請對照原文進行閱讀。如果有報告本節的錯誤,將會延遲至重寫之後進行處理。 視差貼圖(Parallax Mapping)技術和法線貼圖差不多,但它有著不同的原則。和法線貼圖一樣視差貼圖能夠極大提升表面細節,使之
JDBC學習之路(十二)使用Spring中的JdbcTemple實現資料查詢
其實在Spring這個框架中,提供了一些對JDBC訪問資料庫的封裝,其中JdbcTemplate就是一個很好用的類,下面來演示一下這個類的一些用法。首先需要匯入commons-logging.jar,和spring.jar這兩個包。然後使用他的功能就可以了,可以說,Spring
hadoop生態系統學習之路(十二)cloudera manager的簡單使用
最近,忙著辭職和考駕照的事,都沒時間寫部落格了,差點把大資料相關的一些技術都給忘了。不過還好做好歸納整理,能夠快速的恢復起來。其實,筆者發現,學習大資料還是有點小竅門的。首先,最好能有個人指引,有什麼問題都可以問他,因為我僅僅只看視訊、資料等,很難挖掘裡面有價值
《我的PaddlePaddle學習之路》筆記七——車牌端到端的識別
目錄 前言 車牌識別的應用場景有很多,比如在停車場。通過車牌識別登記入庫和出庫的車輛的情況,並計算該車停留時間,然後折算費用。還可以在公路上識別來往的車輛,方便交警的檢查等等。接下來我們就是使用PaddlePaddle來做一個車牌識別,我們直接
《我的PaddlePaddle學習之路》筆記九——使用VOC資料集的實現目標檢測
目錄 前言 目標檢測的使用範圍很廣,比如我們使用相機拍照時,要正確檢測人臉的位置,從而做進一步處理,比如美顏等等。在目標檢測的深度學習領域上,從2014年到2016年,先後出現了R-CNN,Fast R-CNN, Faster R-CNN, I
我的學習之路_第十一章_字符流
之間 才會 fileutil output keys 返回 ont 讀取數據 一個 【字符流】 IO流的分類 ★字節流 操作的文件不是文本文件 字節輸入流: InputStream 抽象類 FileInputStream操作文件的字節輸入流 字節輸出流: OutputStr
我的學習之路_第十七章_JavaUtils
包含 string 和數 類的方法 objc 基本數據類型 通過 序列 setprop 【BeanUtils工具類】 javaBaen : Java和數據庫所對應關系實體類 表(Utils)-->類(User) 表中的列-->類中字段(屬性) 表中的行-->
我的學習之路_第十八章_SQL語句
之路 唯一約束 一個表 database pda eat 三種方式 rac 條件過濾 SQL語句 啟動數據庫: net start mysql 關閉數據庫: net stop mysql 登錄數據庫 : cmd-->命令行-->mysql--&g
我的學習之路_第二十九章_bootstrap
柵格系統 學習之路 大屏幕 支持 響應式 入門 顯示效果 oot name bootstrap 內置了html,css,js插件為一體的前端框架 響應式布局: 設計一套頁面就可以使用於很多現實設備 bootstrap: 1.入門(響應式布局的容器) 1.先進入jQu
【學習】Unity手遊之路<十二>手遊資源熱更新策略探討
似的 remove 方式 comment word rep 熱更新 style encoding http://blog.csdn.net/janeky/article/details/17666409 =================================
Android破解學習之路(十)—— 我們戀愛吧 三色繪戀 二次破解
前言 好久沒有寫破解教程了(我不會告訴你我太懶了),找到一款戀愛遊戲,像我這樣的宅男只能玩玩戀愛遊戲感覺一下戀愛的心動了。。 這款遊戲免費試玩,但是後續章節得花6元錢購買,我怎麼會有錢呢,而且身在吾愛的大家庭裡,不破解一波怎麼對得起我破解渣渣的身份呢! 喲,還是支付寶購買的,直接9000大法,但是破解的時候沒
Python小白學習之路(十七)—【內建函式二】
序列操作類函式 all() 功能:判斷可迭代物件的每個元素是否都為True值注意:If the iterable is empty, return True.(舉例3) 回顧:None '' () {} [] 0 ==>False其餘 ==>Tru