一、图像卷积运算
对图像矩阵与滤波器矩阵进行对应相乘再求和运算,转化得到新的矩阵。
作用:快速定位图像中某些边缘特征
英文:convolution(CNN)
池化层实现维度缩减
池化:按照一个固定规则对图像矩阵进行处理,将其转换为更低维度的矩阵
卷积神经网络
把卷积、池化、mlp先后连接在一起,组成卷积神经网络。

激活函数:Relu
卷积神经网络两大特点
-
参数共享(parameter sharing):同一个特征过滤器可用于整张图片
-
稀疏连接(sparsity of connections):生成的特征图片每个节点只与原图片中特定节点连接
经典的CNN模型
二、实战准备
三、实战:建立CNN模型,识别图片中的猫/狗

#加载数据
from tensorflow.keras.preprocessing.image import ImageDataGenerator
train_datagen = ImageDataGenerator(rescale=1./255)
training_set = train_datagen.flow_from_directory('./dataset/training_set',
target_size=(50,50),
batch_size=32,
class_mode='binary')

#创建cnn模型
from keras.models import Sequential
from keras.layers import Conv2D,MaxPool2D,Flatten,Dense
model = Sequential()
#卷积层
model.add(Conv2D(32,(3,3),input_shape=(50,50,3),activation='relu'))
#池化层
model.add(MaxPool2D(pool_size=(2,2)))
#卷积层
model.add(Conv2D(32,(3,3),activation='relu'))
#池化层
model.add(MaxPool2D(pool_size=(2,2)))
#展开
model.add(Flatten())
#全连接层
model.add(Dense(units=128,activation='relu'))
#输出层
model.add(Dense(units=1,activation='sigmoid'))
#配置模型 (优化器,损失函数)
model.compile(optimizer='adam',
loss='binary_crossentropy',
metrics=['accuracy'])
#查看模型结构
model.summary()

#模型训练
model.fit(training_set,epochs=25)

#训练集模型准确率
accuracy_train = model.evaluate(training_set)
print(accuracy_train)

#测试集模型准确率
test_set = train_datagen.flow_from_directory('./dataset/test_set',
target_size=(50,50),
batch_size=32,
class_mode='binary')
accuracy_test = model.evaluate(test_set)
print(accuracy_test)

#预测单张测试图片
from keras.preprocessing.image import load_img,img_to_array
import numpy as np
pic_dog = 'dog_test.jpg'
pic_dog = load_img(pic_dog,target_size=(50,50))
pic_dog = img_to_array(pic_dog)
pic_dog = pic_dog/255
pic_dog = pic_dog.reshape(1,50,50,3)
predictions = model.predict(pic_dog)
result = '预测为:狗狗' if predictions[0] >= 0.5 else '预测为:猫咪'
print(result)

training_set.class_indices

#测试多张图片,验证准确率
import matplotlib as mlp
font2 = {'family' :'SimHei',
'weight':'normal',
'size':20,}
mlp.rcParams['font.family'] = 'SimHei'
mlp.rcParams['axes.unicode_minus'] = False
from matplotlib import pyplot as plt
from matplotlib.image import imread
from keras.preprocessing.image import load_img
from keras.preprocessing.image import img_to_array
from keras.models import load_model
a = [i for i in range(1,10)]
fig = plt.figure(figsize=(10,10))
for i in a:
img_name = str(i)+'.jpg'
img_ori = load_img(img_name,target_size=(50,50))
img = img_to_array(img_ori)
img = img.astype('float32')/255
img = img.reshape(1,50,50,3)
predictions = model.predict(img)
img_ori = load_img(img_name,target_size=(250,250))
plt.subplot(3,3,i)
plt.imshow(img_ori)
plt.title('预测为:狗狗' if predictions[0] >= 0.5 else '预测为:猫咪')
plt.show()

四、实战:使用VGG16模型提取图像特征,再根据特征建立mlp模型,实现猫狗图像识别
#加载数据
from keras.preprocessing.image import load_img,img_to_array
img_path = '1.jpg'
img = load_img(img_path,target_size=(224,224))
img = img_to_array(img)
print(type(img))

#导入VGG16模型
from keras.applications.vgg16 import VGG16
from keras.applications.vgg16 import preprocess_input
import numpy as np
model_vgg = VGG16(weights='imagenet',include_top=False)
x = np.expand_dims(img,axis=0)
x = preprocess_input(x)#图像预处理
print(x.shape)

#特征轮廓提取
features = model_vgg.predict(x)
print(features.shape)

features = features.reshape(1,7*7*512)
print(features.shape)

#可视化图片
from matplotlib import pyplot as plt
fig = plt.figure(figsize=(2,2))
img = load_img(img_path,target_size=(224,224))
plt.imshow(img)

#批量处理图片
from keras.preprocessing.image import img_to_array,load_img
from keras.applications.vgg16 import VGG16
from keras.applications.vgg16 import preprocess_input
import numpy as np
model_vgg = VGG16(weights='imagenet',include_top=False)
def modelProcess(img_path,model):
img = load_img(img_path,target_size=(224,224))
img = img_to_array(img)
x = np.expand_dims(img,axis=0)
x = preprocess_input(x)
x_vgg = model.predict(x)
x_vgg = x_vgg.reshape(1,25088)
return x_vgg
import os
folder = 'dataset/vgg16_set/cat'
# folder = 'dataset/test_set/cat'
dirs = os.listdir(folder)
img_path = []
for i in dirs:
if os.path.splitext(i)[1] == '.jpg':
img_path.append(i)
img_path = [folder+'//'+i for i in img_path]
features1 = np.zeros([len(img_path),25088])
for i in range(len(img_path)):
feature_i = modelProcess(img_path[i],model_vgg)
print('preprocessed:',img_path[i])
features1[i] = feature_i
folder = 'dataset/vgg16_set/dog'
# folder = 'dataset/test_set/dog'
dirs = os.listdir(folder)
img_path = []
for i in dirs:
if os.path.splitext(i)[1] == '.jpg':
img_path.append(i)
img_path = [folder+'//'+i for i in img_path]
features2 = np.zeros([len(img_path),25088])
for i in range(len(img_path)):
feature_i = modelProcess(img_path[i],model_vgg)
print('preprocessed:',img_path[i])
features2[i] = feature_i
print(features1.shape,features2.shape)
y1 = np.zeros(300)
y2 = np.ones(300)
# y1 = np.zeros(3)
# y2 = np.ones(1)
x = np.concatenate((features1,features2),axis=0)
y = np.concatenate((y1,y2),axis=0)
y = y.reshape(-1,1)
print(x.shape,y.shape)

#数据分离
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.3,random_state=50)
print(x_train.shape,x_test.shape,x.shape)

#建立mlp模型
from keras.models import Sequential
from keras.layers import Dense
model = Sequential()
model.add(Dense(units=10,activation='relu',input_dim=25088))
model.add(Dense(units=1,activation='sigmoid'))
model.summary()

#配置模型,训练模型
model.compile(optimizer='adam',
loss='binary_crossentropy',
metrics=['accuracy'])
model.fit(x_train,y_train,epochs=50)

#预测
from sklearn.metrics import accuracy_score
# 获取预测概率
y_train_pred_prob = model.predict(x_train)
# 二分类:sigmoid输出,使用0.5作为阈值
y_train_predict = (y_train_pred_prob > 0.5).astype("int32").flatten()
accuracy_train = accuracy_score(y_train,y_train_predict)
print(accuracy_train)

# 获取预测概率
y_test_pred_prob = model.predict(x_test)
# 二分类:sigmoid输出,使用0.5作为阈值
y_test_predict = (y_test_pred_prob > 0.5).astype("int32").flatten()
accuracy_test = accuracy_score(y_test,y_test_predict)
print(accuracy_test)

#测试多张图片,验证准确率
import matplotlib as mlp
font2 = {'family' :'SimHei',
'weight':'normal',
'size':20,}
mlp.rcParams['font.family'] = 'SimHei'
mlp.rcParams['axes.unicode_minus'] = False
from matplotlib import pyplot as plt
from matplotlib.image import imread
from keras.preprocessing.image import load_img
from keras.preprocessing.image import img_to_array
from keras.models import load_model
a = [i for i in range(1,10)]
fig = plt.figure(figsize=(10,10))
for i in a:
img_name = str(i)+'.jpg'
img_ori = load_img(img_name,target_size=(224,224))
img = img_to_array(img_ori)
x = np.expand_dims(img,axis=0)
x = preprocess_input(x)
#vgg16提取特征
x_vgg = model_vgg.predict(x)
x_vgg = x_vgg.reshape(1,25088)
# 获取预测概率
predictions = model.predict(x_vgg)
# 二分类:sigmoid输出,使用0.5作为阈值
y_train_predict = (y_train_pred_prob > 0.5).astype("int32").flatten()
img_ori = load_img(img_name,target_size=(250,250))
plt.subplot(3,3,i)
plt.imshow(img_ori)
plt.title('预测为:狗狗' if predictions >= 0.5 else '预测为:猫咪')
plt.show()
