一、代码演示
imagetoarraypreprocessor.py:
#加载图像--->重新定义尺寸--->通道排序--->输出图像
from keras.preprocessing.image import img_to_array
class ImageToArrayPreprocessor:
def __init__(self,dataFormat=None):
"""Keras.json配置的图像数据格式约定
Keras.json
{
"floatx": "float32",
"epsilon": 1e-07,
"backend": "tensorflow",
"image_data_format": "channels_last"
}
image_data_format: 字符串,“channels_last” 或者 “channels_first”。它指定了 Keras 将遵循的数据格式约定。
对于 2D 数据 (例如图像),“channels_last” 假定为 (rows, cols, channels),而 “channels_first” 假定为 (channels, rows, cols)。
backend: 字符串, “tensorflow”, “theano”, 或 “cntk”。
"""
#根据Keras配置文件选择要使用的图像维排序
self.dataFormat = dataFormat
def preprocess(self, image):
#图像以要求的维度排序方式转为数组并返回
return img_to_array(image, data_format=self.dataFormat)
SimplePreprocessor.py:
#encoding:utf-8
import cv2
class SimplePreprocessor:
def __init__(self,width,height,inter = cv2.INTER_AREA):
self.width = width
self.height = height
self.inter = inter
def preprocess(self,image):
return cv2.resize(image,(self.width,self.height),interpolation=self.inter)
SimpleDatasetLoader.py:
#encodig:utf-8
import numpy as np
import cv2
import os
class SimpleDatasetLoader:
def __init__(self,preprocessors = None):
self.preprocessors = preprocessors
if self.preprocessors is None:
self.preprocessors = []
def load(self,imagePaths,verbose = -1):
data = []
labels = []
for (i,imagePath) in enumerate(imagePaths):
image = cv2.imread(imagePath)
label = imagePath.split(os.path.sep)[-2]
if self.preprocessors is not None:
for preprocessor in self.preprocessors:
image = preprocessor.preprocess(image)
data.append(image)
labels.append(label)
if verbose > 0 and i >0 and (i+1) % verbose == 0:
print("[INFO] processed {0}/{1}".format(i+1,len(imagePaths)))
return (np.array(data),np.array(labels))
shallownet.py:
"""简单的浅层网络
结构:INPUT => CONV => RELU => FC
"""
from keras.models import Sequential
from keras.layers.convolutional import Conv2D #2维卷积
from keras.layers.core import Activation #激活函数
from keras.layers.core import Flatten #将多维数组“拉”成一维数组
from keras.layers.core import Dense #全连接层
from keras import backend as K #后端处理方式 “tensorflow”或“theano”
class ShallowNet:
#经过@staticmethod修饰的方法,不需要self参数,其使用方法和直接调用函数一样
@staticmethod
def build(width,height,depth,classes):
"""
width: 输入图像的宽度(即,矩阵中的列数)
height:输入图像的高度(即,矩阵中的行数)
depth:输入图像中通道数
classes:预测的类的总数:如Animals(狗、猫、熊猫)数据集,classes=3
"""
#21行-25行 通用做法
model = Sequential()
inputShape = (height,width,depth)
if K.image_data_format()=='channels_first':
inputShape = (depth,height,width)
#搭建网络
# CONV => RELU same:卷积时补零 使输入输出形状不变
model.add(Conv2D(32,(3,3),padding='same',input_shape=inputShape))
model.add(Activation('relu'))
# => FC
model.add(Flatten())
model.add(Dense(classes))
model.add(Activation("softmax"))
return model
shallownet_animals.py:
"""
from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
import imagetoarraypreprocessor
import SimplePreprocessor
import SimpleDatasetLoader
import shallownet
from keras.optimizers import SGD
from imutils import paths
import matplotlib.pyplot as plt
import numpy as np
import argparse
ap = argparse.ArgumentParser()
ap.add_argument('-d','--dataset',required=True,help='path to input dataset')
args = vars(ap.parse_args())
print("[INFO] loading image...")
imagePaths = list(paths.list_images(args['dataset']))
sp = SimplePreprocessor.SimplePreprocessor(32,32) #图像调整为32*32
iap = imagetoarraypreprocessor.ImageToArrayPreprocessor()#通道排序
#加载器:
"""首先,一个给定的输入图像将被调整为32×32像素。
然后,调整大小的图像将根据我们的keras.json配置文件排序"""
sdl = SimpleDatasetLoader.SimpleDatasetLoader(preprocessors=[sp,iap])
#加载图像和标签,并将图像缩放到[0,1]
(data,labels) = sdl.load(imagePaths,verbose=500)
data = data.astype('float')/255.0
#分割数据集,并将标签转化为向量
(trainX,testX,trainY,testY) = train_test_split(data,labels,test_size=0.25,random_state=42)
trainY = LabelBinarizer().fit_transform(trainY)
testY = LabelBinarizer().fit_transform(testY)
#初始化优化器和模型
print('[INFO] compiling model...')
opt = SGD(lr=0.005)
model = shallownet.ShallowNet.build(width=32,height=32,depth=3,classes=3)
model.compile(loss='categorical_crossentropy',optimizer=opt,metrics=['accuracy'])
#训练网络
print('[INFO] training network...')
H = model.fit(trainX,trainY,validation_data=(testX,testY),batch_size=32,epochs=100,verbose=1)
#评估网络
print('[INFO] evaluating network...')
predictions = model.predict(testX,batch_size=32)
print(classification_report(testY.argmax(axis=1),predictions.argmax(axis=1),target_names=['cat','dog','panda']))
plt.style.use("ggplot")
plt.figure()
plt.plot(np.arange(0, 100), H.history["loss"], label="train_loss")
plt.plot(np.arange(0, 100), H.history["val_loss"], label="val_loss")
plt.plot(np.arange(0, 100), H.history["acc"], label="train_acc")
plt.plot(np.arange(0, 100), H.history["val_acc"], label="val_acc")
plt.title("Training Loss and Accuracy")
plt.xlabel("Epoch #")
plt.ylabel("Loss/Accuracy")
plt.legend()
plt.show()
shallownet_cifar10.py
from sklearn.preprocessing import LabelBinarizer
from sklearn.metrics import classification_report
import shallownet
from keras.optimizers import SGD
from keras.datasets import cifar10
import matplotlib.pyplot as plt
import numpy as np
print("[INFO] loading CIFAR-10 data...")
((trainX,trainY),(testX,testY)) = cifar10.load_data()
trainX = trainX.astype('float')/255.0
testX = testX.astype('float')/255.0
lb = LabelBinarizer()
trainY = lb.fit_transform(trainY)
testY = lb.transform(testY)
labelNames = ["airplane", "automobile", "bird", "cat", "deer",
"dog", "frog", "horse", "ship", "truck"]
print('[INFO] compiling model...')
opt = SGD(lr=0.01)
model = shallownet.ShallowNet.build(width=32,height=32,depth=3,classes=10)
model.compile(loss='categorical_crossentropy',optimizer=opt,metrics=['accuracy'])
print('[INFO] training network...')
H = model.fit(trainX,trainY,validation_data=(testX,testY),batch_size=32,epochs=40,verbose=1)
print('[INFO] evaluating network...')
predictions = model.predict(testX,batch_size=32)
print(classification_report(testY.argmax(axis=1),predictions.argmax(axis=1),target_names=labelNames))
plt.style.use("ggplot")
plt.figure()
plt.plot(np.arange(0, 40), H.history["loss"], label="train_loss")
plt.plot(np.arange(0, 40), H.history["val_loss"], label="val_loss")
plt.plot(np.arange(0, 40), H.history["acc"], label="train_acc")
plt.plot(np.arange(0, 40), H.history["val_acc"], label="val_acc")
plt.title("Training Loss and Accuracy")
plt.xlabel("Epoch #")
plt.ylabel("Loss/Accuracy")
plt.legend()
plt.show()
二、注意事项
1.执行该程序
最好从电脑终端(或pycharm终端执行)进入 该程序所在路径 执行语句:python shallownet_animals.py --dataset ../datasets/animals
注:终端要在annoconda环境下