我們在安裝tensorflow-gpu後,其運作時我們可以標明使用gpu來進行加速訓練,這無疑會幫助我們加快訓練腳步。
(注意:當我們的tensorflow-gpu安裝後,其預設會使用gpu來訓練)
之前部落客已經為自己的python環境安裝了tensorflow-gpu,詳情參考:
Tensorflow安裝 安裝完成後,我們以BP神經網絡算法實作手寫數字識别這個項目為例
首先先對BP神經網絡的原理進行簡單了解
BP神經網絡實作手寫數字識别
# -*- coding: utf-8 -*-
"""
手寫數字識别, BP神經網絡算法
"""
# -------------------------------------------
'''
使用python解析二進制檔案
'''
import numpy as np
import struct
import random
import tensorflow as tf
from sklearn.model_selection import train_test_split
import os
os.environ["CUDA_VISIBLE_DEVICES"] = "0" # 強制使用cpu
import time
T1 = time.clock()
class LoadData(object):
def __init__(self, file1, file2):
self.file1 = file1
self.file2 = file2
# 載入訓練集
def loadImageSet(self):
binfile = open(self.file1, 'rb') # 讀取二進制檔案
buffers = binfile.read() # 緩沖
head = struct.unpack_from('>IIII', buffers, 0) # 取前4個整數,傳回一個元組
offset = struct.calcsize('>IIII') # 定位到data開始的位置
imgNum = head[1] # 圖像個數
width = head[2] # 行數,28行
height = head[3] # 列數,28
bits = imgNum*width*height # data一共有60000*28*28個像素值
bitsString = '>' + str(bits) + 'B' # fmt格式:'>47040000B'
imgs = struct.unpack_from(bitsString, buffers, offset) # 取data資料,傳回一個元組
binfile.close()
imgs = np.reshape(imgs, [imgNum, width*height])
return imgs, head
# 載入訓練集标簽
def loadLabelSet(self):
binfile = open(self.file2, 'rb') # 讀取二進制檔案
buffers = binfile.read() # 緩沖
head = struct.unpack_from('>II', buffers, 0) # 取前2個整數,傳回一個元組
offset = struct.calcsize('>II') # 定位到label開始的位置
labelNum = head[1] # label個數
numString = '>' + str(labelNum) + 'B'
labels = struct.unpack_from(numString, buffers, offset) # 取label資料
binfile.close()
labels = np.reshape(labels, [labelNum]) # 轉型為清單(一維數組)
return labels, head
# 将标簽拓展為10維向量
def expand_lables(self):
labels, head = self.loadLabelSet()
expand_lables = []
for label in labels:
zero_vector = np.zeros((1, 10))
zero_vector[0, label] = 1
expand_lables.append(zero_vector)
return expand_lables
# 将樣本與标簽組合成數組[[array(data), array(label)], []...]
def loadData(self):
imags, head = self.loadImageSet()
expand_lables = self.expand_lables()
data = []
for i in range(imags.shape[0]):
imags[i] = imags[i].reshape((1, 784))
data.append([imags[i], expand_lables[i]])
return data
file1 = r'train-images.idx3-ubyte'
file2 = r'train-labels.idx1-ubyte'
trainingData = LoadData(file1, file2)
training_data = trainingData.loadData()
file3 = r't10k-images.idx3-ubyte'
file4 = r't10k-labels.idx1-ubyte'
testData = LoadData(file3, file4)
test_data = testData.loadData()
X_train = [i[0] for i in training_data]
y_train = [i[1][0] for i in training_data]
X_test = [i[0] for i in test_data]
y_test = [i[1][0] for i in test_data]
X_train, X_validation, y_train, y_validation = train_test_split(X_train, y_train, test_size=0.1, random_state=7)
# print(np.array(X_test).shape)
# print(np.array(y_test).shape)
# print(np.array(X_train).shape)
# print(np.array(y_train).shape)
INUPUT_NODE = 784
OUTPUT_NODE = 10
LAYER1_NODE = 500
BATCH_SIZE = 200
LERANING_RATE_BASE = 0.005 # 基礎的學習率
LERANING_RATE_DACAY = 0.99 # 學習率的衰減率
REGULARZATION_RATE = 0.01 # 正則化項在損失函數中的系數
TRAINING_STEPS = 30000
MOVING_AVERAGE_DECAY = 0.99 # 滑動平均衰減率
# 三層全連接配接神經網絡,滑動平均類
def inference(input_tensor, avg_class, weights1, biases1, weights2, biases2):
if not avg_class:
layer1 = tf.nn.relu(tf.matmul(input_tensor, weights1)+biases1)
# 沒有使用softmax層輸出
return tf.matmul(layer1, weights2)+biases2
else:
layer1 = tf.nn.relu(tf.matmul(input_tensor, avg_class.average(weights1))+
avg_class.average(biases1))
return tf.matmul(layer1, avg_class.average(weights2))+avg_class.average(biases2)
def train(X_train, X_validation, y_train, y_validation, X_test, y_test):
x = tf.placeholder(tf.float32, [None, INUPUT_NODE], name="x-input")
y_ = tf.placeholder(tf.float32, [None, OUTPUT_NODE], name="y-input")
# 生成隐藏層
weights1 = tf.Variable(
tf.truncated_normal([INUPUT_NODE, LAYER1_NODE], stddev=0.1))
biases1 = tf.Variable(tf.constant(0.1, shape=[LAYER1_NODE]))
# 生成輸出層
weights2 = tf.Variable(
tf.truncated_normal([LAYER1_NODE, OUTPUT_NODE], stddev=0.1))
biases2 = tf.Variable(tf.constant(0.1, shape=[OUTPUT_NODE]))
y = inference(x, None, weights1, biases1, weights2, biases2)
global_step = tf.Variable(0, trainable=False)
variable_averages = tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY, global_step)
variable_averages_op = variable_averages.apply(tf.trainable_variables())
average_y = inference(x, variable_averages, weights1, biases1, weights2, biases2)
cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y, labels=tf.argmax(y_, 1))
cross_entropy_mean = tf.reduce_mean(cross_entropy)
# L2正則化損失
regularizer = tf.contrib.layers.l2_regularizer(REGULARZATION_RATE)
regularization = regularizer(weights1) + regularizer(weights2)
loss = cross_entropy_mean + regularization
# 指數衰減的學習率
learning_rate = tf.train.exponential_decay(LERANING_RATE_BASE,
global_step,
len(X_train)/BATCH_SIZE,
LERANING_RATE_DACAY)
train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss, global_step=global_step)
with tf.control_dependencies([train_step, variable_averages_op]):
train_op = tf.no_op(name='train')
correct_prediction = tf.equal(tf.argmax(average_y, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
with tf.Session() as sess:
init_op = tf.global_variables_initializer()
sess.run(init_op)
validation_feed = {x: X_validation, y_: y_validation}
train_feed = {x: X_train, y_: y_train}
test_feed = {x: X_test, y_: y_test}
for i in range(TRAINING_STEPS):
if i % 500 == 0:
validate_acc = sess.run(accuracy, feed_dict=validation_feed)
print("after %d training step(s), validation accuracy "
"using average model is %g" % (i, validate_acc))
start = (i * BATCH_SIZE) % len(X_train)
end = min(start + BATCH_SIZE, len(X_train))
sess.run(train_op,
feed_dict={x: X_train[start:end], y_: y_train[start:end]})
# print('loss:', sess.run(loss))
test_acc = sess.run(accuracy, feed_dict=test_feed)
print("after %d training step(s), test accuracy using"
"average model is %g" % (TRAINING_STEPS, test_acc))
train(X_train, X_validation, y_train, y_validation, X_test, y_test)
T2 = time.clock()
print('程式運作時間:%s毫秒' % ((T2 - T1)*1000))
GPU運作結果
CPU運作結果