Python 深度学习--学习笔记(一)
编写mnist手写神经网络
首先导入数据,第一次导入时需要等待下载
from keras.datasets import mnist
(train_images,train_labels),(test_images,test_labels) = mnist.load_data()
train_images:训练需要的图片
test_images:测试需要的图片
train_labels:训练图片对应的标签
test_labels:测试图片对应的标签
现在我们查看下图片是否正确导入
import matplotlib.pyplot as plt
import numpy as np
a = int(np.random.choice(train_images.shape[0],1))
digit = train_images[a]
plt.imshow(digit,cmap=plt.cm.binary)
plt.show()
print(train_labels[a])
cmap=plt.cm.binary:生成黑白灰度图
输出结果:
接着,我们再查看下训练图片及其标签,测试图片及其标签的大小:
print(train_images.shape,train_labels.shape)
print(test_images.shape,test_labels.shape)
输出结果:
(60000, 28, 28) (60000,)
(10000, 28, 28) (10000,)
可知,训练图片有60000张,测试图片有10000张,它们的大小都为28 * 28
然后,我们就可以定义模型了:
from keras import models
from keras import layers
network = models.Sequential() #Sequential:有序的
network.add(layers.Dense(512,activation='relu',input_shape=(28*28,)))
network.add(layers.Dense(10,activation='softmax')) #输出层
我们定义的模型是有序的,在第一行声明
network = models.Sequential() 意味有序层
这里定义了2个网络层。
第一层有512个神经元,激活函数为relu
relu函数的定义是:
x (x>0)
y =
0 (x<=0)
我们需要使用激活函数是数据呈非线性化,机器才能得到 “学习”
我们定义的层为密集层,没有空间结构,输入的单位大小需要为一个一维数组,数量任意。
故需要把原来的图片改为一维(28*28)的形式
第二层为输出层,输出10个结果,即对应10个阿拉伯数字的概率,概率最大的为预测结果。
输出多个(两个以上)的分类结果的概率,我们需要用到的激活函数为softmax。
10个输出概率加起来正好为 1。
接着定义学习模式:
network.compile(loss='categorical_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])
loss(损失函数):这里使用多元交叉熵来衡量损失值的大小
多元交叉熵是多分类问题中经常用到的衡量公式
optimizer(优化器):简单来说就是通过反向传播求得各层梯度,通过调整权重和偏置来使得损失值变小,进而提高精确度。这里用到是 RMSprop优化器
metrics(评价标准):训练时的输出结果,分类问题一般都用acc——accuracy(准确度)
在训练模型前,我们需要对数据处理,转为机器能够学习处理的数据。
对图片进行处理:
train_images = train_images.reshape((60000,28*28))
train_images = train_images.astype('float32') / 255
test_images = test_images.reshape((10000,28*28))
test_images = test_images.astype('float32') / 255
这里,我们定义的网络层为密集连接层,没有空间结构,输入的单位图像为一维数组,需要将每张图片转为一维结构。
同时为方便学习(relu函数在0~1时敏感),我们将图片的每个像素除以 255 已得到像素值为0~1黑白灰的图像。
对标签进行处理:
from keras.utils import to_categorical
#对标签进行分类编码
train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)
将标签转为one-hot标签,与输出层为10个结果的结构对应。
例如,标签为3,经过one-hot处理成[0,0,0,1,0,0,0,0,0,0]
1对应的索引正好为3。
前期准备都完成了,现在开始训练:
network.fit(train_images,train_labels,epochs=5,batch_size=128)
传入处理的图片数据和标签数据,训练5轮(全部数据传输完成一次为一轮),批次数为128(每次传入128个数据,即(128,28*28))
可以看到,每个epoch都会输出loss和acc(metrics定义好的)
最后,用测试集评估,观测是否出现过拟合:
test_loss,test_acc = network.evaluate(test_images,test_labels)
print('test_acc:',test_acc)
输出结果:
测试集的精确度也能达到98%,模型的泛化程度不错