人工智能--预训练的卷积神经网络
Posted Abro.
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了人工智能--预训练的卷积神经网络相关的知识,希望对你有一定的参考价值。
学习目标:
- 掌握使用预训练好的ResNet对自己的数据再次进行训练的方法。
- 掌握函数式建立Keras模型的方法。
学习内容:
- 利用ImageDataGenerator类直接从硬盘中读取猫和狗(cat-and-dog)数据,自定义合适的卷积神经网络进行分类。
- 对猫和狗(cat-and-dog)数据,在预训练好的ResNet上添加合适的网络层,构造网络进行训练。并调整网络参数,对比分析相应的结果。
学习过程:
1.用Adam优化器,学习率为0.0001,batch_size为16,统一resize图片的大小为128*128,进行10次迭代的结果如下:
用Adam优化器,学习率为0.0001,batch_size为16,统一resize图片的大小为256*256,进行15次迭代的结果如下:
最后测试集的识别率为0.7420。
优化器 | 学习率 | 批量大小 | 图片大小 | 迭代次数 | 识别率 |
Adam | 0.0001 | 16 | 128*128 | 10 | 0.7830 |
Adam | 0.0001 | 16 | 256*256 | 15 | 0.7420 |
图像放大后进行测试的效果反而没有没放大之前的好。
2.
模型各层的输出大小:
预训练好的ResNet上调整优化器为Adam,学习率为0.0001,batch_size为16,统一resize图片的大小为128*128,进行10次迭代的结果如下:
调整优化器为Adam,学习率为0.0001,batch_size为16,统一resize图片的大小为64*64,进行20次迭代的结果如下:
训练结果如下表:
优化器 | 学习率 | 批量大小 | 图片大小 | 迭代次数 | 识别率 |
Adam | 0.0001 | 16 | 128*128 | 10 | 0.7123 |
Adam | 0.0001 | 16 | 64*64 | 20 | 0.6653 |
图像缩小后进行测试的效果也没有图片像素为128*128的好。
源码:
第一问:
# In[0]:构造网络
from tensorflow.keras import Sequential,Input,layers,optimizers
model = Sequential( [
Input(shape=(256,256,3)), # 二维卷积操作的输入数据要求:[样本数,宽度,高度,通道数]
layers.Conv2D(32, kernel_size=(3, 3), activation="relu"), # 3x3的卷积核,输出32个通道
layers.MaxPooling2D(pool_size=(2, 2)), # 取2x2网格的最大值进行下采样
layers.Conv2D(64, kernel_size=(3, 3), activation="relu"),
layers.MaxPooling2D(pool_size=(2, 2)),
layers.Conv2D(64, kernel_size=(3, 3), activation="relu"),
layers.Flatten(), # 把上一层得到的结果展平成一维向量(3*3*64=576)
layers.Dropout(0.5), # 训练时,每个batch随机选50%的权重固定不更新
layers.Dense(64, activation="relu"),
layers.Dense(2, activation="softmax"),
])
model.summary()
# 自定义优化器
optimizer = optimizers.Adam(lr=0.0001)
model.compile(optimizer,loss='categorical_crossentropy', metrics=['accuracy'])
# In[1]: 加载数据
from tensorflow.keras.preprocessing.image import ImageDataGenerator
datagen_train = ImageDataGenerator(rescale = 1. / 255 ,
#rotation_range = 20,
# width_shift_range = 0.2,
#height_shift_range = 0.2
#shear_range = 0.2,
#zoom_range = 0.2,
#horizontal_flip = True,
)
# In[2]:从硬盘分批读取数据并测试
generator_train = datagen_train.flow_from_directory(
r'D:\\Cadabra_tools002\\course_data\\cat-and-dog\\training_set', # 训练集所在路径,子目录为类别
target_size=(256, 256), # 统一resize所有图片的大小为 (28,28)
batch_size=16, # 输入到fit函数中的批的大小
)
model.fit(generator_train,epochs=15)
# In[3]:从硬盘分批读取数据并测试
datagen_validation = ImageDataGenerator(rescale = 1. / 255)
generator_validation = datagen_validation.flow_from_directory(
r'D:\\Cadabra_tools002\\course_data\\cat-and-dog\\test_set',
target_size=(256, 256), #依次换成128*128和256*256
batch_size=16,
)
# In[4]:测试
loss, accuracy = model.evaluate(generator_validation)
第二问:
#-------------------------------------------
# 用预训练好的ResNet50网络进行图像分类,并根据自己的数据微调网络权重
#-------------------------------------------
from tensorflow.keras.applications.resnet50 import ResNet50
from tensorflow.keras.layers import Flatten, Dense
from tensorflow.keras.models import Model
from tensorflow.keras.regularizers import l2
from tensorflow.keras import Sequential,optimizers
import numpy as np
#import cv2
# In[1]: 加载数据
from tensorflow.keras.preprocessing.image import ImageDataGenerator
datagen_train = ImageDataGenerator(rescale = 1. / 255 ,)
# In[2]:从硬盘分批读取数据并测试
generator_train = datagen_train.flow_from_directory(
r'D:\\Cadabra_tools002\\course_data\\cat-and-dog\\training_set', # 训练集所在路径,子目录为类别
target_size=(64, 64), # 统一resize所有图片的大小为 (28,28)
batch_size=16, # 输入到fit函数中的批的大小
)
# In[2]: ResNet50模型,加载预训练权重
# 若没有模型文件,则自动下载(由于下载速度很慢,所以建议先把文件放进相应的目录)
# C:\\Users\\Administrator\\.keras\\models\\resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5
base_model = ResNet50(input_shape=(64, 64, 3),
include_top=False,
weights='imagenet')
base_model.trainable=False
x = base_model.output
x = Flatten()(x)
x = Dense(512,activation='relu',kernel_regularizer=l2(0.0003))(x)
predictions = Dense(2, activation='softmax')(x)
model = Model(inputs=base_model.input, outputs=predictions)
#自定义优化器
optimizer = optimizers.Adam(lr=0.0001)
model.compile(optimizer, loss='categorical_crossentropy',metrics=['accuracy'])
model.summary() # 打印模型各层的输出大小
# In[3]: 训练
# 更改迭代此处 epochs=50,才能获得比较高的识别率
model.fit(generator_train,epochs=20, batch_size=16,)
#model.save_weights('resnet_turn_cifar10.h5')
# In[4]:测试
datagen_validation = ImageDataGenerator(rescale = 1. / 255)
generator_validation = datagen_validation.flow_from_directory(
r'D:\\Cadabra_tools002\\course_data\\cat-and-dog\\test_set',
target_size=(64, 64), #依次换成128*128和64*64
batch_size=16,
)
# In[5]:测试识别率
loss, accuracy = model.evaluate(generator_validation)
print('测试识别率为:', np.round(accuracy,4))
学习产出:
1.跑起来有点费时,通过调整图像的大小,图像越大费时越多,最后只能往小了调整,但图片的像素小,最后测试的识别率不高。
以上是关于人工智能--预训练的卷积神经网络的主要内容,如果未能解决你的问题,请参考以下文章