迁移学习: 使用别人预训练模型参数时,要注意别人的预处理方式。
常见的迁移学习方式:
导入resnet 模型:
model.compile(loss = 'categorical_crossentropy',optimizer = 'adam',metrics = ['acc'])
# 切片指定, 不可调整的层数
for layer in resnet50.layers[0:-5]:layer.trainable = False
使用迁移学习的优势:
注意:使用别人预训练模型参数时,要注意别人的预处理方式。
常见的迁移学习方式:
from tensorflow import keras
import numpy as np
import pandas as pd
import tensorflow as tf
import matplotlib.pyplot as pltcpu=tf.config.list_physical_devices("CPU")
tf.config.set_visible_devices(cpu)
print(tf.config.list_logical_devices())
resnet50 = keras.applications.ResNet50(include_top=False, pooling='avg')num_classes =10
model = keras.models.Sequential()
model.add(resnet50)
model.add(keras.layers.Dense(num_classes, activation = 'softmax'))
model.summary()
# 把除最后一层的参数外, 全部冻结
model.layers[0].trainable = False
model.compile(loss = 'categorical_crossentropy',optimizer = 'adam',metrics = ['acc'])
train_dir = '../day 48 resnet/training/training/'
valid_dir = '../day 48 resnet/validation/validation/'
train_datagen = keras.preprocessing.image.ImageDataGenerator(preprocessing_function = keras.applications.resnet50.preprocess_input,rotation_range = 40,width_shift_range = 0.2,height_shift_range = 0.2,shear_range = 0.2,zoom_range = 0.2,horizontal_flip = True,vertical_flip = True,fill_mode = 'nearest')height = 224
width = 224
channels = 3
batch_size = 32
num_classes = 10train_generator = train_datagen.flow_from_directory(train_dir,target_size= (height, width),batch_size = batch_size,shuffle= True,seed = 7,class_mode= 'categorical')valid_datagen = keras.preprocessing.image.ImageDataGenerator(preprocessing_function = keras.applications.resnet50.preprocess_input)valid_generator = valid_datagen.flow_from_directory(valid_dir,target_size= (height, width),batch_size= batch_size,shuffle= True,seed = 7,class_mode= 'categorical')
print(train_generator.samples) # 1098
print(valid_generator.samples) # 272
# 使用迁移学习, 效果较差, 原始数据的处理方式不同
# 修改需处理方式继续执行, 效果较好
histroy = model.fit(train_generator,steps_per_epoch= train_generator.samples // batch_size,epochs = 10,validation_data = valid_generator,validation_steps= valid_generator.samples // batch_size)
resnet50 = keras.applications.ResNet50(include_top=False, pooling='avg', weights='imagenet')
# 切片指定, 不可调整的层数
for layer in resnet50.layers[0:-5]:layer.trainable = False# 添加输出层
resnet50_new = keras.models.Sequential([resnet50, keras.layers.Dense(10, activation = 'softmax')])
resnet50_new.compile(loss = 'categorical_crossentropy',optimizer = 'adam',metrics = ['acc'])
resnet50_new.summary()
histroy = resnet50_new.fit(train_generator,steps_per_epoch= train_generator.samples // batch_size,epochs = 10,validation_data = valid_generator,validation_steps= valid_generator.samples // batch_size)
# 预测数据
mokey = plt.imread('./n5020.jpg')
plt.imshow(mokey) # mokey.shape (600, 336, 3)
for i in range(2):x, y = train_generator.next()print(type(x), type(y)) # print('***', x.shape, y.shape) # *** (32, 224, 224, 3) (32, 10)
# 主要是形状和尺寸不对
# 改变尺寸, 再改变形状reshape
from scipy import ndimage # 专门处理图片
# 改变形状
# 224 = 367 * x x = 224/367
# 224 = 550 * y y = 224/550
zoom = (224/mokey.shape[0], 224/mokey.shape[1])
monkey_zoomed = ndimage.zoom(mokey, (224/mokey.shape[0], 224/mokey.shape[1], 1))
monkey_zoomed.shape # (224, 224, 3)
monkey_1 = keras.applications.resnet50.preprocess_input(monkey_zoomed)
monkey_1.min() # -123.68
monkey_1 = monkey_1.reshape(1, 224, 224, 3)
model.predict(monkey_1).argmax(axis = 1) # array([5], dtype=int64)
mokey1 = mokey/127.5
plt.imshow(mokey1)
mokey1 = mokey1 - 1
plt.imshow(mokey1)
mokey1