机器学习入门级别项目,话不多说,我看的教程在这里,代码来源也是这里,快附上B站教程:https://www.bilibili.com/video/BV16g4y1z7Qu?from=search&seid=15844105976503693847,可以说讲解很细致了,我就是跟着一句一句敲下来的,我算入门了吗主要是这份代码也还不是很难,在理解了之后。
1. 全连接网络实现,采用Adam优化器精度可达96.61%
# 可用来消除警告
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
from keras.utils import to_categorical
# 导入keras模型、层和正则器
from keras import models, layers, regularizers
# 导入keras梯度下降优化器,选择均方和传播RMSprop
from keras.optimizers import RMSprop, Adam
# 在很多深度学习框架和入门教程里面已经将mnist下载和读入统一提供给api接口
from keras.datasets import mnist
import matplotlib.pyplot as plt
# 加载数据集
# 第二次不会下载,直接将本地数据读入为四个变量
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
# 这是注释掉因为目前只是用来查看信息
# 60000张28*28大小的训练集,10000张28*28的测试集
# print(train_images.shape, test_images.shape)
# # 打印第一张图像的像素信息和对应的标签
# print(train_images[0])
# print(train_labels[0])
# # 调用python的画图软件
# plt.imshow(train_images[0])
# plt.show()
# 数据处理:每行叠在一起,将矩阵处理成28*28大小的一维向量
# 数据类型设置为float便于计算梯度和权值,原来是int值
train_images = train_images.reshape((60000, 28*28)).astype('float')
test_images = test_images.reshape((10000, 28*28)).astype('float')
# 将数据处理成onehot编码
# 将类别向量转换为二进制(只有0和1)的矩阵类型表示,1 [0,1,0,0,0,0,0,0,0,0]
train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)
# print(train_labels[0])
# 建立神经网络模型
# Sequential序列模型,将网络串起来
network = models.Sequential()
# Dense建立全连接层15个神经元,创建隐藏层,默认relu激活函数,输入一维数据大小为28*28
# 改进:15改为128,加入正则化减少过拟合
network.add(layers.Dense(units=128, activation='relu', input_shape=(28*28, ), kernel_regularizer=regularizers.l1(0.0001)))
# 使用dropout也是为了减少过拟合,杀死部分神经元
network.add(layers.Dropout(0.01))
# 改进:增加一个隐藏层
network.add(layers.Dense(units=32, activation='relu', kernel_regularizer=regularizers.l1(0.0001)))
# 输出层10个神经元,多分类问题常用两种激活函数,sigmoid和softmax,这里采用softmax是希望得到属于0-9的概率
network.add(layers.Dropout(0.01))
network.add(layers.Dense(units=10, activation='softmax'))
# 神经网络训练
# 指定梯度下降优化器、学习率、损失函数
# RMSprop训练好低,Adam可以直接到96的学习率
network.compile(optimizer=Adam(lr = 0.001), loss='categorical_crossentropy', metrics=['accuracy'])
# 指定epochs训练多少个会和,batch_size表示每次训练给多大的数据,verbose = 2 为每个epoch输出一行记录
network.fit(train_images, train_labels, epochs=20, batch_size=128, verbose=2)
# 查看网络的情况(注意每个神经元有一个偏置)
# print(network.summary())
# 测试集测试训练模型的性能
# 取测试集前五张图片
y_pre = network.predict(test_images[:5])
# 比较是否一一对应,是否预测正确
print(y_pre, test_labels[:5])
# 调用评估函数模型在测试集上的表现
test_loss, test_accuracy = network.evaluate(test_images, test_labels)
print("test_loss:", test_loss, " test_accuracy:", test_accuracy)
2. 卷积神经网络LeNet,采用RMSprop优化器,准确率可达99.5%
from keras.utils import to_categorical
from keras import models, layers
from keras.optimizers import RMSprop
from keras.datasets import mnist
# 加载数据集
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
# 搭建LeNet网络
# 三个卷积层,两个平均池化,一个平坦,两个全连接层
def LeNet():
network = models.Sequential()
network.add(layers.Conv2D(filters=6, kernel_size=(3, 3), activation='relu', input_shape=(28, 28, 1)))
network.add(layers.AveragePooling2D((2, 2)))
network.add(layers.Conv2D(filters=16, kernel_size=(3, 3), activation='relu'))
network.add(layers.AveragePooling2D((2, 2)))
network.add(layers.Conv2D(filters=120, kernel_size=(3, 3), activation='relu'))
network.add(layers.Flatten())
network.add(layers.Dense(84, activation='relu'))
network.add(layers.Dense(10, activation='softmax'))
return network
network = LeNet()
network.compile(optimizer=RMSprop(lr=0.001), loss='categorical_crossentropy', metrics=['accuracy'])
# 训练之前,需要对数据进行预处理,将其变换为网络要求的形状,并缩放到所有值都在[0,1]之间
train_images = train_images.reshape((60000, 28, 28, 1)).astype('float') / 255
test_images = test_images.reshape((10000, 28, 28, 1)).astype('float') / 255
train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)
# 训练网络,用fit函数, epochs表示训练多少个回合, batch_size表示每次训练给多大的数据
network.fit(train_images, train_labels, epochs=10, batch_size=128, verbose=2)
test_loss, test_accuracy = network.evaluate(test_images, test_labels)
print("test_loss:", test_loss, " test_accuracy:", test_accuracy)
PS:中间出现过一个警告,前面加入这段代码可消除警告,意思可能是我的tensorflow太low了,加入这段代码就没有警告了,后来我注意到视频里他运行的时候也有警告,所以其实不去掉问题也不大,看个人咯。
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'