人工智能--预训练的卷积神经网络

Posted Abro.

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了人工智能--预训练的卷积神经网络相关的知识,希望对你有一定的参考价值。

学习目标:

  1. 掌握使用预训练好的ResNet对自己的数据再次进行训练的方法。
  2. 掌握函数式建立Keras模型的方法。

学习内容:

  1. 利用ImageDataGenerator类直接从硬盘中读取猫和狗(cat-and-dog)数据,自定义合适的卷积神经网络进行分类。
  2. 对猫和狗(cat-and-dog)数据,在预训练好的ResNet上添加合适的网络层,构造网络进行训练。并调整网络参数,对比分析相应的结果。

学习过程:

1.Adam优化器,学习率为0.0001batch_size16,统一resize图片的大小为128*128,进行10次迭代的结果如下:

Adam优化器,学习率为0.0001batch_size16,统一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.0001batch_size16,统一resize图片的大小为128*128,进行10次迭代的结果如下:

调整优化器为Adam,学习率为0.0001batch_size16,统一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.跑起来有点费时,通过调整图像的大小,图像越大费时越多,最后只能往小了调整,但图片的像素小,最后测试的识别率不高。

以上是关于人工智能--预训练的卷积神经网络的主要内容,如果未能解决你的问题,请参考以下文章

人工智能--卷积结果可视化

使用预训练的卷积神经网络__keras实现VGG16

相关名词

卷积神经网络模型如何辨识裸体图片

[转] 轻松使用多种预训练卷积网络抽取图像特征

一键学习的人脸识别