機(jī)器學(xué)習(xí)入門之HelloWorld(Tensorflow)
源碼下載地址:https://share.weiyun.com/a0c1664d334c4c67ed51fc5e0ac5f2b2
初學(xué)機(jī)器學(xué)習(xí),寫篇文章mark一下,希望能為將入坑者解點(diǎn)惑。本文介紹一些機(jī)器學(xué)習(xí)的入門知識(shí),從安裝環(huán)境到跑通機(jī)器學(xué)習(xí)入門程序MNIST demo。
內(nèi)容提綱:
- 環(huán)境搭建
- 了解Tensorflow運(yùn)行機(jī)制
- MNIST(手寫數(shù)字識(shí)別 ) softmax性線回歸
- MNIST 深度卷積神經(jīng)網(wǎng)絡(luò)(CNN)
- tools 工具類
- CPU & GPU & multi GPU
- 學(xué)習(xí)資料
1 環(huán)境搭建 (Windows)
- 安裝虛擬環(huán)境 Anaconda,方便python包管理和環(huán)境隔離。
Anaconda3 4.2 https://www.anaconda.com/downloads,自帶python 3.5。
- 創(chuàng)建tensorflow隔離環(huán)境。打開Anaconda安裝后的終端Anaconda Prompt,執(zhí)行下面命令
- conda create -n tensorflow python=3.5 #創(chuàng)建名為tensorflow,python版本為3.5的虛擬環(huán)境
- activate tensorflow #激活這個(gè)環(huán)境
- deactivate #退出當(dāng)前虛擬環(huán)境。這個(gè)不用執(zhí)行
CPU 版本
- pip install tensorflow #通過(guò)包管理來(lái)安裝
- pip install whl-file #通過(guò)下載 whl 文件安裝,tensorflow-cpu安裝包:http://mirrors.oa.com/tensorflow/windows/cpu/tensorflow-1.2.1-cp35-cp35m-win_amd64.whl, cp35是指python3.5
GPU 版本。我的筆記本是技持NVIDIA顯卡的,可以安裝cuda,GPU比CPU快很多,不過(guò)筆記本的顯存不大,小模型還可以跑,大模型建議在本地用CPU跑通,到Tesla平臺(tái)上訓(xùn)練。
注意點(diǎn):選擇正確的 CUDA 和 cuDNN 版本搭配,不要只安裝最新版本,tensorflow可能不支持。
目前Tensorflow已支持到CUDA 9 & cuDNN 7,之前本人安裝只支持CUDA 8 & cuDNN 6,所以用是的:
CUDA8.1 https://developer.nvidia.com/cuda-80-ga2-download-archive
cudnn 6 https://developer.nvidia.com/cudnn ,將cudnn包解壓,把文件放到cuda安裝的對(duì)應(yīng)目錄中,C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0,bin對(duì)應(yīng)bin,include對(duì)應(yīng)include,再添加bin目錄到環(huán)境變量path中。
- pip install tensorflow-gpu #通過(guò)包管理來(lái)安裝
- pip install whl-file #http://mirrors.oa.com/tensorflow/windows/gpu/tensorflow_gpu-1.2.1-cp35-cp35m-win_amd64.whl
一些python工具包安裝。用到啥安啥就行, pip install,不行就找源碼編譯安裝
- (tensorflow) D:\> pip install opencv-python #opencv, tensoflow 虛擬環(huán)境中
- (tensorflow) D:\> pip install scipy #圖片讀取寫入,scipy.misc.imread
- (tensorflow) D:\> pip install Pillow #PIL/Pillow,這里有個(gè)坑,壓縮過(guò)的PNG圖,在1.x版本解析會(huì)出現(xiàn)透明通道質(zhì)量下降,升級(jí)
2 了解Tensorflow運(yùn)行機(jī)制
- 上代碼。注意注釋說(shuō)明
- import tensorflow as tf
- hello_world = tf.constant('Hello World!', dtype=tf.string) #常量tensor
- print(hello_world) #這時(shí)hello_world是一個(gè)tensor,代表一個(gè)運(yùn)算的輸出
- #out: Tensor("Const:0", shape=(), dtype=string)
- hello = tf.placeholder(dtype=tf.string, shape=[None])#占位符tensor,在sess.run時(shí)賦值
- world = tf.placeholder(dtype=tf.string, shape=[None])
- hello_world2 = hello+world #加法運(yùn)算tensor
- print(hello_world2)
- #out: Tensor("add:0", shape=(?,), dtype=string)
- #math
- x = tf.Variable([1.0, 2.0]) #變量tensor,可變。
- y = tf.constant([3.0, 3.0])
- mul = tf.multiply(x, y) #點(diǎn)乘運(yùn)算tensor
- #logical
- rgb = tf.constant([[[255], [0], [126]]], dtype=tf.float32)
- logical = tf.logical_or(tf.greater(rgb,250.), tf.less(rgb, 5.))#邏輯運(yùn)算,rgb中>250 or <5的位置被標(biāo)為True,其它False
- where = tf.where(logical, tf.fill(tf.shape(rgb),1.), tf.fill(tf.shape(rgb),5.))#True的位置賦值1,False位置賦值5
- # 啟動(dòng)默認(rèn)圖.
- # sess = tf.Session()
- with tf.Session() as sess:
- sess.run(tf.global_variables_initializer())#變量初始化
- result = sess.run(hello_world) #Fetch, 獲取tensor運(yùn)算結(jié)果
- print(result, result.decode(), hello_world.eval())#`t.eval()` is a shortcut for calling `tf.get_default_session().run(t)`.
- #out: b'Hello World!' Hello World! b'Hello World!' #前輟'b'表示bytestring格式,decode解成string格式
- print(sess.run(hello, feed_dict={hello: ['Hello']}))
- #out: ['Hello']
- print(sess.run(hello_world2, feed_dict={hello: ['Hello'], world: [' World!']}))#Feed,占位符賦值
- #out: [b'Hello World!']
- print(sess.run(mul))
- #out: [ 3. 6.]
- print(sess.run(logical))
- #out: [[[ True] [ True] [False]]] #rgb中>250 or <5的位置被標(biāo)為True,其它False
- print(sess.run(where))
- #out: [[[ 1.] [ 1.] [ 5.]]] #True的位置賦值1,False位置賦值5
- #sess.close()#sess如果不是用with方式定義,需要close
- Tensor。是一個(gè)句柄,代表一個(gè)運(yùn)算的輸出,但并沒(méi)有存儲(chǔ)運(yùn)算輸出的結(jié)果,需要通過(guò)tf.Session.run(Tensor)或者Tensor.eval()執(zhí)行運(yùn)算過(guò)程后,才能得到輸出結(jié)果。A Tensor is a symbolic handle to one of the outputs of an Operation,It does not hold the values of that operation's output, but instead provides a means of computing those values in a TensorFlow.
- Tensorflow運(yùn)行過(guò)程:定義計(jì)算邏輯,構(gòu)建圖(Graph) => 通過(guò)會(huì)話(Session),獲取結(jié)果數(shù)據(jù)?;居梅▍⒁婃溄印?/li>
3 MNIST(手寫數(shù)字識(shí)別 ) softmax性線回歸
- 分析
MNIST是一個(gè)入門級(jí)的計(jì)算機(jī)視覺(jué)數(shù)據(jù)集,它包含各種手寫數(shù)字圖片:
它也包含每一張圖片對(duì)應(yīng)的標(biāo)簽,告訴我們這個(gè)是數(shù)字幾。比如,上面這四張圖片的標(biāo)簽分別是5,0,4,1。
數(shù)據(jù)集圖片大小28x28,單通道灰度圖。存儲(chǔ)樣式如下:
MNIST手寫數(shù)字識(shí)別的目的是輸入這樣的包含手寫數(shù)字的28x28的圖片,預(yù)測(cè)出圖片中包含的數(shù)字。
softmax線性回歸認(rèn)為圖片中數(shù)字是N可能性由圖像中每個(gè)像素點(diǎn)用
表示是 數(shù)字 i 的可能性,計(jì)算出所有數(shù)字(0-9)的可能性,也就是所有數(shù)字置信度,然后把可能性最高的數(shù)字作為預(yù)測(cè)值。
evidence的計(jì)算方式如下:
其中
代表權(quán)重,
代表數(shù)字 i 類的偏置量,j 代表給定圖片 x 的像素索引(0~28x28=784),用于像素求和。即圖片每個(gè)像素值x權(quán)重之和,再加上一個(gè)偏置b,得到可能性值。
引入softmax的目的是對(duì)可能性值做歸一化normalize,讓所有可能性之和為1。這樣可以把這些可能性轉(zhuǎn)換成概率 y:
- 開始實(shí)現(xiàn)
數(shù)據(jù)
X樣本 size 28x28 = 784
Y樣本 ,樣式如
讀取
- from tensorflow.examples.tutorials.mnist import input_data
- mnist = input_data.read_data_sets(FLAGS.data_dir, one_hot=True) #total 55000,one_hot方式,圖片x格式為1維數(shù)組,大小784
- batch_xs, batch_ys = mnist.train.next_batch(batch_size) #分batch讀取
構(gòu)建圖(Graph)
Inference推理,由輸入 x 到輸出預(yù)測(cè)值 y 的推理過(guò)程
- x = tf.placeholder(tf.float32, [None, 784], name="input")#None表示batch size待定
- with tf.variable_scope("inference"):#定義作用域,名子inference
- W = tf.Variable(tf.zeros([784, 10])) #初值為0,size 784x10
- b = tf.Variable(tf.zeros([10])) #初值為0 size 10
- y = tf.matmul(x, W) + b #矩陣相乘
Loss 損失函數(shù),分類一般采用交叉熵,這里用的是softmax交交叉熵。交叉熵是用來(lái)度量?jī)蓚€(gè)概率分布間的差異性信息,交叉熵公式如下:
- with tf.variable_scope("loss"):
- loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y), name="loss")
- #softmax交叉熵公式: z * -log(softmax(x)) + (1 - z) * -log(1 - softmax (x)) # x: logits, z: label
計(jì)算loss的方法有很多種,常見的還有L1 loss 、L2 loss、sigmoid 交叉熵、聯(lián)合loss、自定義loss...
Accuracy 準(zhǔn)確率,預(yù)測(cè)值與真實(shí)值相同的概率。矩陣相乘輸出y值是一個(gè)數(shù)組,tf.argmax函數(shù)可能從數(shù)據(jù)中找出最大元素下標(biāo),預(yù)測(cè)值的最大值下標(biāo)和真值的最大值下標(biāo)一致即為正確。
- with tf.variable_scope("accuracy"):
- accuracy = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1)), tf.float32), name="accuracy")
Training 訓(xùn)練,訓(xùn)練的目的是讓Loss接近最小化,預(yù)測(cè)值接近真值,Tensorflow通過(guò)優(yōu)化器Optimizers來(lái)實(shí)現(xiàn)。在y = Wx+b中,W、b在訓(xùn)練之初會(huì)賦初值(隨機(jī) or 0),經(jīng)過(guò)Optimizer不短優(yōu)化,Loss逼近最小值,使W、b不斷接近理想值。W、b一起共784x10+10個(gè)參數(shù)。
- train_step = tf.train.GradientDescentOptimizer(FLAGS.learning_rate).minimize(loss)
minimize函數(shù):更新參數(shù),讓Loss最小化,包含兩個(gè)步驟:計(jì)算梯度;更新參數(shù)。
- grad_var = compute_gradients(loss) # return (gradient, variable) pairs
- apply_gradients(grad_var) #沿著參數(shù)的梯度反方向更新參數(shù),讓Loss變小
GradientDescentOptimizer:梯度下降算法優(yōu)化器, Tensorflow實(shí)現(xiàn)的是SGD(隨機(jī)梯度下降)。其缺點(diǎn)是依賴當(dāng)前batch,波動(dòng)較大。
其它一些增強(qiáng)版Optimizers:參考鏈接。 MomentumOptimizer、AdadeltaOptimizer、AdamOptimizer、RMSPropOptimizer、AdadeltaOptimizer ...
Session:Tensorflow需要通過(guò)Session(會(huì)話)來(lái)執(zhí)行推理運(yùn)算,有兩種創(chuàng)建方式,兩者差別在于InteractiveSession會(huì)將自己設(shè)置為默認(rèn)session,有了默認(rèn)session,tensor.eval()才能執(zhí)行。
- sess = tf.Session()
- sess = tf.InteractiveSession()
也可以通過(guò)下設(shè)置默認(rèn)session:
- with sess.as_default(): xx.eval()
- with tf.Session() as sess: xx.eval()
配置gpu相關(guān)session參數(shù):
- sess_config = tf.ConfigProto(allow_soft_placement=True, log_device_placement=False)#允許沒(méi)有g(shù)pu或者gpu不足時(shí)用軟件模擬
- sess_config.gpu_options.allow_growth = True #動(dòng)態(tài)申請(qǐng)顯存。不加會(huì)申請(qǐng)全部,導(dǎo)致其他訓(xùn)練程序不能運(yùn)行
- #sess_config.gpu_options.per_process_gpu_memory_fraction = 0.8 #按比例申請(qǐng)顯存
- sess = tf.InteractiveSession(config=sess_config)
一個(gè)網(wǎng)絡(luò)的訓(xùn)練過(guò)程是一個(gè)不斷迭代(前向+反向)的過(guò)程。前向算法由前向后計(jì)算網(wǎng)絡(luò)各層輸出,反向算法由后向前計(jì)算參數(shù)梯度,優(yōu)化參數(shù),減小Loss。流程如圖:
注意:每隔一段時(shí)間輸出一下網(wǎng)絡(luò)Loss和Accuracy,查看效果。每隔一段時(shí)間緩存一下網(wǎng)絡(luò)參數(shù),防止被突然中斷,可再恢復(fù)。
模型參數(shù)的保存與恢復(fù):
check point:默認(rèn)保存方式。
pb:mobile使用。
npz:字典保存方式,{name: value}, numpy的一種保存方式。對(duì)參數(shù)按名保存,按名恢復(fù)。save和restore方法自己控制,可以選擇性保存和恢復(fù)。參見附近代碼中【tools.py】save_npz_dict & load_and_assign_npz_dict方法。
- saver = tf.train.Saver(max_to_keep = 3, write_version = 2)
- save_path = saver.save(sess, FLAGS.out_model_dir+'/model.ckpt')# check point方式
- output_graph_def = tf.graph_util.convert_variables_to_constants(sess, sess.graph_def, output_node_names=['output'])#指定輸出節(jié)點(diǎn)名稱,這個(gè)需要在網(wǎng)絡(luò)中定義
- with tf.gfile.FastGFile(FLAGS.out_model_dir+'/mobile-model.pb', mode='wb') as f:
- f.write(output_graph_def.SerializeToString()) #pb方式
- tools.save_npz_dict(save_list=tf.global_variables(), name=FLAGS.out_model_dir+'/model.npz', sess=sess) #pnz方式
恢復(fù):
- #check point
- saver = tf.train.Saver(max_to_keep = 3, write_version = 2)
- model_file=tf.train.latest_checkpoint(FLAGS.log_dir)
- if model_file:
- saver.restore(sess, model_file)
- #npz
- tools.load_and_assign_npz_dict(name=FLAGS.log_dir+'/model.npz', sess=sess))打印網(wǎng)絡(luò)中各參數(shù)信息:方便查看網(wǎng)絡(luò)參數(shù)是否正確。
- def print_all_variables(train_only=False):
- if train_only:
- t_vars = tf.trainable_variables()
- print(" [*] printing trainable variables")
- else:
- t_vars = tf.global_variables()
- print(" [*] printing global variables")
- for idx, v in enumerate(t_vars):
- print(" var {:3}: {:15} {}".format(idx, str(v.get_shape()), v.name))
- 可視化。Tensorflow提供tensorboard可視化工具,通過(guò)命令打開web服務(wù),由瀏覽器查看,輸入網(wǎng)址http://localhost:6006
- tensorboard --logdir=your-log-path #path中不要出現(xiàn)中文
- # 需要在訓(xùn)練過(guò)程指定相應(yīng)log路徑,寫入相關(guān)信息
- # 參考附件【sample.py】中summary、writer相關(guān)關(guān)鍵字代碼。
Graph可視化:
訓(xùn)練過(guò)程可視化:
batch size = 128, 訓(xùn)練集,驗(yàn)證集??梢钥吹絣oss在收斂,accuracy在提高。由于訓(xùn)練集曲線反應(yīng)的是當(dāng)前batch的loss和accuracy,batch size相對(duì)不高,抖動(dòng)較大。而驗(yàn)證集是全部圖片進(jìn)行測(cè)試,曲線較平滑。
4 MNIST深度卷積神經(jīng)網(wǎng)絡(luò)(CNN)
Softmax性線回歸網(wǎng)絡(luò)中,輸出y是輸入x的線性組合,即y = Wx+b,這是線性關(guān)系。在很多問(wèn)題中其解法并非線性關(guān)系能完成的,在深度學(xué)習(xí),能過(guò)能多層卷積神經(jīng)網(wǎng)絡(luò)組合非線性激活函數(shù)來(lái)模擬更復(fù)雜的非線性關(guān)系,效果往往比單一的線性關(guān)系更好。先看深度卷積神經(jīng)網(wǎng)絡(luò)(CNN,Convolutional Neural Network)構(gòu)建的MNIST預(yù)測(cè)模型,再逐一介紹各網(wǎng)絡(luò)層。
- MNIST CNN Inference推理圖。從輸入到輸出中間包含多個(gè)網(wǎng)絡(luò)層:reshape、conv卷積、pool池化、fc全鏈接、dropout。自底向上輸入原始圖片數(shù)據(jù)x經(jīng)過(guò)各層串行處理,得到各數(shù)字分類概率預(yù)測(cè)輸出y。Inference的結(jié)果轉(zhuǎn)給loss用作迭代訓(xùn)練,圖中的
可以看出用的是AdamOptimizer優(yōu)化器。
- reshape 變形,對(duì)數(shù)據(jù)的邏輯結(jié)構(gòu)進(jìn)行改變,如二維變四維:[1, 784] => [1, 28, 28, 1],數(shù)據(jù)存儲(chǔ)內(nèi)容未發(fā)生改變。這里由于輸入數(shù)據(jù)存儲(chǔ)的手寫圖片是一維數(shù)據(jù),轉(zhuǎn)成[batch_size, height, width, channels]格式
- with tf.name_scope('reshape'): #scope
- inputs = tf.reshape(inputs, [-1, 28, 28, 1])
- #[batch_size, height, width, channels], batch size=-1表示由inputs決定,
- #batch_size=inputs_size/(28x28x1)
- conv2d 卷積, 卷積核(yellow)與Image元(green)素相乘,累加得到輸出元素值(red)。Image的每個(gè)Channel(通道)都對(duì)應(yīng)一個(gè)不同的卷積核,Channel內(nèi)卷積核參數(shù)共享。所有輸入channel與其kernel相乘累加多層得到輸出的一個(gè)channel值。輸出如有多個(gè)channel,則會(huì)重復(fù)多次,kernel也是不同的。所以會(huì)有input_channel_count * output_channel_count個(gè)卷積核。在卷積層中訓(xùn)練的是卷積核。
- def conv2d(x, W): #W: filter [kernel[0], kernel[1], in_channels, out_channels]
- return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')
tf.nn.conv2d:
data_format: input和output數(shù)據(jù)的邏輯結(jié)構(gòu),NHWC : batch height width channel。NCHW: batch channel height width。常用的是NHWC格式;在一些輸入數(shù)據(jù)中各通道數(shù)據(jù)分開存放,這種更適合NCHW。
input:輸入,data_format=NHWC時(shí),shape為batch, in_height, in_width, in_channels,Tensor。
filter:卷積核,shape為filter_height, filter_width, in_channels, out_channels,共有in_channels*out_channels個(gè)filter_height, filter_width的卷積核,輸入輸出channel越多,計(jì)算量越大。
strides: 步長(zhǎng),shape為1, stride_h, stride_w, 1,通常stride_h和stride_w相等,表示卷積核延縱橫方向上每次前進(jìn)的步數(shù)。上gif圖stride為1。
padding:卷積計(jì)算時(shí)數(shù)據(jù)不對(duì)齊時(shí)填充方式,VALID:丟棄多余;SAME:兩端補(bǔ)0,讓多余部分可被計(jì)算。
output:輸出,shape為batch, out_height, out_width, out_channels
- output[b, i, j, k] =
- sum_{di, dj, q} input[b, strides[1] * i + di, strides[2] * j + dj, q] *
- filter[di, dj, q, k]
- 激活函數(shù),與卷積搭配使用。激活函數(shù)不是真的要去激活什么,在神經(jīng)網(wǎng)絡(luò)中,激活函數(shù)的作用是能夠給神經(jīng)網(wǎng)絡(luò)加入一些非線性因素,使得神經(jīng)網(wǎng)絡(luò)可以更好地解決較為復(fù)雜的問(wèn)題。
tf.nn.relu即是激活函數(shù),對(duì)卷積輸出作非線性處理,其函數(shù)如下:
其它還有如sigmoid:
tanh:
- Pool池化,有最大池化和平均值池化,計(jì)算與卷積計(jì)算類似,但無(wú)卷積核,求核所覆蓋范圍的最大值或平均值,輸入channel對(duì)應(yīng)輸出channel,沒(méi)有多層累加情況。輸入與輸出 channel數(shù)相同,輸出height、width取決于strides。
- if is_max_pool:
- x = tf.nn.max_pool(x, [1,kernel[0],kernel[1],1], strides=[1,stride[0],stride[1],1], padding=padding, name='pool')
- else:
- x = tf.nn.avg_pool(x, [1,kernel[0],kernel[1],1], strides=[1,stride[0],stride[1],1], padding=padding, name='pool')
- Dropout,隨機(jī)刪除一些數(shù)據(jù),讓網(wǎng)絡(luò)在這些刪除的數(shù)據(jù)上也能訓(xùn)練出準(zhǔn)確的結(jié)果,讓網(wǎng)絡(luò)有更強(qiáng)的適應(yīng)性,減少過(guò)擬合。
- x = tf.nn.dropout(x, keep_prob) #keep_prob 保留比例,keep_prob=1.0表示無(wú)dropout
- BN(batch normalize),批規(guī)范化。Inference中未標(biāo)出,demo中未使用,但也是網(wǎng)絡(luò)中很常用的一層。BN常作用在非線性映射前,即對(duì)Conv結(jié)果做規(guī)范化。一般的順序是 卷積-> BN -> 激活函數(shù)。
BN好處:提升訓(xùn)練速度,加快loss收斂,增加網(wǎng)絡(luò)適應(yīng)性,一定程序的解決反向傳播過(guò)程中的梯度消失和爆炸問(wèn)題。詳細(xì)請(qǐng)戳。
- FC(Full Connection)全連接,核心是矩陣相乘
,softmax性線回歸就是一個(gè)FC。在CNN中全連接常出現(xiàn)在最后幾層,用于對(duì)前面設(shè)計(jì)的特征做加權(quán)和。Tensorflow提供了相應(yīng)函數(shù)tf.layers.dense。
- 日志,下圖打印了模型中需要訓(xùn)練的參數(shù)的shape 和 各層輸出數(shù)據(jù)的shape(batch_size=1時(shí)),附件【tool.py】中有相關(guān)代碼。目的是方便觀自己搭的網(wǎng)絡(luò)結(jié)構(gòu)是否符合預(yù)期。
數(shù)據(jù)由[1x784] -reshape-> [1x28x28x1](batch_size, height, width, channels) -conv-> [1x28x28x32] -pool-> [1x14x14x32] -conv-> [1x14x14x64] -pool-> [1x7x7x64] -fc-> [1x1024] -fc-> [1x10](每類數(shù)字的概率)
- 訓(xùn)練效果,詳細(xì)代碼參考附件【cnn.py】
- 一個(gè)網(wǎng)上的可視化手寫識(shí)別DEMO,http://scs.ryerson.ca/~aharley/vis/conv/flat.html
- CNN家族經(jīng)典網(wǎng)絡(luò),如LeNet,AlexNet,VGG-Net,GoogLeNet,ResNet、U-Net、FPN。它們也都是由基本網(wǎng)絡(luò)層元素(上述介紹)堆疊而成,像搭積木一樣。
VGG,如下圖,非常有名的特征提取和分類網(wǎng)絡(luò)。由多層卷積池化層組成,最后用FC做特征融合實(shí)現(xiàn)分類,很多網(wǎng)絡(luò)基于其前幾層卷積池化層做特征提取,再發(fā)展自己的業(yè)務(wù)。
5 tool工具類
【tool.py】是一個(gè)自己基于tensorflow二次封裝的工具類,位于附件中。好處是以后編程更方便,代碼結(jié)構(gòu)更好看。網(wǎng)上也有現(xiàn)成的開源庫(kù),如TensorLayer、Keras、Tflearn,自己封裝的目的是更好的理解tensorflow API,自己造可控性也更強(qiáng)一些,如果控制是參數(shù)是否被訓(xùn)練、log打印。
下圖是MNIST CNN網(wǎng)絡(luò)的Inference推理代碼:
6 CPU & GPU & multi GPU
- CPU, Tensorflow默認(rèn)所有cpu都是/cpu:0,默認(rèn)占所有cpu,可以通過(guò)代碼指定占用數(shù)。
- sess_config = tf.ConfigProto(device_count={"CPU": 14}, allow_soft_placement=True, log_device_placement=False)
- sess_config.intra_op_parallelism_threads = 56
- sess_config.inter_op_parallelism_threads = 56
- sess = tf.InteractiveSession(config=sess_config)
- GPU,Tensorflow默認(rèn)占用/gpu:0, 可通過(guò)指定device來(lái)確定代碼運(yùn)行在哪個(gè)gpu。下面
- with tf.device('/device:GPU:2'):
- a = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[2, 3], name='a')
- b = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[3, 2], name='b')
- c = tf.matmul(a, b)
- #下面的代碼配置可以避免GPU被占滿,用多少內(nèi)存占多少
- sess_config = tf.ConfigProto(allow_soft_placement=True, log_device_placement=False)
- sess_config.gpu_options.allow_growth = True
- sess_config.gpu_options.per_process_gpu_memory_fraction = 0.8
- sess = tf.InteractiveSession(config=sess_config)
多塊GPU時(shí),可以通過(guò)在終端運(yùn)行下面指令來(lái)設(shè)置CUDA可見GPU塊來(lái)控制程序使用哪些GPU。
- export CUDA_VISIBLE_DEVICES=2,3
- 多GPU使用,在Tensorflow中多GPU編程比較尷尬,資料較好,代碼寫起比較復(fù)雜,這一點(diǎn)不如Caffe。
在Tensorflow中你需要自己寫代碼控制多GPU的loss和gradient的合并,這里有個(gè)官方例子請(qǐng)戳。自己也寫過(guò)多GPU的工程,附件代碼【tmp-main-gpus-不可用.py】可做參考,但此處不可用,來(lái)自它工程。
7 學(xué)習(xí)資料
收藏了一些機(jī)器學(xué)習(xí)相關(guān)資料,分享一下。自己也只看過(guò)很小一部分,仍在學(xué)習(xí)中....
Google最近出的機(jī)器學(xué)習(xí)速成課程 https://developers.google.cn/machine-learning/crash-course/ml-intro
斯坦福大學(xué)公開課 :機(jī)器學(xué)習(xí)課程 Andrew Ng吳恩達(dá) http://open.163.com/special/opencourse/machinelearning.html
我愛(ài)機(jī)器學(xué)習(xí)博客 https://www.52ml.net/
曉雷機(jī)器學(xué)習(xí)筆記 https://zhuanlan.zhihu.com/xiaoleimlnote
lilicao博客 http://www.cnblogs.com/lillylin/
貓狗大戰(zhàn)知乎專欄 https://zhuanlan.zhihu.com/alpha-smart-dog
計(jì)算機(jī)視覺(jué),機(jī)器學(xué)習(xí)相關(guān)領(lǐng)域源代碼大集合 https://zhuanlan.zhihu.com/p/26691794
物體檢測(cè)大集合 https://handong1587.github.io/deep_learning/2015/10/09/object-detection.html#r-cnn
機(jī)器學(xué)習(xí)筆記 https://feisky.xyz/machine-learning/
原文鏈接:https://cloud.tencent.com/developer/article/1058521
【本文是51CTO專欄作者“云加社區(qū)”的原創(chuàng)稿件,轉(zhuǎn)載請(qǐng)通過(guò)51CTO聯(lián)系原作者獲取授權(quán)】