比對在訓練CNN模型任務下ECS伺服器和GPU伺服器的速度差異
人工智慧已經是當下一大熱點,各個行業都在探討人工智慧將為自身帶來怎樣的改變,包括出行、居家、安全等不同方面,我們都可以看到人工智慧的應用可能性。
在這樣的趨勢下,很多公司開始加入人工智慧的開發研究當中。但是基於大資料、深度學習的人工智慧技術,需要強大的計算能力來支援。一般的物理伺服器或雲端的ecs伺服器勉強可以支援完成計算,但是效率上來講侷限很大。
GPU高速伺服器,就是為了解決這種難題而推出的,在相同的任務下,GPU伺服器的表現遠遠優於ECS伺服器的計算能力。我們利用TensorFlow的驗證碼識別訓練,比較了在訓練CNN模型方面ECS伺服器和GPU伺服器各自的速度,過程以及結果如下。
資料學習
安裝 captcha 庫
pip install captcha
獲取訓練資料
本教程使用的驗證碼由數字、大寫字母、小寫字母組成,每個驗證碼包含 4 個字元,總共有 62^4 種組合,所以一共有 62^4 種不同的驗證碼。
示例程式碼:
現在您可以在 /home/ubuntu 目錄下建立原始檔 generate_captcha.py,內容可參考:
示例程式碼:/home/ubuntu/generate_captcha.py
#-*- coding:utf-8 -*- from captcha.image import ImageCaptcha from PIL import Image import numpy as np import random import string class generateCaptcha(): def __init__(self, width = 160,#驗證碼圖片的寬 height = 60,#驗證碼圖片的高 char_num = 4,#驗證碼字元個數 characters = string.digits + string.ascii_uppercase + string.ascii_lowercase):#驗證碼組成,數字+大寫字母+小寫字母 self.width = width self.height = height self.char_num = char_num self.characters = characters self.classes = len(characters) def gen_captcha(self,batch_size = 50): X = np.zeros([batch_size,self.height,self.width,1]) img = np.zeros((self.height,self.width),dtype=np.uint8) Y = np.zeros([batch_size,self.char_num,self.classes]) image = ImageCaptcha(width = self.width,height = self.height) while True: for i in range(batch_size): captcha_str = ''.join(random.sample(self.characters,self.char_num)) img = image.generate_image(captcha_str).convert('L') img = np.array(img.getdata()) X[i] = np.reshape(img,[self.height,self.width,1])/255.0 for j,ch in enumerate(captcha_str): Y[i,j,self.characters.find(ch)] = 1 Y = np.reshape(Y,(batch_size,self.char_num*self.classes)) yield X,Y def decode_captcha(self,y): y = np.reshape(y,(len(y),self.char_num,self.classes)) return ''.join(self.characters[x] for x in np.argmax(y,axis = 2)[0,:]) def get_parameter(self): return self.width,self.height,self.char_num,self.characters,self.classes def gen_test_captcha(self): image = ImageCaptcha(width = self.width,height = self.height) captcha_str = ''.join(random.sample(self.characters,self.char_num)) img = image.generate_image(captcha_str) img.save(captcha_str + '.jpg') X = np.zeros([1,self.height,self.width,1]) Y = np.zeros([1,self.char_num,self.classes]) img = img.convert('L') img = np.array(img.getdata()) X[0] = np.reshape(img,[self.height,self.width,1])/255.0 for j,ch in enumerate(captcha_str): Y[0,j,self.characters.find(ch)] = 1 Y = np.reshape(Y,(1,self.char_num*self.classes)) return X,Y
理解訓練資料
- X:一個 mini-batch 的訓練資料,其 shape 為 [ batch_size, height, width, 1 ],batch_size 表示每批次多少個訓練資料,height 表示驗證碼圖片的高,width 表示驗證碼圖片的寬,1 表示圖片的通道。
- Y:X 中每個訓練資料屬於哪一類驗證碼,其形狀為 [ batch_size, class ] ,對驗證碼中每個字元進行 One-Hot 編碼,所以 class 大小為 4*62。
執行:
- 獲取驗證碼和對應的分類
d /home/ubuntu; python from generate_captcha import generateCaptcha g = generateCaptcha() X,Y = g.gen_test_captcha()
- 檢視訓練資料
X.shape
Y.shape
可以在 /home/ubuntu 目錄下檢視生成的驗證碼,jpg 格式的圖片可以點選檢視。
模型學習
任務時間:時間未知
CNN 模型
總共 5 層網路,前 3 層為卷積層,第 4、5 層為全連線層。對 4 層隱藏層都進行 dropout。網路結構如下所示: input——>conv——>pool——>dropout——>conv——>pool——>dropout——>conv——>pool——>dropout——>fully connected layer——>dropout——>fully connected layer——>output
示例程式碼:
現在您可以在 /home/ubuntu 目錄下建立原始檔 captcha_model.py,內容可參考:
示例程式碼:/home/ubuntu/captcha_model.py
# -*- coding: utf-8 -*
import tensorflow as tf
import math
class captchaModel():
def __init__(self,
width = 160,
height = 60,
char_num = 4,
classes = 62):
self.width = width
self.height = height
self.char_num = char_num
self.classes = classes
def conv2d(self,x, W):
return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')
def max_pool_2x2(self,x):
return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],
strides=[1, 2, 2, 1], padding='SAME')
def weight_variable(self,shape):
initial = tf.truncated_normal(shape, stddev=0.1)
return tf.Variable(initial)
def bias_variable(self,shape):
initial = tf.constant(0.1, shape=shape)
return tf.Variable(initial)
def create_model(self,x_images,keep_prob):
#first layer
w_conv1 = self.weight_variable([5, 5, 1, 32])
b_conv1 = self.bias_variable([32])
h_conv1 = tf.nn.relu(tf.nn.bias_add(self.conv2d(x_images, w_conv1), b_conv1))
h_pool1 = self.max_pool_2x2(h_conv1)
h_dropout1 = tf.nn.dropout(h_pool1,keep_prob)
conv_width = math.ceil(self.width/2)
conv_height = math.ceil(self.height/2)
#second layer
w_conv2 = self.weight_variable([5, 5, 32, 64])
b_conv2 = self.bias_variable([64])
h_conv2 = tf.nn.relu(tf.nn.bias_add(self.conv2d(h_dropout1, w_conv2), b_conv2))
h_pool2 = self.max_pool_2x2(h_conv2)
h_dropout2 = tf.nn.dropout(h_pool2,keep_prob)
conv_width = math.ceil(conv_width/2)
conv_height = math.ceil(conv_height/2)
#third layer
w_conv3 = self.weight_variable([5, 5, 64, 64])
b_conv3 = self.bias_variable([64])
h_conv3 = tf.nn.relu(tf.nn.bias_add(self.conv2d(h_dropout2, w_conv3), b_conv3))
h_pool3 = self.max_pool_2x2(h_conv3)
h_dropout3 = tf.nn.dropout(h_pool3,keep_prob)
conv_width = math.ceil(conv_width/2)
conv_height = math.ceil(conv_height/2)
#first fully layer
conv_width = int(conv_width)
conv_height = int(conv_height)
w_fc1 = self.weight_variable([64*conv_width*conv_height,1024])
b_fc1 = self.bias_variable([1024])
h_dropout3_flat = tf.reshape(h_dropout3,[-1,64*conv_width*conv_height])
h_fc1 = tf.nn.relu(tf.nn.bias_add(tf.matmul(h_dropout3_flat, w_fc1), b_fc1))
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)
#second fully layer
w_fc2 = self.weight_variable([1024,self.char_num*self.classes])
b_fc2 = self.bias_variable([self.char_num*self.classes])
y_conv = tf.add(tf.matmul(h_fc1_drop, w_fc2), b_fc2)
return y_conv
訓練 CNN 模型
每批次採用 64 個訓練樣本,每 100 次迴圈採用 100 個測試樣本檢查識別準確度,當準確度大於 99% 時,訓練結束,採用 GPU 需要 4-5 個小時左右,CPU 大概需要 20 個小時左右。
示例程式碼:
現在您可以在 /home/ubuntu 目錄下建立原始檔 train_captcha.py,內容可參考:
示例程式碼:/home/ubuntu/train_captcha.py
#-*- coding:utf-8 -*-
import tensorflow as tf
import numpy as np
import string
import generate_captcha
import captcha_model
if __name__ == '__main__':
captcha = generate_captcha.generateCaptcha()
width,height,char_num,characters,classes = captcha.get_parameter()
x = tf.placeholder(tf.float32, [None, height,width,1])
y_ = tf.placeholder(tf.float32, [None, char_num*classes])
keep_prob = tf.placeholder(tf.float32)
model = captcha_model.captchaModel(width,height,char_num,classes)
y_conv = model.create_model(x,keep_prob)
cross_entropy = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(labels=y_,logits=y_conv))
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
predict = tf.reshape(y_conv, [-1,char_num, classes])
real = tf.reshape(y_,[-1,char_num, classes])
correct_prediction = tf.equal(tf.argmax(predict,2), tf.argmax(real,2))
correct_prediction = tf.cast(correct_prediction, tf.float32)
accuracy = tf.reduce_mean(correct_prediction)
saver = tf.train.Saver()
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
step = 1
while True:
batch_x,batch_y = next(captcha.gen_captcha(64))
_,loss = sess.run([train_step,cross_entropy],feed_dict={x: batch_x, y_: batch_y, keep_prob: 0.75})
print ('step:%d,loss:%f' % (step,loss))
if step % 100 == 0:
batch_x_test,batch_y_test = next(captcha.gen_captcha(100))
acc = sess.run(accuracy, feed_dict={x: batch_x_test, y_: batch_y_test, keep_prob: 1.})
print ('###############################################step:%d,accuracy:%f' % (step,acc))
if acc > 0.99:
saver.save(sess,"./capcha_model.ckpt")
break
step += 1
然後執行:
cd /home/ubuntu;
python train_captcha.py
執行結果:
Ecs伺服器結果
GPU伺服器結果
可以看到,在訓練結果中,ECS伺服器的訓練時間為151893s,而GPU伺服器講訓練時間減少到了29570s,速度提升五倍以上!顯然,使用GPU伺服器進行深度學習訓練、研發人工智慧技術,將極大的提升效率。
<程式碼來源於騰訊雲開發者實驗室>
<兩種試驗用伺服器來源於新睿雲>