1. 导入库文件
- # import the necessary packages
- from keras.models import Sequential
- from keras.layers.convolutional import Conv2D
- from keras.layers.convolutional import MaxPooling2D
- from keras.layers.core import Activation
- from keras.layers.core import Flatten
- from keras.layers.core import Dense
- from keras import backend as K
- # import the necessary packages
- from keras.preprocessing.image import ImageDataGenerator
- from keras.optimizers import Adam
- from keras.preprocessing.image import img_to_array
- from keras.utils import to_categorical
- from imutils import paths
- import matplotlib.pyplot as plt
- import numpy as np
- import random
- import cv2
- import os
- import sys
- sys.path.append('..')
2. 定义常量
- # initialize the number of epochs to train for, initial learning rate,
- # and batch size
- EPOCHS = 35
- INIT_LR = 1e-3
- BS = 32
- CLASS_NUM = 62
- norm_size = 32
3. 读取数据
- def load_data(path):
- print("[INFO] loading images...")
- data = []
- labels = []
- # grab the image paths and randomly shuffle them
- imagePaths = sorted(list(paths.list_images(path)))
- random.seed(42)
- random.shuffle(imagePaths)
- # loop over the input images
- for imagePath in imagePaths:
- # load the image, pre-process it, and store it in the data list
- image = cv2.imread(imagePath)
- image = cv2.resize(image, (norm_size, norm_size))
- image = img_to_array(image)
- data.append(image)
- # extract the class label from the image path and update the
- # labels list
- label = int(imagePath.split(os.path.sep)[-2])
- labels.append(label)
- # scale the raw pixel intensities to the range [0, 1]
- data = np.array(data, dtype="float") / 255.0
- labels = np.array(labels)
- # convert the labels from integers to vectors
- labels = to_categorical(labels, num_classes=CLASS_NUM)
- return data,labels
4. 训练并保存模型
- def train(aug,trainX,trainY,testX,testY):
- # initialize the model
- print("[INFO] compiling model...")
- model = build(width=norm_size, height=norm_size, depth=3, classes=CLASS_NUM)
- opt = Adam(lr=INIT_LR, decay=INIT_LR / EPOCHS)
- model.compile(loss="categorical_crossentropy", optimizer=opt,
- metrics=["accuracy"])
- # train the network
- print("[INFO] training network...")
- H = model.fit_generator(aug.flow(trainX, trainY, batch_size=BS),
- validation_data=(testX, testY), steps_per_epoch=len(trainX) // BS,
- epochs=EPOCHS, verbose=1)
- # save the model to disk
- print("[INFO] serializing network...")
- model.save('traffic.h5')
5. 评估训练模型
- # plot the training loss and accuracy
- plt.style.use("ggplot")
- plt.figure()
- N = EPOCHS
- plt.plot(np.arange(0, N), H.history["loss"], label="train_loss")
- plt.plot(np.arange(0, N), H.history["val_loss"], label="val_loss")
- plt.plot(np.arange(0, N), H.history["acc"], label="train_acc")
- plt.plot(np.arange(0, N), H.history["val_acc"], label="val_acc")
- plt.title("Training Loss and Accuracy on traffic-sign classifier")
- plt.xlabel("Epoch #")
- plt.ylabel("Loss/Accuracy")
- plt.legend(loc="lower left")
- plt.show()
6. 训练模型主函数
- #python train.py --dataset_train ../../traffic-sign/train --dataset_test ../../traffic-sign/test --model traffic_sign.model
- if __name__ == '__main__':
- train_file_path = './data/train'
- test_file_path = './data/test'
- trainX,trainY = load_data(train_file_path)
- testX,testY = load_data(test_file_path)
- # construct the image generator for data augmentation
- aug = ImageDataGenerator(
- rotation_range=15,
- width_shift_range=0.1,
- height_shift_range=0.1,
- horizontal_flip=True,
- vertical_flip=False
- )
- train(aug,trainX,trainY,testX,testY)
7. 模型转换,由keras的h5转换为tensorflow的pb模型
- import keras
- import tensorflow as tf
- import os
- #这个函数参考自网上
- def freeze_session(session, keep_var_names=None, output_names=None, clear_devices=True):
- """
- Freezes the state of a session into a pruned computation graph.
- Creates a new computation graph where variable nodes are replaced by
- constants taking their current value in the session. The new graph will be
- pruned so subgraphs that are not necessary to compute the requested
- outputs are removed.
- @param session The TensorFlow session to be frozen.
- @param keep_var_names A list of variable names that should not be frozen,
- or None to freeze all the variables in the graph.
- @param output_names Names of the relevant graph outputs.
- @param clear_devices Remove the device directives from the graph for better portability.
- @return The frozen graph definition.
- """
- graph = session.graph
- with graph.as_default():
- freeze_var_names = list(set(v.op.name for v in tf.global_variables()).difference(keep_var_names or []))
- output_names = output_names or []
- output_names += [v.op.name for v in tf.global_variables()]
- input_graph_def = graph.as_graph_def()
- if clear_devices:
- for node in input_graph_def.node:
- node.device = ''
- frozen_graph = tf.graph_util.convert_variables_to_constants(
- session, input_graph_def, output_names, freeze_var_names)
- return frozen_graph
- if __name__ == '__main__':
- input_path = './'
- #keras训练保存的h5文件
- input_file = 'traffic.h5'
- weight_file_path = os.path.join(input_path, input_file)
- output_graph_name = weight_file_path[:-3] + '.pb'
- # 加载模型
- keras.backend.set_learning_phase(0)
- h5_model = keras.models.load_model(weight_file_path)
- frozen_graph = freeze_session(keras.backend.get_session(), output_names=[out.op.name for out in h5_model.outputs])
- tf.train.write_graph(frozen_graph, input_path, output_graph_name, as_text=False)
- print('Finished')
- # import cv2
- # model = cv2.dnn.readNetFromTensorflow("traffic.pb")
- # print('Load')
8. 预测模型,通过keras的loadModel实现
- # -*- coding: utf-8 -*-
- """
- Created on Mon Aug 24 10:08:04 2020
- @author: Yonghong Li
- """
- # import the necessary packages
- from keras.preprocessing.image import img_to_array
- from keras.models import load_model
- import numpy as np
- import argparse
- import imutils
- import cv2
- norm_size = 32
- def predict():
- # load the trained convolutional neural network
- print("[INFO] loading network...")
- model = load_model('traffic.h5')
- #load the image
- image = cv2.imread('E:/python learn/TrafficClassify/data/test/00058/00413_00000.png')
- orig = image.copy()
- # pre-process the image for classification
- image = cv2.resize(image, (norm_size, norm_size))
- image = image.astype("float") / 255.0
- image = img_to_array(image)
- image = np.expand_dims(image, axis=0)
- # classify the input image
- result = model.predict(image)[0]
- print (result)
- proba = np.max(result)
- print(proba)
- label = str(np.where(result==proba)[0])
- label = "{}: {:.2f}%".format(label, proba * 100)
- print(label)
- if True:
- # draw the label on the image
- output = imutils.resize(orig, width=400)
- cv2.putText(output, label, (10, 25),cv2.FONT_HERSHEY_SIMPLEX,
- 0.7, (0, 255, 0), 2)
- # show the output image
- cv2.imshow("Output", output)
- cv2.waitKey(0)
- #python predict.py --model traffic_sign.model -i ../2.png -s
- if __name__ == '__main__':
- predict()
9. 预测模型,通过OpenCV dnn 加载
- # -*- coding: utf-8 -*-
- """
- Created on Sat Aug 29 15:57:15 2020
- @author: Yonghong Li
- """
- import cv2
- import imutils
- import numpy as np
- norm_size = 32
- def predict():
- # load the trained convolutional neural network
- print("[INFO] loading network...")
- net = cv2.dnn.readNetFromTensorflow('traffic.pb')
- #load the image
- image = cv2.imread('E:/python learn/TrafficClassify/data/test/00058/00413_00000.png')
- orig = image.copy()
- img_tensor = cv2.dnn.blobFromImage(image, 1 / 255.0, (norm_size, norm_size), swapRB=True, crop=False)
- net.setInput(img_tensor)
- #ln = net.getUnconnectedOutLayersNames()
- result = net.forward()
- print(result)
- # proba = np.max(result)
- # print(proba)
- # label = str(np.where(result==proba)[2])
- #
- # print(label)
- #
- # label = "{}: {:.2f}%".format(label, proba * 100)
- # print(label)
- ## # classify the input image
- #
- min_val,max_val,min_indx,max_indx=cv2.minMaxLoc(result)
- print(min_val,max_val,min_indx,max_indx)
- label = "{}: {:.2f}%".format(max_indx, max_val * 100)
- ##
- if True:
- # draw the label on the image
- output = imutils.resize(orig, width=400)
- cv2.putText(output, label, (10, 25),cv2.FONT_HERSHEY_SIMPLEX,
- 0.7, (0, 255, 0), 2)
- # # show the output image
- cv2.imshow("Output", output)
- cv2.waitKey(0)
- if __name__ == '__main__':
- predict()
10. 通过OpenCV dnn加载深度学习模块,在传统的C++代码上实现了深度学习,能够根据输入的图像实现图像分类,完整代码 https://download.csdn.net/download/mr_liyonghong/12785394
联系客服