#训练神经网络
#给出一张28*28像素手写0-9数字图片,判断出数字
#准备:训练库[图片训练集,标签训练集,图片测试集,标签测试集]
#训练集链接:https://pan.baidu.com/s/11sicY5zfXgUTThY74RAcyw
提取码:uxcg
#安装keras库,tensorflow[老式电脑,cpu可能不支持最新版tensorflow,指定版本==1.5可以]
#安装库路径,使用国内源会快很多,类似下面格式
#pip install jieba -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com#安装jieba示例
创建mnist.py
功能封装图片和标签加载处理类和方法:
import numpy as np
class loader(object):#加载文件内容
def __init__(self,path,count):
self.path=path
self.count=count
def get_file_content(self):
print(self.path)
f=open(self.path,"rb")
content=f.read()
f.close()
return content
class ImageLoade(loader):
def get_picture(self,content,index):
start=index*28*28+16
picture=[]
for i in range(28):
picture.append([])
for j in range(28):
byte1=content[start+i*28+j]
picture[i].append(byte1)#28*28的一幅图片
return picture
def get_one_sample(self,picture):
sample=[]
for i in range(28):
for j in range(28):
sample.append(picture[i][j])
return sample#转换成784行向量
def load(self,oneraw=False):
content=self.get_file_content()#获取文件字节数组
data_set=[]
for index in range(self.count):#count为样本个数
onepic=self.get_picture(content,index)#得到一幅图片,二维数组
if oneraw:
onepic=self.get_one_sample(onepic)
data_set.append(onepic)
return data_set
class LabelLoad(loader):#标签数据加载器
def load(self):
content=self.get_file_content()#得到文件字节数组
labels=[]
for index in range(self.count):
onelabel=content[index+8]#文件头八个字节
onelabelvec=self.norm(onelabel)#编码????
labels.append(onelabelvec)
return labels#返回一个数组[[],[],[].....]
def norm(self,label):
labelvec=[]
label_value=label#字节转int类型??
for i in range(10):#one-hot编码
if i==label_value:
labelvec.append(1)
else:
labelvec.append(0)
return labelvec
def get_train_data_set(num,oneraw=False):#获得训练数据集
image_loader=ImageLoade("train-images.idx3-ubyte",num)
label_loader=LabelLoad("t10k-labels.idx1-ubyte",num)
return image_loader.load(oneraw),label_loader.load()#返回[[],[],[]......]#28个
def get_test_data_set(num,oneraw=False):
image_loader=ImageLoade("t10k-images.idx3-ubyte",num)
label_loader=LabelLoad("t10k-labels.idx1-ubyte",num)
return image_loader.load(oneraw),label_loader.load()
def printimg(onepic):
onepic=onepic.reshape(28,28)
for i in range(28):
for j in range(28):
if onepic[i,j]==0:
print(" ",end="")
else:
print("* ",end="")
print("")
创建deep_learn.py
功能:创建模型,训练数据,生成modul库
import mnist
import numpy as np
from keras.models import Sequential#顺序模型
from keras.layers import Dense,Dropout,Activation,Flatten
#dense fc(全连接层),Activation激活层
from keras.layers import Conv2D,MaxPooling2D,AveragePooling2D
nb_class=10
kernel_size=(5,5)#卷积核大小
pool_size=(2,2)
img_rows,img_cols=28,28
batch_size=128#批处理样本数量
epochs=600 #迭代次数
input_shape=(img_rows,img_cols,1)#图片维度
#X_train[[],[],[],[].......]
X_train,Y_train=mnist.get_train_data_set(1000,False)#加载训练样本数据集
X_test,Y_test=mnist.get_test_data_set(1000,False)#加载测试样本数据集
X_train=np.array(X_train).astype(bool).astype(float)/255#?????????????????????
print("X_train_F:",X_train)
X_train=X_train[:,:,:,np.newaxis]#添加新维度
print("X_train_B:",X_train)
Y_train=np.array(Y_train)
X_test=np.array(X_test).astype(bool).astype(float)/255#?????????????????????
X_test=X_test[:,:,:,np.newaxis]#添加新维度转换成[[[[0.],[0.],[],......]]]
Y_test=np.array(Y_test)
print("样本数据集维度:",X_train.shape,Y_train.shape)#由外到内,包含元素
print("测试数据集维度:",X_test.shape,Y_test.shape)
#
# 构建模型
#
model=Sequential()#顺序模型
model.add(Conv2D(6,kernel_size,input_shape=input_shape,strides=1))#卷积层,步进1
model.add(AveragePooling2D(pool_size=pool_size,strides=2))#池化层
#再次卷积不需要输入图像
model.add(Conv2D(12,kernel_size,strides=1))
model.add(AveragePooling2D(pool_size=pool_size,strides=2))
model.add(Flatten())#一维数据
model.add(Dense(nb_class))#全连接
model.add(Activation("sigmoid"))#激活函数
#编译模型
#loss交叉熵,优化器,评估
model.compile(loss="categorical_crossentropy",optimizer="adadelta",
metrics=["accuracy"])
print("X_test:",X_test.shape)
print("Y_test:",Y_test.shape)
#训练模型
model.fit(X_train,Y_train,batch_size=batch_size,epochs=epochs,verbose=1,
validation_data=(X_test,Y_test))
#评估模型
score=model.evaluate(X_test,Y_test,verbose=0)
print("Test score:",score[0])
print("Test accuracy:",score[1])
#保存模型
model.save("cnn_model.h5")#保存模型,HDF5文件
测试生成的模型
from keras.models import load_model
import numpy as np
import cv2
model=load_model("cnn_model.h5")
image=cv2.imread("test.png")
img=cv2.imread("test.png",0)
img=np.reshape(img,(1,28,28,1)).astype(bool).astype("float32")/255
my_proba=model.predict_proba(img)#输出序列概率
my_predict=model.predict_classes(img)#输出类别
print("图片数字为:")
print(my_proba)
print(my_predict)
cv2.imshow("image",image)#opencv 显示图片
cv2.waitKey(0)