TensorFlow 是一個(gè)開放源代碼軟件庫,用于進(jìn)行高性能數(shù)值計(jì)算。借助靈活的架構(gòu),用戶可以輕松地將計(jì)算工作部署到多種平臺(CPU、GPU、TPU)和設(shè)備(桌面設(shè)備、服務(wù)器集群、移動設(shè)備、邊緣設(shè)備等)。最近在 JS 社區(qū)中,對 TF 中 Java API 相關(guān)項(xiàng)目與技術(shù)的高度需求是前所未有的。
近日,TensorFlow 發(fā)表推文正式發(fā)布 TensorFlow v1.9 ,大家可以更新各自的代碼啦~~在 TF 的更新文檔中更新了 keras,包括一個(gè)新的基于keras的入門,一個(gè)非常適合初學(xué)者的Jupyter 筆記本,還增加了更多的實(shí)例。
其中有兩個(gè)案例受到了大家的廣泛關(guān)注,這個(gè)項(xiàng)目是通過 Colab 在 tf.keras 中訓(xùn)練模型,并通過TensorFlow.js 在瀏覽器中運(yùn)行;最近在 JS 社區(qū)中,對這些相關(guān)項(xiàng)目的高度需求是前所未有的。之前人工智能頭條也為大家介紹了一個(gè)在瀏覽器中通過TensorFlow.js 進(jìn)行多人人臉識別與特征檢測的項(xiàng)目,也受到大家的廣泛關(guān)注。此外 TensorFlow 還給那些想了解、學(xué)習(xí)相關(guān)項(xiàng)目技術(shù)的關(guān)注者們推出了系列官方教學(xué)視頻。
今天人工智能頭條會帶領(lǐng)大家學(xué)習(xí)這個(gè)新項(xiàng)目,JS 愛好者和開發(fā)者們不要錯過!
另一個(gè)項(xiàng)目是簡單的RNN網(wǎng)絡(luò)生成文本的實(shí)踐,這次作者不僅在GitHub 上分享了源碼,大家還可以利用這次 v1.9 中的筆記本新功能來進(jìn)行端到端的直接運(yùn)行。
在 Google Colab 中看到這個(gè)項(xiàng)目的第一眼,就覺得真的很適合初學(xué)者研究學(xué)習(xí)。左側(cè)可以一目了然地看 “目錄” 與 “代碼段”。
已經(jīng)分解的源碼結(jié)構(gòu),從安裝、導(dǎo)入需要的工具,到下載讀取數(shù)據(jù),創(chuàng)建訓(xùn)練模型,最后預(yù)測模型,只要跟著一步一步來,相信大家都會學(xué)有所成。
▌TensorFlow v1.9 實(shí)踐
前言
在這個(gè)應(yīng)用中我們將完成通過識別圖畫來輸出當(dāng)前圖畫的名稱的實(shí)踐。使用 Google Colab 來訓(xùn)練模型,使用 TensorFlow.js 在瀏覽器上進(jìn)行部署,直接在瀏覽器上運(yùn)行。需要注意的一點(diǎn)是,務(wù)必要在測試 Google Colab 的 notebook 工具:
https://colab.research.google.com/github/zaidalyafeai/zaidalyafeai.github.io/blob/master/sketcher/Sketcher.ipynb
數(shù)據(jù)集
我們將使用 CNN 來識別不同類型的圖畫。CNN 將在Quick Draw數(shù)據(jù)集上進(jìn)行訓(xùn)練。這個(gè)數(shù)據(jù)集包含了大約5000萬張、345類別的圖畫。
管道
我們將使用 Keras 在 Google Colab 上訓(xùn)練模型,然后通過 TensorFlow.js (tfjs) 在瀏覽器上直接運(yùn)行。下圖向大家展示了這個(gè)項(xiàng)目的管道圖
參考教程:
https://js.tensorflow.org/
https://github.com/tensorflow/tfjs-examples
輸入
我們將使用帶有tensorflow后端的keras:
importosimportglobimportnumpyasnpfromtensorflow.kerasimportlayersfromtensorflowimportkerasimporttensorflowastf
加載數(shù)據(jù)
由于內(nèi)存有限,我們不會在所有的類別進(jìn)行訓(xùn)練。我們只使用100個(gè)類別的數(shù)據(jù)集。在Google Cloud 的quickdraw_dataset 上每個(gè)類別的數(shù)據(jù)都可以用形狀表示為[N,784]的numpy數(shù)組,其中N是該特定類的的圖像數(shù)量。我們首先下載數(shù)據(jù)集:
importurllib.requestdefdownload():base='https://storage.googleapis.com/quickdraw_dataset/full/numpy_bitmap/'forcinclasses:cls_url=c.replace('_','%20')path=base+cls_url+'.npy'print(path)urllib.request.urlretrieve(path,'data/'+c+'.npy')
由于內(nèi)存有限,因此每個(gè)類只能加載5000個(gè)圖像到內(nèi)存。另外還保留了20%的用于測試的數(shù)據(jù)。
defload_data(root,vfold_ratio=0.2,max_items_per_class=5000):all_files=glob.glob(os.path.join(root,'*.npy'))#initializevariablesx=np.empty([0,784])y=np.empty([0])class_names=[]#loadasubsetofthedatatomemoryforidx,fileinenumerate(all_files):data=np.load(file)data=data[0:max_items_per_class,:]labels=np.full(data.shape[0],idx)x=np.concatenate((x,data),axis=0)y=np.append(y,labels)class_name,ext=os.path.splitext(os.path.basename(file))class_names.append(class_name)data=Nonelabels=None#separateintotrainingandtestingpermutation=np.random.permutation(y.shape[0])x=x[permutation,:]y=y[permutation]vfold_size=int(x.shape[0]/100*(vfold_ratio*100))x_test=x[0:vfold_size,:]y_test=y[0:vfold_size]x_train=x[vfold_size:x.shape[0],:]y_train=y[vfold_size:y.shape[0]]returnx_train,y_train,x_test,y_test,class_names
預(yù)處理數(shù)據(jù)
我們對數(shù)據(jù)進(jìn)行預(yù)處理,為訓(xùn)練做準(zhǔn)備。該模型將采用 [N, 28, 28, 1] 批次并輸出為[N, 100]的概率。
#Reshapeandnormalizex_train=x_train.reshape(x_train.shape[0],image_size,image_size,1).astype('float32')x_test=x_test.reshape(x_test.shape[0],image_size,image_size,1).astype('float32')x_train/=255.0x_test/=255.0#Convertclassvectorstoclassmatricesy_train=keras.utils.to_categorical(y_train,num_classes)y_test=keras.utils.to_categorical(y_test,num_classes)
創(chuàng)建模型
我們將創(chuàng)建一個(gè)簡單的CNN。參數(shù)數(shù)量越少,模型就越簡單越好。因?yàn)槲覀兪窃跒g覽器上進(jìn)行轉(zhuǎn)換后運(yùn)行模型,并且希望模型能夠快速運(yùn)行以便進(jìn)行預(yù)測。下面模型包含了3個(gè)conv層和2個(gè)dense層。
#Definemodelmodel=keras.Sequential()model.add(layers.Convolution2D(16,(3,3),padding='same',input_shape=x_train.shape[1:],activation='relu'))model.add(layers.MaxPooling2D(pool_size=(2,2)))model.add(layers.Convolution2D(32,(3,3),padding='same',activation='relu'))model.add(layers.MaxPooling2D(pool_size=(2,2)))model.add(layers.Convolution2D(64,(3,3),padding='same',activation='relu'))model.add(layers.MaxPooling2D(pool_size=(2,2)))model.add(layers.Flatten())model.add(layers.Dense(128,activation='relu'))model.add(layers.Dense(100,activation='softmax'))#Trainmodeladam=tf.train.AdamOptimizer()model.compile(loss='categorical_crossentropy',optimizer=adam,metrics=['top_k_categorical_accuracy'])print(model.summary())
適配、驗(yàn)證和測試
在此之后,我們對模型進(jìn)行了5個(gè)輪數(shù)和256個(gè)批次的訓(xùn)練,并進(jìn)行了10%的驗(yàn)證劃分:
#fitthemodelmodel.fit(x=x_train,y=y_train,validation_split=0.1,batch_size=256,verbose=2,epochs=5)#evaluateonunseendatascore=model.evaluate(x_test,y_test,verbose=0)print('Testaccuarcy:{:0.2f}%'.format(score[1]*100))viewraw
訓(xùn)練的結(jié)果如下圖所示:
測試準(zhǔn)確率中第5個(gè)準(zhǔn)確率為92.20%。
為Web格式準(zhǔn)備模型
在我們對模型的準(zhǔn)確率感到滿意之后,我們將其保存并準(zhǔn)備進(jìn)行轉(zhuǎn)換:
model.save('keras.h5')
安裝tfjs包進(jìn)行轉(zhuǎn)換:
!pipinstalltensorflowjs
然后轉(zhuǎn)換模型:
!mkdirmodel!tensorflowjs_converter--input_formatkeraskeras.h5model/
創(chuàng)建了一些權(quán)重文件和包含模型體系結(jié)構(gòu)的json文件。
壓縮模型,準(zhǔn)備將其下載到我們的本地計(jì)算機(jī)中:
!zip-rmodel.zipmodel
最后下載模型:
fromgoogle.colabimportfilesfiles.download('model.zip')
下面將展示如何加載模型并進(jìn)行推理。假設(shè)我們有一個(gè)300x300大小的畫布。
加載模型
要使用TensorFlow.js,請首先運(yùn)行以下腳本:
注意:需要在本地計(jì)算機(jī)上運(yùn)行服務(wù)器,
然后,使用瀏覽器加載模型(await關(guān)鍵字用于等待瀏覽器加載模型)
model=awaittf.loadModel('model/model.json')viewraw
預(yù)處理
在做預(yù)測之前,我們需要先對數(shù)據(jù)進(jìn)行預(yù)處理。首先從畫布中獲取圖像數(shù)據(jù)變量dpi用于根據(jù)屏幕像素的密度對畫布進(jìn)行拉伸。
//theminimumboudningboxaroundthecurrentdrawingconstmbb=getMinBox()//cacluatethedpiofthecurrentwindowconstdpi=window.devicePixelRatio//extracttheimagedataconstimgData=canvas.contextContainer.getImageData(mbb.min.x*dpi,mbb.min.y*dpi,(mbb.max.x-mbb.min.x)*dpi,(mbb.max.y-mbb.min.y)*dpi);
我們將畫布當(dāng)前的圖像數(shù)據(jù)轉(zhuǎn)換為一個(gè)張量,調(diào)整大小并進(jìn)行規(guī)范化。
functionpreprocess(imgData){returntf.tidy(()=>{//converttheimagedatatoatensorlettensor=tf.fromPixels(imgData,numChannels=1)//resizeto28x28constresized=tf.image.resizeBilinear(tensor,[28,28]).toFloat()//Normalizetheimageconstoffset=tf.scalar(255.0);constnormalized=tf.scalar(1.0).sub(resized.div(offset));//Weaddadimensiontogetabatchshapeconstbatched=normalized.expandDims(0)returnbatched})}
對于預(yù)測,我們使用model.predict,這將返回形狀的概率[N, 100]:
constpred=model.predict(preprocess(imgData)).dataSync()
然后我們可以用簡單的函數(shù)來求前5個(gè)概率。
提高準(zhǔn)確率
記住,我們的模型接受形狀[N, 28, 28,1]的張量,繪圖畫布大小為300x300,對于繪圖來說,可能需要兩個(gè)大的用于繪圖,或者可能需要用戶繪制小一些的圖。最好只裁剪包含當(dāng)前圖畫的框。為了做到這一點(diǎn),我們通過查找左上角和右下角來提取繪圖周圍的最小邊界框:
//recordthecurrentdrawingcoordinatesfunctionrecordCoor(event){//getcurrentmousecoordinatevarpointer=canvas.getPointer(event.e);varposX=pointer.x;varposY=pointer.y;//recordthepointifwithingthecanvasandthemouseispressedif(posX>=0&&posY>=0&&mousePressed){coords.push(pointer)}}//getthebestboundingboxbyfindingthetopleftandbottomrightcorndersfunctiongetMinBox(){varcoorX=coords.map(function(p){returnp.x});varcoorY=coords.map(function(p){returnp.y});//findtopleftcornervarmin_coords={x:Math.min.apply(null,coorX),y:Math.min.apply(null,coorY)}//findrightbottomcornervarmax_coords={x:Math.max.apply(null,coorX),y:Math.max.apply(null,coorY)}return{min:min_coords,max:max_coords}}
測試?yán)L圖
下圖展示了一些第一次繪圖和最高百分比級別。所有的圖畫都是我用鼠標(biāo)繪制的。如果用一支電腦繪圖筆可以獲得更好的準(zhǔn)確率:
-
數(shù)據(jù)集
+關(guān)注
關(guān)注
4文章
1209瀏覽量
24830 -
tensorflow
+關(guān)注
關(guān)注
13文章
329瀏覽量
60629
原文標(biāo)題:TensorFlow 發(fā)布新版本v1.9(附應(yīng)用實(shí)踐教程)
文章出處:【微信號:rgznai100,微信公眾號:rgznai100】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論