前言
最近课上用到卷积神经网络搭建车牌识别,所以花费了很多精力进行这个学习。lenet是1987的神经网络,相对简单,没有dropout层,所以使用这个新手搭起来比较简单。
主要python文件有两个NeuralNetworkConstruction.py,Detected.py。
NeuralNetworkConstruction.py主要负责数据的预处理,神经网络的搭建。lenet5网络有两个卷积层,两个池化层,一个拉直层和3个全连接层。
开始训练
训练时,使用的是百度AI平台上的训练数据,data文件夹已分类好各种字符,像素为20×20的灰度图像。NeuralNetworkConstruction.py中,读取图片集并写出训练名单的代码,生成了所需的训练集名单和测试集名单。每隔10张,训练集一张图片放入测试集。
需要使用时,将图片数据生成npy,若没有,则使用generateds函数生成。
神经网络的搭建,我是用class搭建法。第一层卷积层为6个5×5的卷积核,激活函数sigmoid。池化层第一层步长为2。第二层卷积层为16个5×5的卷积核,激活函数sigmoid。池化层第二层步长为2。然后进入拉直层,再经历3个全连接层。如果大家的训练图片大小或者类型不同,可深入理解lenet每一层的参数进行修改。由于我车牌识别共用到65个字符的识别,所以最后一层使用了softmax输出。
训练完模型后,将模型断点保存下来,下一次可以从这加载。最后可以针对模型的准确度和loss进行输出
import tensorflow as tf
import os
import numpy as np
from matplotlib import pyplot as plt
from tensorflow.keras.layers import Conv2D, BatchNormalization, Activation, MaxPool2D, Dropout, Flatten, Dense
from tensorflow.keras import Model
from PIL import Image
import cv2
np.set_printoptions(threshold=np.inf)
# ==========================================读取图片集并写出训练名单
data_path = './characterData/data'
character_folders = os.listdir(data_path)
label = 0
LABEL_temp = {
}
if(os.path.exists('train_data.list')): #有则删除,无则生成txt
os.remove('train_data.list')
if(os.path.exists('test_data.list')):
os.remove('test_data.list')
for character_folder in character_folders:
with open('train_data.list', 'a') as f_train:
with open('test_data.list', 'a') as f_test:
if character_folder == '.DS_Store' or character_folder == '.ipynb_checkpoints' or character_folder == 'data23617':
continue
print(character_folder + " " + str(label)) #label是自增的,和在data中的文件夹的先后关系对应
LABEL_temp[str(label)] = character_folder #存储一下标签的对应关系
character_imgs = os.listdir(os.path.join(data_path, character_folder))
for i in range(len(character_imgs)):
if i%10 == 0:
f_test.write(os.path.join(os.path.join(data_path, character_folder), character_imgs[i]) + "@" + str(label) + '\n')
else:
f_train.write(os.path.join(os.path.join(data_path, character_folder), character_imgs[i]) + "@" + str(label) + '\n')
label = label + 1
print('图像列表已生成')
#=============================================加载自制数据集部分
train_path = '' #txt中路径齐全,所以将这个改成空串,方便运行
train_txt = './train_data.list' #写了训练图片对应标签路径的txt
x_train_savepath = './mnist_image_label/mnist_x_train.npy'
y_train_savepath = './mnist_image_label/mnist_y_train.npy'
test_path = ''
test_txt = './test_data.list'
x_test_savepath = './mnist_image_label/mnist_x_test.npy'
y_test_savepath = './mnist_image_label/mnist_y_test.npy'
def generateds(path, txt): #将图片和标签分别读入x,y_,返回
f = open(txt, 'r') # 以只读形式打开txt文件
contents = f.readlines() # 读取文件中所有行
f.close() # 关闭txt文件
x, y_ = [], [] # 建立空列表
for content in contents: # 逐行取出
value = content.split("@") # 以空格分开,图片路径为value[0] , 标签为value[1] , 存入列表
img_path = path + value[0] # 拼出图片路径和文件名
print(img_path) #调试,打印出文件路径
print("value[1]:",value[1]) #调试,打印出标签
img = Image.open(img_path) # 读入图片
img = np.array(img.convert('RGB')) # 图片变为8位宽灰度值的np.array格式
img = cv2.resize