2023.10.7学习-卷积神经网络
人工智能基础学习
图像识别特点:局部性;可能出现在任意位置
下采样图像,不会改变图像目标
卷积运算会导致的问题:
-
图像被压缩,造成信息丢失
-
边缘信息使用次数少
所以需要进行图像填充预处理
图像处理步骤:
- 图像填充(padding)
在图像边缘增加像素(通过padding增加像素点数量,由过滤器尺寸与滑动窗口stride决定),使其在进行卷积运算后维持原图大小
- 卷积(conv)
选取尺寸为(k, k)的filter(也称卷积核kernel)其参数可学习,在图像上所有区域滑动,进行卷积运算
- 池化(pooling)
以小于原图像尺寸的窗口观察一个区域,提取最大值,通道数不变。将图片信息进一步降维,仅反映最突出的特点。
- 扁平化处理,将一维数据录入全连接隐藏层
经典CNN模型:
LeNet-5
特点:(1)随着网络越深,图像的高度和宽度在缩小,通道数(filter)在增加;(2)卷积和池化先后成对使用
AlexNet
特点:(1)适用于识别较复杂的彩色图,可识别1000种类别;(2)结构比LeNet更复杂,使用Relu作为激活函数
VGG
特点:(1)所有卷积层filter宽和高都是3,步长为1,padding都使用same convolution;(2)所有池化层filter宽和高都是2,步长为2;(3)相比于AlexNet,有更多的filter用于提取轮廓信息,具有更高精准性。
经典CNN模型应用新场景:
- 加载经典CNN模型,剥除其FC层,对图像进行预处理
- 把预处理完成的数据作为输入,分类结果为输出,建立MLP模型
- 模型训练
代码:猫狗识别
import numpy as np
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Conv2D, MaxPool2D, Flatten, Dense
from keras.preprocessing.image import load_img, img_to_array
# 图像预处理
# 可以进行图像增强、缩放、平移等各种操作,这里进行图像的归一化
train_datagen = ImageDataGenerator(rescale=1/255)
# 数据导入。参数:target_size=(50, 50):希望图片转换成的尺寸;batch_size=32:每次训练从图库中选多少张图片;class_mode='binary':二分类
training_set = train_datagen.flow_from_directory('./data_set/PetImages', target_size=(50, 50), batch_size=32, class_mode='binary')
# Found 25000 images belonging to 2 classes.
# 建立CNN模型
model = Sequential() # 创建顺序模型实例
# 增加卷积层。参数:32个filters;每个filter的尺寸为(3, 3);步长为1(默认,则不填写);输入图片的尺寸是(50, 50, 3);激活函数使用relu
model.add(Conv2D(32, (3, 3), input_shape=(50, 50, 3), activation='relu'))
# 增加池化层。参数:池化层的尺寸为(2, 2)
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())
# 增加全连接层。128个神经元
model.add(Dense(units=128, activation='relu'))
# 增加最后一个全连接层,因为是二分类,所以只设定一个神经元,激活函数使用“sigmoid”
model.add(Dense(units=1, activation='sigmoid'))
# 配置模型参数。使用adam优化器,损失函数为binary_crossentropy
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
# 查看模型结构
model.summary()
# 模型训练
model.fit_generator(training_set, epochs=15) # 迭代15次
# 测试训练数据的准确率
accuracy_train = model.evaluate_generator(training_set)
print(accuracy_train)
# 测试数据的准确率
test_set = train_datagen.flow_from_directory('./data_set/test_set', target_size=(50, 50), batch_size=32, class_mode='binary')
accuracy_test = model.evaluate_generator(test_set)
print(accuracy_test)
# 随机找一幅图片进行预测
pic_cat = '1.jpg'
pic_cat = load_img(pic_cat, target_size=(50, 50)) # 将图片转换成(50, 50)大小
pic_cat = img_to_array(pic_cat) # 转换为图像数组
pic_cat = pic_cat/255 # 归一化处理
pic_cat = pic_cat.reshape(1, 50, 50, 3) # 转换可进行图片预测的格式,维度转换().1:预测的第几张图片,(50, 50):图片维度;3:通道数
result = model.predict(pic_cat)
result = np.round(result).astype(int)
print(training_set.class_indices) # 查看类别
print(result) # 结果如果为1,狗;如果为0,猫
if result[0][0] == 0:
print('预测为:猫猫')
else:
print('预测为:狗狗')