Tensorflow2-Lenet-5实现Cifar10分类

引言

  • 为了掌握tensorflow一些函数的基本操作,写写博客记录下。
  • 在学习时为了方便查找一些函数,这里放了keras中文文档方便查找,也有pdf版本:百度网盘链接:https://pan.baidu.com/s/1gf_vlnyPqeCRsoywzFrHrQ
    提取码:jnwq
  • 这也是自己的第一篇博客,希望能坚持写下去,3年后能有一个好的收获。
    在这里插入图片描述

模型

在keras中有创建模型时有两种模型:

Sequential

顺序模型是多个网络层的线性堆叠。
可以通过将网络层实例的列表传递给 Sequential 的构造器,来创建一个 Sequential 模型:

from keras.models import Sequential
from keras.layers import Dense, Activation

model = Sequential([
    Dense(32, input_shape=(784,)),
    Activation('relu'),
    Dense(10),
    Activation('softmax'),
])

也可以简单地使用 model.add() 方法将各层添加到模型中:

model = Sequential()
model.add(Dense(32, input_dim=784))
model.add(Activation('relu'))

Model

通用模型可以设计比较复杂的网络

from tensorflow.keras import Model,Sequential,optimizers
from tensorflow.keras.layers import Activation,Dense,Conv2D,MaxPool2D,Input,Dropout,Flatten
inputs=Input([32,32,3])
x=Conv2D(6,kernel_size=(5,5),activation='relu')(inputs)
x=Dropout(0.5)(x)
x=MaxPool2D(pool_size=(2,2))(x)
x=Dense(84)(x)
out=Dense(10,activation='softmax')(x)
#实例化导入输入输出
model=Model(inputs,out)

基本函数

本次实验使用Model模型,所以在函数编写上会和Sequential不太一样。

1.全连接层Dense

  • Dense是全连接层,一般放在网络结构的最后几层。
  • Dense层一般需要设定卷积核个数激活函数。(有时候可以省略激活函数)
x=Dense(64,activation='relu')(x)

2.卷积层Conv2D

  • Conv2D需要设定卷积核个数卷积核大小激活函数步长填充方式
x=Conv2D(64,kernel_size=(5,5),activation='relu',strides=2,padding='same')

3.池化层Maxpool2D

  • Maxpool2D需要设定卷积核大小激活函数
  • 池化层不需要设定卷积核个数,因为池化层的作用就是让特征图尺寸变小,不改变通道数。

搭建网络

1.导入数据集

#导入数据
data=tf.keras.datasets.cifar10
(x_train,y_train),(x_test,y_test)=data.load_data()
#对训练标签和测试标签进行one-hot编码
y_train=tf.keras.utils.to_categorical(y_train, num_classes=10)
y_test=tf.keras.utils.to_categorical(y_test, num_classes=10)
#对样本进行归一化,减小计算量
x_train=x_train/255.0
x_test=x_test/255.0

注:这里要对训练标签和测试标签进行升维,因为cifar10是个10分类的问题,我们要将标签数字[0-9]转化为one-hot向量。
做个展示

data=tf.keras.datasets.cifar10
(x_train,y_train),(x_test,y_test)=data.load_data()
print("y_train",y_train.shape)
y_train=tf.keras.utils.to_categorical(y_train, num_classes=10)
y_test=tf.keras.utils.to_categorical(y_test, num_classes=10)
print("y_train",y_train.shape)
#result
y_train (50000, 1)
y_train (50000, 10)

2.创建模型

#建立模型
inputs=Input([32,32,3])
x=Conv2D(6,kernel_size=(5,5),activation='relu')(inputs)
x=Dropout(0.5)(x)
x=MaxPool2D(pool_size=(2,2))(x)
x=Conv2D(16,kernel_size=(5,5),activation='relu')(x)
x=Dropout(0.5)(x)
x=MaxPool2D(pool_size=(2,2))(x)
x=Conv2D(120,kernel_size=(5,5),activation='relu')(x)
x=Flatten()(x)
x=Dense(120)(x)
x=Dense(84)(x)
out=Dense(10,activation='softmax')(x)
model=Model(inputs,out)

3.model.compile

编译需要设定优化器损失函数度量环节

model.compile(loss='categorical_crossentropy', optimizer='adam',metrics=['sparse_categorical_accuracy'])

如果想改变优化器的参数比如学习率等,可以自己设定优化器,不用按照系统默认参数,如下:

adam=optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=None, decay=0.0, amsgrad=False)
model.compile(loss='categorical_crossentropy',
              optimizer=adam,
              metrics=['accuracy'])

4.model.fit

  • 训练过程一般需要设定训练集输入特征训练集输入标签batch_size个数epoch数训练集和测试集的比例/多少epoch测试一次
model.fit(x_train, y_train, batch_size=16,epochs=5,validation_split=0.25)

5.model.summary

  • 打印信息,如训练参数
model.summary()

代码

"""
Author: Wang Qiang
Date:2020/12/11
"""
import tensorflow as tf
from tensorflow.keras import Model,Sequential,optimizers
from tensorflow.keras.layers import Activation,Dense,Conv2D,MaxPool2D,Input,Dropout,Flatten
import os
import numpy as np
import matplotlib.pyplot as plt
np.set_printoptions(threshold=np.inf)
#导入数据
data=tf.keras.datasets.cifar10
(x_train,y_train),(x_test,y_test)=data.load_data()
#对训练标签和测试标签进行one-hot编码
y_train=tf.keras.utils.to_categorical(y_train, num_classes=10)
y_test=tf.keras.utils.to_categorical(y_test, num_classes=10)
#对样本进行归一化,减小计算量
x_train=x_train/255.0
x_test=x_test/255.0
#建立模型
inputs=Input([32,32,3])
x=Conv2D(6,kernel_size=(5,5),activation='relu')(inputs)
x=Dropout(0.5)(x)
x=MaxPool2D(pool_size=(2,2))(x)
x=Conv2D(16,kernel_size=(5,5),activation='relu')(x)
x=Dropout(0.5)(x)
x=MaxPool2D(pool_size=(2,2))(x)
x=Conv2D(120,kernel_size=(5,5),activation='relu')(x)
x=Flatten()(x)
x=Dense(120)(x)
x=Dense(84)(x)
out=Dense(10,activation='softmax')(x)
model=Model(inputs,out)
#设定优化器
adam=optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=None, decay=0.0, amsgrad=False)
model.compile(loss='categorical_crossentropy',
              optimizer=adam,
              metrics=['accuracy'])
#保存模型
# 先定义出存放模型的路径和文件名,命名为ckpt文件
# 生成ckpt文件时,会同步生成索引表,所以通过判断是否已经有索引表,就知道是不是已经保存过模型参数
save_path = "./checkpoint/lenet5.ckpt"
if os.path.exists(save_path + '.index'):
    print('-------------load the model-----------------')
    # 如果有索引表,就说明保存过模型,则可以调用load_weights读取模型参数
    model.load_weights(save_path)

cp_callback=tf.keras.callbacks.ModelCheckpoint(filepath=save_path,monitor='val_loss',verbose=0,
                                                       save_best_only=True,save_weights_only=True)

history = model.fit(x_train, y_train, validation_split=0.25, epochs=5, batch_size=16,
                   callbacks=[cp_callback])
model.summary()
#print(model.trainable_variables)
file = open('./weights.txt', 'w')
for v in model.trainable_variables:
    file.write(str(v.name) + '\n')
    file.write(str(v.shape) + '\n')
    file.write(str(v.numpy()) + '\n')
file.close()

# 绘制训练 & 验证的准确率值
plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])
plt.title('Model accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epoch')
plt.legend(['Train', 'Test'], loc='upper left')
plt.show()

# 绘制训练 & 验证的损失值
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('Model loss')
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.legend(['Train', 'Test'], loc='upper left')
plt.show()

实验结果

  • 简单跑了几个epoch,代码内部设置了保存模型参数,所以每次训练都可以实现加载最优的模型参数。
Epoch 1/5
2344/2344 [==============================] - 17s 7ms/step - loss: 1.1881 - accuracy: 0.5783 - val_loss: 1.4333 - val_accuracy: 0.4962
Epoch 2/5
2344/2344 [==============================] - 16s 7ms/step - loss: 1.1655 - accuracy: 0.5863 - val_loss: 1.4670 - val_accuracy: 0.4942
Epoch 3/5
2344/2344 [==============================] - 15s 6ms/step - loss: 1.1525 - accuracy: 0.5939 - val_loss: 1.4527 - val_accuracy: 0.4910
Epoch 4/5
2344/2344 [==============================] - 15s 7ms/step - loss: 1.1376 - accuracy: 0.5993 - val_loss: 1.5371 - val_accuracy: 0.4561
Epoch 5/5
2344/2344 [==============================] - 15s 6ms/step - loss: 1.1290 - accuracy: 0.5981 - val_loss: 1.4024 - val_accuracy: 0.5110
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值