之前學(xué)習(xí)神經(jīng)網(wǎng)絡(luò)時寫代碼用的是C++ 寫的扔傅,代碼冗長而且容易出錯〗J幔現(xiàn)在學(xué)了Python發(fā)現(xiàn)用Python-tensorflow寫神經(jīng)網(wǎng)絡(luò)代碼非常的簡潔苗傅。
一捺球、材料準(zhǔn)備
Python 3.5缸浦,可通過官網(wǎng)下載
tensorflow,可用pip install tensorflow
命令安裝
Pycharm 2017氮兵,百度有一大堆破解教程
MNIST數(shù)據(jù)集裂逐,下載地址
二、實(shí)現(xiàn)代碼
先把下載到的這幾個壓縮包解壓出來:
我解壓到了如下的目錄
讀取數(shù)據(jù)
offset | type | value | description |
---|---|---|---|
0000 | 32 bit integer | 0x00000801(2049) | magic number (MSB first) |
0004 | 32 bit integer | 60000 | number of items |
0008 | unsigned byte | ?? | label |
0009 | unsigned byte | ?? | label |
........ |
數(shù)據(jù)的內(nèi)容格式如下:
訓(xùn)練標(biāo)簽數(shù)據(jù)(labels-idx1-ubyte):
offset | type | value | description |
---|---|---|---|
0000 | 32 bit integer | 0x00000801(2049) | magic number (MSB first) |
0004 | 32 bit integer | 60000 | number of items |
0008 | unsigned byte | ?? | label |
0009 | unsigned byte | ?? | label |
........ |
The labels values are 0 to 9.
offset | type | value | description |
---|---|---|---|
0000 | 32 bit integer | 0x00000803(2051) | magic number |
0004 | 32 bit integer | 60000 | number of images |
0008 | 32 bit integer | 28 | number of rows |
0012 | 32 bit integer | 28 | number of columns |
0016 | unsigned byte | ?? | pixel |
0017 | unsigned byte | ?? | pixel |
........ |
訓(xùn)練圖像數(shù)據(jù) (images-idx3-ubyte):
offset | type | value | description |
---|---|---|---|
0000 | 32 bit integer | 0x00000803(2051) | magic number |
0004 | 32 bit integer | 60000 | number of images |
0008 | 32 bit integer | 28 | number of rows |
0012 | 32 bit integer | 28 | number of columns |
0016 | unsigned byte | ?? | pixel |
0017 | unsigned byte | ?? | pixel |
........ |
Pixels are organized row-wise. Pixel values are 0 to 255. 0 means background (white), 255 means foreground (black).
offset | type | value | description |
---|---|---|---|
0000 | 32 bit integer | 0x00000801(2049) | magic number (MSB first) |
0004 | 32 bit integer | 10000 | number of items |
0008 | unsigned byte | ?? | label |
0009 | unsigned byte | ?? | label |
........ |
測試標(biāo)簽數(shù)據(jù) (t10k-labels-idx1-ubyte):
offset | type | value | description |
---|---|---|---|
0000 | 32 bit integer | 0x00000801(2049) | magic number (MSB first) |
0004 | 32 bit integer | 10000 | number of items |
0008 | unsigned byte | ?? | label |
0009 | unsigned byte | ?? | label |
........ |
The labels values are 0 to 9.
offset | type | value | description |
---|---|---|---|
0000 | 32 bit integer | 0x00000803(2051) | magic number |
0004 | 32 bit integer | 10000 | number of images |
0008 | 32 bit integer | 28 | number of rows |
0012 | 32 bit integer | 28 | number of columns |
0016 | unsigned byte | ?? | pixel |
0017 | unsigned byte | ?? | pixel |
........ |
測試圖像數(shù)據(jù) (t10k-images-idx3-ubyte):
offset | type | value | description |
---|---|---|---|
0000 | 32 bit integer | 0x00000803(2051) | magic number |
0004 | 32 bit integer | 10000 | number of images |
0008 | 32 bit integer | 28 | number of rows |
0012 | 32 bit integer | 28 | number of columns |
0016 | unsigned byte | ?? | pixel |
0017 | unsigned byte | ?? | pixel |
........ |
Pixels are organized row-wise. Pixel values are 0 to 255. 0 means background (white), 255 means foreground (black).
讀取數(shù)據(jù)代碼:
def read_train_data():
file = open('mnist_data/images-idx3-ubyte','rb')
'''
跳過了魔術(shù)碼(4 byte)
圖像數(shù)量讀取(4 byte)
行(4 byte)泣栈、列(4 byte)
'''
file.seek(4*4)
img = []
for i in range(60000):
tmp = []
for j in range(784):
t = struct.unpack('b',file.read(1))
if t[0] > -1:
tmp.append(0)
else:
tmp.append(1)
img.append(tmp)
file = open('mnist_data/labels-idx1-ubyte','rb')
'''
跳過了魔術(shù)碼(4 byte)
標(biāo)簽數(shù)量(4 byte)
'''
file.seek(4*2)
label = []
for i in range(60000):
t = struct.unpack('b', file.read(1))
tmp = []
for j in range(10):
if t[0] == j:
tmp.append(1)
else:
tmp.append(0)
label.append(tmp)
return img,label
神經(jīng)網(wǎng)絡(luò)模型:
我要構(gòu)建的神經(jīng)網(wǎng)絡(luò)模型如下:
訓(xùn)練代碼:
if __name__ == "__main__":
x = tf.placeholder("float", [None, 784])
w1 = tf.Variable(tf.random_uniform([784, 120], -1.0, 1.0))
b1 = tf.Variable(tf.random_uniform([120], -1.0, 1))
w2 = tf.Variable(tf.random_uniform([120, 10], -1.0, 1.0))
b2 = tf.Variable(tf.random_uniform([10], -1.0, 1.0))
hid = tf.nn.sigmoid(tf.matmul(x, w1) + b1)
output = tf.nn.softmax(tf.matmul(hid, w2) + b2)
output_ = tf.placeholder("float", [None, 10])
cross_entropy = -tf.reduce_sum(output_ * tf.log(output))
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)
IMG, LABEL = read_train_data()
# 訓(xùn)練200次
for i in range(200):
j = 0
while j < 60000:
batch_xs, batch_ys = get_batch(IMG, LABEL, j, 100)
sess.run(train_step, feed_dict={x: batch_xs, output_: batch_ys})
j += 100
W1 = sess.run(w1)
W2 = sess.run(w2)
B1 = sess.run(b1)
B2 = sess.run(b2)
# 把神經(jīng)網(wǎng)絡(luò)模型參數(shù)保存下來
save_para(W1,W2,B1,B2)
sess.close()
測試代碼:
import tensorflow as tf
import struct
def restore_para():
W1 = []
W2 = []
B1 = []
B2 = []
# 載入weight
file = open('mnist_para/w1', 'rb')
for i in range(784):
tmp = []
for j in range(120):
t = struct.unpack("f", file.read(4))
tmp.append(t[0])
W1.append(tmp)
file.close()
file = open('mnist_para/w2', 'rb')
for i in range(120):
tmp = []
for j in range(10):
t = struct.unpack("f", file.read(4))
tmp.append(t[0])
W2.append(tmp)
file.close()
# 載入bias
file = open('mnist_para/b1', 'rb')
for i in range(120):
t = struct.unpack('f', file.read(4))
B1.append(t[0])
file.close()
file = open('mnist_para/b2', 'rb')
for i in range(10):
t = struct.unpack('f', file.read(4))
B2.append(t[0])
file.close()
w1 = tf.constant(W1)
b1 = tf.constant(B1)
w2 = tf.constant(W2)
b2 = tf.constant(B2)
return w1, b1, w2, b2
def read_test_data():
file = open('mnist_data\\t10k-images-idx3-ubyte', 'rb')
file.seek(4 * 4)
img = []
for i in range(10000):
tmp = []
for j in range(784):
t = struct.unpack('b', file.read(1))
if t[0] > -1:
tmp.append(0)
else:
tmp.append(1)
img.append(tmp)
file = open('mnist_data\\t10k-labels-idx1-ubyte', 'rb')
file.seek(4 * 2)
label = []
for i in range(10000):
t = struct.unpack('b', file.read(1))
tmp = []
for j in range(10):
if t[0] == j:
tmp.append(1)
else:
tmp.append(0)
label.append(tmp)
return img, label
if __name__ == "__main__":
x = tf.placeholder("float",[None,784])
w1, b1, w2, b2 = restore_para()
hid = tf.nn.sigmoid(tf.matmul(x,w1)+b1)
output = tf.nn.softmax(tf.matmul(hid,w2)+b2)
output_ = tf.placeholder("float",[None,10])
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)
IMG, LABEL = read_test_data()
correct_prediction = tf.equal(tf.argmax(output, 1), tf.argmax(output_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
print("識別率:")
print(sess.run(accuracy, feed_dict={x: IMG, output_:LABEL}))
sess.close()
最后的識別率能達(dá)到95.93%左右卜高,下次嘗試用卷積神經(jīng)網(wǎng)絡(luò)來識別,識別率用改會更高一些南片。