用tensorflow搭建的lenet网络➕源代码

LeNet:《Gradient-Based Learning Applied to Document Recognition》 CNN的开山之作,也是手写体识别经典论文。

  • 用tensorflow搭建的lenet
  • 一、用tensorflow搭建的(可以学习一下pytorch的 更简单)
  • lenet5的结构图:
  • 二、CNN主要三大特色
    • 1.引入库
    • 读入数据集 并分好训练跟预测
  • 总结


用tensorflow搭建的lenet

虽然模型有点老了,也没什么太大的实际用处,不过对于cnn的鼻祖,了解一下挺不错的,当时的思想和方法还是对现在有很大启发的,毕竟我是小白。


提示:以下是本篇文章正文内容,下面案例可供参考

一、用tensorflow搭建的(可以学习一下pytorch的 更简单)

我把注释都写上了,希望能帮助到你们,有些我也是云里雾里的,争取最近搞清楚,有什么问题及时探讨下啦。

lenet5的结构图:

用tensorflow搭建的lenet网络➕源代码_第1张图片

二、CNN主要三大特色

  1. 局部感知
    局部感知就是我们说的感受野,实际上就是卷积核和图像卷积的时候,每次卷积核所覆盖的像素只是一小部分,是局部特征,所以说是局部感知。CNN是一个从局部到整体的过程(局部到整体的实现是在全连通层),而传统的神经网络是整体的过程。
  2. 权重共享
    权值共享:不同的图像或者同一张图像共用一个卷积核,减少重复的卷积核。同一张图像当中可能会出现相同的特征,共享卷积核能够进一步减少权值参数。
  3. 多卷积核
    一种卷积核代表的是一种特征,为获得更多不同的特征集合,卷积层会有多个卷积核,生成不同的特征,每一个图片代表不同的特征。

1.引入库

代码如下(示例):

import tensorflow as tf
from tensorflow import keras
from keras import models,layers
import numpy as np
import matplotlib.pyplot as plt

读入数据集 并分好训练跟预测

代码如下(示例):

#读入数据集 并分好训练跟预测
fashion_mnist = tf.keras.datasets.fashion_mnist
(train_images,train_labels),(test_images,test_labels) = fashion_mnist.load_data()
#图像被编码为Numpy数组,而标签只是一组数字,从09,图像和标签之间存在一一对应关系

#输出训练集的特征的大小
#reshape:给数据增加一个维度,使数据和网络结构匹配,train_images的(60000,28,28,1)
Train_images = tf.reshape(train_images,(train_images.shape[0],train_images.shape[1],train_images.shape[2],1))
print(Train_images.shape)
Test_images = tf.reshape(test_images,(test_images.shape[0],test_images.shape[1],test_images.shape[2],1))
print(Test_images.shape)


#构建网络结构 单独使用sequential时候必须from keras import models layers 否则跟tensorflow.keras 的冲突
lenet = models.Sequential()
#第一层 65*5的卷积核,输入图片的大小,sigmoid 激活 使用最大池化,2*2的池化核,步长为2, valid还是same?
lenet.add(layers.Conv2D(filters=6,kernel_size=5,activation='sigmoid',input_shape=(28,28,1),padding='same'))
lenet.add(layers.MaxPool2D(pool_size=2,strides=2))
#第二层 165*5的卷积核
lenet.add(layers.Conv2D(filters=16,kernel_size=5,activation='sigmoid',padding='same'))
lenet.add(layers.MaxPool2D(pool_size=2,strides=2))

#第三层 全联接层
#全联接层之前的展平处理,将二维数组展成一维向量,方便操作
lenet.add(layers.Flatten())
#使用三层全连接层
lenet.add(layers.Dense(120,activation='sigmoid'))
lenet.add(layers.Dense(80,activation='sigmoid'))
lenet.add(layers.Dense(10,activation='sigmoid'))


#损失函数和训练算法采用交叉熵损失函数(cross entropy)和小批量随机梯度下降(SGD) 使用adam比sgd高
# ****试一下AdaGrad算法,RMSProp算法,Adam算法以及AdaDelta算法
optimizer = tf.keras.optimizers.SGD(learning_rate=0.9,momentum=0.001,nesterov=True)

#编译模型 选择优化器,损失函数,显示训练精度
lenet.compile(optimizer='adam',
           loss='sparse_categorical_crossentropy',
           metrics=['accuracy'])

#训练模型,训练次数为5次
#1、使用validation_split用来指定训练集的一定比例数据为验证集;2、可以使用代码来分割
history = lenet.fit(Train_images,train_labels,epochs=4,validation_split=0.1,verbose=1)

#测试训练好的模型,返回精确度和损失,verbose=1 在控制台显示进度条显示精度;0不显示;2每个epoch显示一次,无进度条
test_loss, test_acc = lenet.evaluate(Test_images, test_labels,verbose=1)
print('\nTest accuracy:', test_acc)
print('Test loss:',test_loss)



#评估模型
plt.plot(history.history['accuracy'],label = 'accuracy',color = 'red')
plt.plot(history.history['val_accuracy'],label = 'val_accuracy')
plt.xlabel('epoch')
plt.ylabel('accuracy')
plt.ylim([0.4,1]) #y轴从0.51平均分割 1次迭代不显 5次acc:0.86 val_acc:0.85
plt.xlim([0,4])
plt.legend(loc = 'lower right')   #label 放在右下方
plt.show()




##################################测试分割线#####################################
#对测试集图片进行预测
#输出第一张图片的预测结果
Predictions=lenet.predict(Test_images)
print('\nthe predicted p is\n:',Predictions[0])
#预测一张图片的概率分类 看属于第几类(数字显示)
print("\nThe first picture's prediction is:",np.argmax(Predictions[0]))
print("the first picture is:",test_labels[0])

#需要分类对类别名称字典
class_names=['T-shirt/top','Trouser','Pullover','Dress','Coat',
             'Sandal','Shirt','Sneaker','Bag','Ankle boot']
#对测试图像对前25个样本进行预测
#正确标签为绿色,不正确为红色
plt.figure(figsize=(15, 15))
for i in range(25):
    plt.subplot(5, 5, i+1)
    plt.xticks([])
    plt.yticks([])
    plt.imshow(test_images[i], cmap=plt.cm.binary) #colormap用二值色图来填充 可以用其他例如cool,hot等
    predicted_label = np.argmax(Predictions[i])    #看25个分类标签
#如果分类标签和真实标签一样,则输出绿色的color_name(color_name)
    if predicted_label == test_labels[i]:
         color = 'green'
    else:
         color = 'red'
#前面是预测分类,括号内是实际分类
    plt.xlabel("{} ({})".format(class_names[predicted_label],class_names[test_labels[i]]),color=color)
plt.show()


# print(test_labels.shape) #一万个测试标签
# print(test_labels[i])    #标签对数字分类

代码都写上了,自己捣鼓了半天,能够跑出来,准确率在70左右吧,我迭代了4次,多了可就过拟合了,如果有更好的方法和建议请指正,一起加油呀!


总结

1、LeNet5是一种用于手写体字符识别的非常高效的卷积神经网络(可以尝试下用在其他数据集上)说不定就有亮点了呢
2、卷积神经网络能够很好的利用图像的结构信息。卷积神经网络开始
3、卷积层的参数较少,这也是由卷积层的主要特性即局部连接和共享权重所决定。

你可能感兴趣的:(机器学习,卷积,算法,神经网络,机器学习,人工智能)