提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
minist数字识别,是深度学习入门数据集。这里使用了三种方式来实现对minist数字分类。分别是逻辑回归,多层感知机,以及我们熟悉的cnn(卷积神经网络)。这里是基于tensorflow来实现的代码,很好入门。
一、cnn实现minist代码
import time
import tensorflow as tf
import numpy as np
from matplotlib import pyplot as plt
import numpy as np
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets( 'Minist_data',one_hot=True)
#参数初始化
input_num = 784 # 输入的列数
labels = 10 #输出的列数
batchsize = 128 #训练集每一批次的照片
max_epochs = 1000 #迭代的次数
dropout = 0.85
#这里设置的x,y的作用是来存储输入的照片个数,和标签个数
x = tf.placeholder(tf.float32,[None, input_num])
y = tf.placeholder(tf.float32,[None, labels])
# 数据处理,标注化
def normallize( x ):
mean_x = np.mean( x )
std_x = np.std( x )
x = (x - mean_x)/ std_x
return x
#设置卷积层,x:输入的照片,w对应的权值,这里才去的是不填充
def con2d(x , w , b, strides = 1):
x = tf.nn.conv2d(x, w, strides=[1, strides,strides,1], padding = 'VALID')
x = tf.nn.bias_add(x, b)
return tf.nn.relu( x)
#池化层
def maxpool2d(x, k=2):
return tf.nn.max_pool(x, ksize=[1,k,k,1], strides =[1, k, k, 1] , padding = 'SAME')
#设置模型
def con2dnet(x, weights, biases ,dropout):
#因为输入的数据是1行784行,需要转化为28行,28列,这里只是对于一张图开始讨论的哈
x = tf.reshape(x, shape=[-1, 28, 28, 1])
#第一个卷积层 28x28x1 change to 24x24x32
con_1 = con2d( x, weights['wc1'] , biases['bd1'])
#第一个池化层 24x24x32 change to 12x12x32
con_1_maxpol = maxpool2d(con_1, k=2)
#第二个卷积层 12x12x32 change to 8x8x64
con_2 = con2d( con_1_maxpol, weights['wc2'] , biases['bd2'])
#第二个池化层 8x8x64 change to 4x4x64
con_1_maxpo2 = maxpool2d(con_2, k=2)
#全连接层 4*4*64(每一个特征图4*4,共有64个),变化成一行4*4*64,便于全连接
#这里批次是128张图,那么就是128个行4*4*64
fc1 = tf.reshape(con_1_maxpo2,[-1,weight['wd1'].get_shape().as_list()[0]])
#这个就是全连接层的计算 [1,4x4x64] change to [1, 1024]
fc2 = tf.add(tf.matmul(fc1, weight['wd1']), biases['bd3'])
weight = {
'wc1':tf.Variable(tf.random_normal([5,5,1,32])),
'wc2':tf.Variable(tf.random_normal([5,5,32,64])),
'wd1':tf.Variable(tf.random_normal([4*4*64,1024])),
'wd2':tf.Variable(tf.random_normal([1024,10]))}
biases = {
'bd1':tf.Variable(tf.random_normal([32])),
'bd2':tf.Variable(tf.random_normal([64])),
'bd3':tf.Variable(tf.random_normal([1024])),
'bd4':tf.Variable(tf.random_normal([10]))}
fc2 = tf.nn.relu(fc2)
# dropout层
fc3 = tf.nn.dropout(fc2,dropout)
# [1,1024] change to [1, 10]
fc3 = tf.add(tf.matmul(fc2, weight['wd2']),biases['bd4'])
return fc3
pred = con2dnet( x, weight, biases , dropout)
coss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred, labels = y))
optimizer = tf.train.AdamOptimizer(learning_rate = 0.01).minimize(coss)
correct_prediction = tf.equal(tf.argmax(pred,1), tf.argmax(y,1))
corrct_num = tf.reduce_sum(tf.cast(correct_prediction, "float"))
init_op = tf.global_variables_initializer()
with tf.Session() as sess:
accucy_list = [] #存续每次迭代后的准确率
accucy_coss = [] #存续每次迭代后的损失值率
sess.run(init_op)
for eopch in range(max_epochs):
train_x, train_y = mnist.train.next_batch(batchsize)
z = sess.run(optimizer, feed_dict={
x: train_x, y: train_y})
coss_1, num_1 = sess.run([coss, corrct_num], feed_dict={
x:mnist.test.images, y:mnist.test.labels})
print('epoch:{0}, accucy:{1}:'.format(eopch, num_1/10000))
accucy_list.append(num_1/10000)
accucy_coss.append(coss_1/10000)
plt.title('test_accucy')
plt.xlabel('epochs')
plt.ylabel('accucy')
plt.plot(accucy_list)
plt.show()
plt.title('test_coss')
plt.xlabel('epochs')
plt.ylabel('coss')
plt.plot(accucy_coss)
plt.show()
实现结果:
epoch:986, accucy:0.9639:
epoch:987, accucy:0.9645:
epoch:988, accucy:0.9653:
epoch:989, accucy:0.9649:
epoch:990, accucy:0.9643:
epoch:991, accucy:0.9634:
epoch:992, accucy:0.9623:
epoch:993, accucy:0.9625:
epoch:994, accucy:0.963:
epoch:995, accucy:0.9635:
epoch:996, accucy:0.9638:
epoch:997, accucy:0.9643:
epoch:998, accucy:0.9645:
epoch:999, accucy:0.964:
二、多层感知器实现minist代码
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import time
mnist = input_data.read_data_sets('Minist_data', one_hot=True)
n_input = 784 #input num
n_labels = 10 # output num
n_hidden_layer = 30 # hidden layer
max_epochs = 10000
batch_size = 100
alphy = 0.2
seed = 0
# 设置sigmoid 函数求导公式
def sigmoid_derivation( x ):
return tf.multiply(tf.sigmoid( x ), tf.subtract(tf.constant(1.0), tf.sigmoid( x)))
# 设置权重
weigths = {
'w_1':tf.Variable(tf.random_normal([ n_input, n_hidden_layer], seed=seed)), 'w_2':tf.Variable(tf.random_normal([n_hidden_layer, n_labels],seed=seed))}
basis = {
'basis_1': tf.Variable(tf.random_normal([1,n_hidden_layer],seed=seed)),'basis_2':tf.Variable(tf.Variable(tf.random_normal([1,n_labels],seed=seed)))}
#设置占位符
x_in = tf.placeholder(tf.float32, [None, n_input])
y = tf.placeholder(tf.float32, [None, n_labels])
def creat_model(x_in , weight, basis):
h_1 = tf.matmul(x_in, weight['w_1']) + basis['basis_1']
o_1 = tf.sigmoid( h_1 )
h_2 = tf.matmul( o_1, weight['w_2']) + basis['basis_2']
o_2 = tf.sigmoid (h_2)
return h_1, o_1, h_2, o_2
#Forward pass
h_1, o_1, h_2, y_hat = creat_model(x_in, weigths, basis)
# #error
error = y_hat - y
#backward pass
delta_2 = tf.multiply( error, sigmoid_derivation( h_2 ))
delta_w_2 = tf.matmul(tf.transpose(o_1), delta_2)
wtd_error = tf.matmul(delta_2, tf.transpose(weigths['w_2']))
delta_1 = tf.multiply(wtd_error, sigmoid_derivation( h_1 ))
delta_w_1 = tf.matmul(tf.transpose(x_in), delta_1 )
alphy = tf.constant( alphy )
# #upgraduate weights
step = [tf.assign(weigths['w_1'], tf.subtract(weigths['w_1'],tf.multiply(alphy, delta_w_1)))
,tf.assign(weigths['w_2'], tf.subtract(weigths['w_2'],tf.multiply(alphy, delta_w_2)))]
acc_mat = tf.equal(tf.argmax(y_hat,1), tf.argmax(y,1))
acc_num = tf.reduce_sum(tf.cast(acc_mat, tf.float32))
#initiallizer
initi_op = tf.global_variables_initializer()
#start session
with tf.Session( ) as sess:
sess.run(initi_op)
for epoch in range(max_epochs):
batch_xs, batch_ys = mnist.train.next_batch(batch_size)
sess.run(step, feed_dict={
x_in:batch_xs, y : batch_ys})
if epoch % 1000 == 0:
acc_test = sess.run(acc_num, feed_dict={
x_in:mnist.test.images, y:mnist.test.labels})
acc_train = sess.run(acc_num, feed_dict={
x_in:mnist.train.images, y:mnist.train.labels})
print('Epoch:{0} , accurcy_test:{1}, accurcy_train:{2}'.format(epoch, acc_test/10000,acc_train/55000))
实现结果:
Epoch:0 , accurcy_test:0.1063, accurcy_train:0.10627272727272727
Epoch:1000 , accurcy_test:0.653, accurcy_train:0.6551636363636364
Epoch:2000 , accurcy_test:0.6668, accurcy_train:0.6692
Epoch:3000 , accurcy_test:0.6667, accurcy_train:0.6737272727272727
Epoch:4000 , accurcy_test:0.7601, accurcy_train:0.7695272727272727
Epoch:5000 , accurcy_test:0.7634, accurcy_train:0.7738181818181818
Epoch:6000 , accurcy_test:0.8517, accurcy_train:0.862890909090909
Epoch:7000 , accurcy_test:0.858, accurcy_train:0.8671454545454546
Epoch:8000 , accurcy_test:0.8631, accurcy_train:0.8733090909090909
Epoch:9000 , accurcy_test:0.9413, accurcy_train:0.9572
三、逻辑回归实现minist代码
#利用逻辑回归实现对于mnist的数据分类
import tensorflow as tf
import matplotlib.pyplot as plt, matplotlib.image as mpimg
from tensorflow.examples.tutorials.mnist import input_data
#读取数据
mnist = input_data.read_data_sets('\Minist_data',one_hot = True)
#给权值赋值
w = tf.Variable(tf.zeros([784,10]), name = 'w')
b = tf.Variable(tf.zeros([10]), name = 'b')
# x = tf.Variable(tf.float32, name = 'x', shape = [None,784])
# y = tf.Variable(tf.float32, name = 'y', shape = [None,10])
#设置x,y的占位符,很简单,对于x 784一个照片的大小,None 不知道你每次需要训练的批次大小
x = tf.placeholder(tf.float32, [None,784],name = 'x')
y = tf.placeholder(tf.float32, [None,10], name = 'y')
# 设置预测值
y_hat = tf.matmul(x,w)+b
#设置损失函数,交叉熵 tf.reduce_mean求得是所有交叉熵的平均值
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels = y, logits = y_hat))
#选择最优梯度下降参数
optimizer = tf.train.GradientDescentOptimizer(learning_rate = 0.01).minimize(loss)
#预测
correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_hat,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
#初始化
initi_op = tf.global_variables_initializer()
with tf.Session() as sess:
total = [] #便于画图
sess.run(initi_op)
for epoch in range(50):
loss_avg = 0
batch_size = 100
num_of_batch = int(mnist.train.num_examples/batch_size)
for i in range(num_of_batch):
batch_xs,batch_ys = mnist.train.next_batch(100)
_, l = sess.run([optimizer, loss], feed_dict = {
x:batch_xs, y:batch_ys})
loss_avg = loss_avg + l
print('Epoch :{0} ,loss: {1}'.format(epoch,loss_avg/num_of_batch))
total.append(loss_avg/num_of_batch)
print('Done')
print(sess.run(accuracy, feed_dict={
x: mnist.test.images, y:mnist.test.labels}))
plt.plot(total)
plt.show()
实现结果:
Epoch :49 ,loss: 0.2860406456481327
Epoch :49 ,loss: 0.2863932258974422
Epoch :49 ,loss: 0.2869208517399701
Epoch :49 ,loss: 0.28743210982192646
Epoch :49 ,loss: 0.28812870155681264
Epoch :49 ,loss: 0.2885602289167317
Epoch :49 ,loss: 0.28918006840077315
Epoch :49 ,loss: 0.28969469279050825
Epoch :49 ,loss: 0.29052486633712593
Epoch :49 ,loss: 0.29099014274098656
Epoch :49 ,loss: 0.2915572559020736
Epoch :49 ,loss: 0.29206312930042094
Epoch :49 ,loss: 0.29243259806524624
Epoch :49 ,loss: 0.2931043164567514
Epoch :49 ,loss: 0.29356380319053477
Epoch :49 ,loss: 0.29405322256413374
Epoch :49 ,loss: 0.2947297677397728
Epoch :49 ,loss: 0.29508687217127194
Epoch :49 ,loss: 0.29597209028222343
Epoch :49 ,loss: 0.2963061141154983
Epoch :49 ,loss: 0.2969307041439143
Epoch :49 ,loss: 0.2975302829796618
Epoch :49 ,loss: 0.29785606977614487
Epoch :49 ,loss: 0.29842295774004673
Epoch :49 ,loss: 0.2990792263366959
Epoch :49 ,loss: 0.299645564745773
Epoch :49 ,loss: 0.3001909241080284
Epoch :49 ,loss: 0.30061151071028275
Epoch :49 ,loss: 0.30132105106657203
Epoch :49 ,loss: 0.30179316797039724
Epoch :49 ,loss: 0.3024873532490297
Epoch :49 ,loss: 0.3029060740362514
Epoch :49 ,loss: 0.3035559590296312
Epoch :49 ,loss: 0.30405486394058573
Epoch :49 ,loss: 0.30449492687528784
Done
0.9191
该处使用的url网络请求的数据。
总结
代码简单,易懂。通过对比,你会发现cnn的运算数度慢,准确率三者差不多。
来源:oschina
链接:https://my.oschina.net/u/4340703/blog/4728247