虽然模型有点老了,也没什么太大的实际用处,不过对于cnn的鼻祖,了解一下挺不错的,当时的思想和方法还是对现在有很大启发的,毕竟我是小白。
提示:以下是本篇文章正文内容,下面案例可供参考
我把注释都写上了,希望能帮助到你们,有些我也是云里雾里的,争取最近搞清楚,有什么问题及时探讨下啦。
代码如下(示例):
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数组,而标签只是一组数字,从0到9,图像和标签之间存在一一对应关系
#输出训练集的特征的大小
#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()
#第一层 6个5*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))
#第二层 16个5*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.5到1平均分割 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、卷积层的参数较少,这也是由卷积层的主要特性即局部连接和共享权重所决定。