一、准备工作
1.打开本链接,其中代码可以直接粘贴使用。
conda install scikit-learn
conda install tensorflow
pip install keras
import numpy as np #数据库 import keras import tensorflow as tf from keras.models import Sequential #序贯模型 from keras.layers.core import Dense,Dropout,Activation #构建 keras网络结构 from keras.optimizers import SGD #SGD随机梯度下降 import matplotlib.pyplot as plt #画图
二、基于keras手写数字识别基本步骤
2.1导入数据-》2.2构建模型-》2.3训练模型-》2.4评估模型
2.1、读取mnist数据集(详见PPT),并格式转换
第一种方法:联网下载mnist数据集
from keras.datasets import mnist #网上下载minist数据集,若联网使用数据集
(x_train, y_train), (x_test, y_test) = mnist.load_data() # 使用Keras自带的mnist工具读取数据,由于网址会被隔断,需要FQ。
第二种方法:本地下载mnist数据集
path='./mnist.npz' f = np.load(path) x_train, y_train = f['x_train'], f['y_train'] #x_train存储的是图像的像素点组成的list数据类型,这里面又由一个二维的list(28 x 28的像素点值)和一个对应的标签list组成 #y_train存储的是对应图像的标签,也就是该图像代表什么数字 x_test, y_test = f['x_test'], f['y_test'] f.close()
格式转换:
x_train=x_train.reshape(x_train.shape[0],28*28).astype('float32') x_test=x_test.reshape(x_test.shape[0],28*28).astype('float32') #x_train.shape会发现它是(60000,28,28),即一共60000个数据,每个数据是28*28的图片。通过reshape转换为(60000,784)的线性张量。 num_classes=10 y_train = keras.utils.to_categorical(y_train, num_classes) y_test = keras.utils.to_categorical(y_test, num_classes) #如果我们打印y_train会发现它是一组表示每张图片的表示数字的数组,每个数字转换为一组长度为10的张量,代表的数字的位置是1,其它位置为0.
2.2 、构建模型:Sequential()序贯模型
#通常有两种模型,序贯模型和函数式模型,序贯模型是多个网络蹭的线性堆叠,是函数式模型的简略版,为最简单的线性,从头到尾的结构顺序,不发生分叉。是多个网络层的线性堆叠。
#参考:https://www.cnblogs.com/wj-1314/p/9967480.html
#选择模型 model = Sequential() ##选择Sequetial 序贯模型 #构建网络层 #第1层 隐藏层 model.add(Dense(500,input_shape=(784,)))#这是第一个隐藏层,并附带定义了输入层,该隐含层有500个神经元。输入则是 784个节点 model.add(Activation('tanh')) # 激活函数是tanh 为双曲正切 model.add(Dropout(0.5)) # 随机取一半进行训练 ##第2层 隐藏层 model.add(Dense(200)) #隐藏节点200 model.add(Activation('tanh')) #激活函数 正切函数 model.add(Dropout(0.5)) #随机丢掉百分之五十的权值,作用相当于对参数进行正则化来防止模型过拟合 ##第3层 输出层 model.add(Dense(10))#输出结果是10个类别,所以维度是10 model.add(Activation('softmax')) #激活函数 归一化softmax model.summary()
通过model.add()增加模型的层数。其中Dense()设定该层的结构,第一个参数表示输出的个数,第二个参数是接受的输入数据的格式。第一层中需要指定输入的格式,在之后的增加的层中输入层节点数默认是上一层的输出个数。Activation()指定激活函数,Dropout()指定每层要丢掉的权值信息百分比。输出层激活函数一般为softmax,不需要丢弃节点。
编译模型:
sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True) # 优化函数,设定学习率(lr)等参数 # lr:学习率 # momentum:动量参数 # decay:每次更新后的学习率衰减值 # nesterov:确定是否使用Nesterov动量(指数1e-9) #有通过了编译,model才真正的建立起来,这时候才能够被使用 model.compile(optimizer=sgd,loss='categorical_crossentropy', metrics=['accuracy']) # 使用交叉熵作为loss函数
2.3、训练模型:
#训练 print("start model training(fitting)") model.fit(x_train,y_train,batch_size=500,epochs=50,shuffle=True,verbose=0,validation_split=0.3) #fit的一些参数 # batch_size:对总的样本数进行分组,每组包含的样本数量 # epochs :训练次数 #shuffle:是否把数据随机打乱之后再进行训练 #verbose:屏显模式 0:不输出 1:输出进度 2:输出每次的训练结果 #validation_split:拿出百分之多少用来做交叉验证 print("model training(fitting) finished, save model") model.save('./now_model.h5')
2.4 、评估模型
print("calculating model accuracy") loss, accuracy = model.evaluate(x_test,y_test,batch_size=500,verbose=0) #evaluate是在每个batch后得到一个值,而predict是在k个batch后得到的一个均值。 print('Test loss:', loss) print('Accuracy:', accuracy)
三、用户测评
3.1 导入相应的函数
import keras from keras.models import load_model #加载模型 from keras.optimizers import SGD #优化函数 from PIL import Image import numpy as np #数据库 import matplotlib.pyplot as plt #画图
# 准备待识别的图片数据 testImage=Image.open("test3.jpg") testImage=testImage.convert("L") testImageForModel=np.array(testImage) plt.subplot(221) #subplot函数的作用是确定图像的位置以及图像的个数,总共放置2*2个图片,放在第一个位置 plt.imshow(testImage, cmap=plt.get_cmap('gray')) testImageForModelFinal=testImageForModel.reshape(1,28*28).astype('float32') #转成可以输入到模型中的格式x_test_input,x_test是可以直接使用cv2显示处理
3.2加载模型,识别数字结果
#加载模型,使用该模型识别数字图片 model=load_model('./now_model.h5') sgd=SGD(lr=0.01,momentum=0.9,decay=1e-9,nesterov=True)#优化函数,参数有学习率,学习衰退率 ,指数1e-9这样写 model.compile(optimizer=sgd,loss='categorical_crossentropy') # 使用交叉熵作为loss函数 print("finshing loading model,starting application")
ans=model.predict(testImageForModelFinal) #输入该数据到模型,得到预测结果的概率 print(ans) ansmax=np.argmax(ans) #找到每行最大的序号 print(ansmax)