无痛实现深度学习小项目(使用keras实现手写数字图片识别)
使用keras中自带的mnist(手写图片)数据集训练一个识别模型。
一.理论知识: 深度学习(建议看李宏毅的深度学习视频补充理论知识)。
二.工作环境:使用Anaconda的juypter notebook(python全家桶,里面集成了许多有用的包),然后安装TensorFlow库,安装方法上网搜一下。
三.源码:
#导包
import numpy as np
from tensorflow import keras
from tensorflow.python.keras.models import Sequential
from tensorflow.python.keras.layers import Conv2D,MaxPooling2D,Flatten
from tensorflow.python.keras.layers import Dense,Dropout,Activation
from tensorflow.python.keras.optimizers import SGD,Adam
from tensorflow.python.keras.utils import np_utils
from tensorflow.python.keras.datasets import mnist
import tensorflow as tf
#导入数据,不用过多纠结这里,就是处理数据的一个功能
def load_data():
(x_train,y_train),(x_test,y_test) = mnist.load_data()
number = 10000
x_train = x_train[0:number]
y_train = y_train[0:number]
x_train = x_train.reshape(number,28*28)
x_test = x_test.reshape(x_test.shape[0],28*28)
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
y_train = np_utils.to_categorical(y_train,10)
y_test = np_utils.to_categorical(y_test,10)
x_train = x_train
x_test = x_test
x_train = x_train / 255
x_test = x_test / 255
return (x_train,y_train),(x_test,y_test)
(x_train,y_train),(x_test,y_test) = load_data()
#ps:运行代码,数据会自动下载,如果无法正常下载,则手动将数据包放入默认目录, C:\Users\(你电脑的用户名)#\.keras\datasets 下载地址:https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz
#查看一下我们训练样本的数据格式
x_train.shape #输出(10000,784),说明训练数据是二维的,表示有一万个训练样本,每一个样本有28*28=784个值
#查看我们输出样本(也就是标签)的数据格式
y_train.shape
#输出(10000,10),说明输出样本数据是二维的,表示一万个训练样本,每一个样本有10个值.因为
#我们用one-hot来表示数据,总共有0,1,2,3....9,有10个数字,用10维的向量表示数字。比如[0,0,1,0,0,0,0,0,0]表示数字2,[1,0,0,0,0,0,0,0,0,0,]表示数据0
#建立神经网络结构
model = model = Sequential()#建立神经网络结构
#第一层,input_dim=28*28,表示每一个输入样本维度是784=28*28,units=666表示该神经元有666个,activation表示**函数#选择sigmoid
model.add(Dense(input_dim=28*28,units=666,activation = 'sigmoid'))
#第二层,可以直接写units=666,输入就是上一层的输出
model.add(Dense(units=666,activation='sigmoid'))
#第三层
model.add(Dense(units=500,activation='sigmoid'))
#第四层,units必须等于10,因为我们的输出是10个维度的向量,因为这里是一个多分类问题,所以最后一层activation选择#softmax**函数
model.add(Dense(units=10,activation='softmax'))
oprimizer=SGD(lr=0.1)#优化器选择SGD,学习率为0.1
model.compile(loss='mse'),
optimizer=optimizer,
metrics=[tf.keras.metrics.CategoricalAccuracy()]
# 查看神经网络结构
model.summary()
#开始训练
model.fit(x_train,y_train,batch_size=100,epochs=20)
#评估模型,输出loss,这里实际上已经把模型训练完了,可以调整参数,重新训练来优化模型。
result = model.evaluate(x_test, y_test)
print(result)
#最后用模型做预测,预测需要做一点处理,因为我们的输出结果是一个10维的向量,但是在对应的位置不是简单的0和1,而是
#一个概率,我们可以打印看一下
predict=model.predict(x_test)
def as_num(x):
y='{:.10f}'.format(x) # 10f表示保留10位小数点的float型
return(y)
i= predict[0]
x=[]
for j in i:
x.append(as_num(j))
print(x)#预测第一个测试样本的值
#可以看到第7个数字0.9999686480最接近1,所以我们可以知道该位是1的概率为0.9999968480
#所以我们可以对预测得到的数据做这样的处理,即设置一个阈值,如果该位>阈值时,则置为1否则置为0,我们设置阈值为0.5
for i in range(10000):
for j in range(10):
if(predict[i][j]<0.5):predict[i][j]=0# 遍历预测的值(矩阵),如果>0.5将该位置为1
else:predict[i][j]=1
#处理完毕后,我们来看一下预测结果跟测试样本结果的比较
#统计测试集有多少预测正确的,并打印出来查看数据
x=0
for i in range(10000):
if((predict[i]==y_test[i]).all()):
print(y_test[i],predict[i])
x=x+1
print(x/10000)#计算准确率,判断正确的样本/总样本