学习并参考了这个链接。
提前准备:anaconda3(Jupyter);tensorflow;cv2;数据集(官网可以下,点开我给的超链接)
注意:tensorflow要求python是3.5/3.6版本的,已经配置了python3.7/3.8的朋友可以重新下载一个python 3.6,具体操作网上有很多教程可以参考~
基本思路:
- 读入图片 & 数据预处理
使用cv2。每个文件夹的名字就是其标签,但是名字不可以当作lable,所以建立了name_dic 字典转换为数字。由于每次加载数据很消耗时间,所以将四个文件(训练、测试集的特征和标签用numpy进行了保存)。另外由于图片数据过少,用到了图像增强。 - 搭建LeNet网络(CNN的一种)
- 训练模型
- 评价模型
话不多说,直接上代码,代码解释的很清楚了——
【对了,里面数据集的地址记得自己改。】
# 导入必要的包
from keras.models import Sequential
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import MaxPooling2D
from keras.layers.core import Dense,Dropout,Activation,Flatten
from keras import backend as K
from keras.preprocessing.image import ImageDataGenerator
from keras.optimizers import Adam
from sklearn.model_selection import train_test_split
from keras.preprocessing.image import img_to_array
from keras.utils import to_categorical # 用于one-hot编码
import matplotlib.pyplot as plt
import numpy as np
import cv2
import os
import pandas as pd
# 套用LeNet网络 (CNN,卷积神经网络)
class LeNet:
def build(width, height, depth, classes):
'''参数分别为:长 宽 高 分类'''
# 初始化模型
model = Sequential() # 建立线性堆叠模型
inputShape = (height, width, depth)
# if we are using "channels last", update the input shape
if K.image_data_format() == "channels_first": #for tensorflow
inputShape = (depth, height, width)
# first set of CONV => RELU => POOL layers
# 卷积1 过滤器大小为 5 * 5,会产生20个图像,卷积不会改变图像大小,起到了滤镜效果,设置ReLU激活函数
model.add(Conv2D(filters=20,kernel_size=(5, 5),padding="same",input_shape=inputShape,activation='relu'))
# 添加激活层
# model.add(Activation("relu"))
# 加入Dropout避免过拟合。
model.add(Dropout(0.25))
# 最大池化1 过滤器大小为 2 * 2,长和宽的步长均为2,不会改变图像的数量(仍旧是20),会改变大小(32*32变成16*16)
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
#second set of CONV => RELU => POOL layers
# 卷积2 过滤器大小为 5 * 5,会产生50个图像,卷积不会改变图像大小,起到了滤镜效果,设置ReLU激活函数
model.add(Conv2D(filters=50, kernel_size = (5, 5), padding="same",activation='relu'))
# 激活函数
# model.add(Activation("relu"))
# 加入Dropout避免过拟合。
# model.add(Dropout(0.25))
# 最大池化2 过滤器大小为2 * 2,长和宽的步长均为2,不会改变图像的数量(仍旧是50),会改变大小(16*16变成8*8)
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
# first (and only) set of FC => RELU layers
# Flatten层用来将输入“压平”
model.add(Flatten())
# Dense表示全连接层(500个神经元)
model.add(Dense(500))
model.add(Activation("relu"))
# 加入Dropout避免过拟合。
# model.add(Dropout(0.25))
# softmax classifier
# 建立输出层(分类数个神经元),softmax可以将输出预测为每一个图像的概率
model.add(Dense(classes,activation='softmax'))