VGG16迁移学习

#代码参考网上博客
import random

from imutils import paths
from keras.optimizers import SGD
from keras_preprocessing.image import load_img, img_to_array
from tensorflow.python.keras.utils import get_file
import gzip
import numpy as np
import keras
from keras.datasets import cifar10
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential, Model
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Conv2D, MaxPooling2D
import os
from keras import applications, Input
import cv2
import tensorflow as tf

#用自己的数据集实现4分类
def load_images(x):
    image = cv2.imread(x)
    # image = cv2.resize(image, (224, 224))
    # print(type(image))
    return image

# 获得模型用数据结构
def load_data_split1(datapath):
    imagePaths = list(paths.list_images(datapath))
    random.shuffle(imagePaths)
    labels = [int(i.split('\\')[-1][0]) for i in imagePaths]
    # print(labels)
    images = np.array([load_images(i) for i in imagePaths])
    return (images, labels)

print('[INFO] loading dataset......')
# include_top = False表明我们迁移除顶层以外的其余网络结构到自己的模型中
img_width, img_height = 224, 224
train_data_dir = 'D:\PPG-picture\HR_dataset_5\\train\\'
test_data_dir = 'D:\PPG-picture\HR_dataset_5\\test\\'
(x_train, y_train) = load_data_split1(train_data_dir)
(x_test, y_test) = load_data_split1(test_data_dir)
# 将类别弄成独热编码
y_train = keras.utils.to_categorical(y_train, 4)
y_test = keras.utils.to_categorical(y_test, 4)

print('[INFO] initializing model......')
# 即每次训练在训练集中取batchsize个样本训练;
batch_size = 32
num_classes = 4
# 完整的数据集在同样的神经网络中传递5次
epochs = 50
data_augmentation = False# 图像增强
# num_predictions = 20
# 模型保存:
save_dir = os.path.join(os.getcwd(), 'saved_models_transfer_learning')
print('模型保存路径:', save_dir)
model_name = 'keras_fashion_transfer_learning_trained_model1.h5'

print('[INFO] initializing model......')
base_model = applications.VGG16(include_top=False, weights='imagenet',
                                input_tensor=Input(shape=(img_width, img_height, 3)))  # 第一层需要指出图像的大小
base_model.summary()
model = Sequential()
print('基本模型的输出:', base_model.output)
model.add(Flatten(input_shape=base_model.output_shape[1:]))
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(64, activation='relu'))
# model.add(Dropout(0.5))
model.add(Dense(num_classes))
model.add(Activation('softmax'))
# add the model on top of the convolutional base
model = Model(inputs=base_model.input, outputs=model(base_model.output))  # VGG16模型与自己构建的模型合并
# 保持VGG16的前15层权值不变,即在训练过程中不训练
for layer in model.layers[:15]:
    layer.trainable = False

# 初始化 RMSprop 优化器
opt = keras.optimizers.rmsprop(lr=0.0001, decay=1e-6)
sgd = SGD(lr=0.0001, momentum=0.9)
# Let's train the model using RMSprop
model.compile(loss='categorical_crossentropy',
              optimizer=sgd,
              # optimizer=sgd,
              metrics=['accuracy'])

print('[INFO] training model')

if not data_augmentation:
    print('Not using data augmentation.')
    history = model.fit(x_train, y_train,
                        batch_size=batch_size,
                        epochs=epochs,
                        validation_data=(x_test, y_test),
                        shuffle=True)
else:
    print('Using real-time data augmentation.')
    # This will do preprocessing and realtime data augmentation:
    datagen = ImageDataGenerator(
        featurewise_center=False,  # set input mean to 0 over the dataset
        samplewise_center=False,  # set each sample mean to 0
        featurewise_std_normalization=False,  # divide inputs by std of the dataset
        samplewise_std_normalization=False,  # divide each input by its std
        zca_whitening=False,  # apply ZCA whitening
        zca_epsilon=1e-06,  # epsilon for ZCA whitening
        rotation_range=0,  # randomly rotate images in the range (degrees, 0 to 180)
        # randomly shift images horizontally (fraction of total width)
        width_shift_range=0.1,
        # randomly shift images vertically (fraction of total height)
        height_shift_range=0.1,
        shear_range=0.,  # set range for random shear
        zoom_range=0.,  # set range for random zoom
        channel_shift_range=0.,  # set range for random channel shifts
        # set mode for filling points outside the input boundaries
        fill_mode='nearest',
        cval=0.,  # value used for fill_mode = "constant"
        horizontal_flip=False,  # randomly flip images
        vertical_flip=False,  # randomly flip images
        # set rescaling factor (applied before any other transformation)
        rescale=None,
        # set function that will be applied on each input
        preprocessing_function=None,
        # image data format, either "channels_first" or "channels_last"
        data_format=None,
        # fraction of images reserved for validation (strictly between 0 and 1)
        )
#测试上面的ImageDataGenerator的效果
    img1=load_img('D:\PPG-picture\HR_dataset_5\\train\\0.3.jpg')
    x=img_to_array(img1)
    x = x.reshape((1,) + x.shape)
    i = 0
    for batch in datagen.flow(x, batch_size=1,
                              save_to_dir='D:\PPG-picture\HR_dataset_5\\', save_prefix='test', save_format='jpeg'):
        i += 1
        if i > 20:
            break


            # Compute quantities required for feature-wise normalization
    # (std, mean, and principal components if ZCA whitening is applied).
    datagen.fit(x_train)
    print(x_train.shape[0] // batch_size)  # 取整
    print(x_train.shape[0] / batch_size)  # 保留小数
    # Fit the model on the batches generated by datagen.flow().
    history = model.fit_generator(datagen.flow(x_train, y_train,  # 按batch_size大小从x,y生成增强数据
                                               batch_size=batch_size),
                                  # flow_from_directory()从路径生成增强数据,和flow方法相比最大的优点在于不用
                                  # 一次将所有的数据读入内存当中,这样减小内存压力,这样不会发生OOM
                                  epochs=epochs,
                                  steps_per_epoch=x_train.shape[0] // batch_size,
                                  validation_data=(x_test, y_test),
                                  workers=10  # 在使用基于进程的线程时,最多需要启动的进程数量。
                                  )

model.summary()
# Save model and weights
if not os.path.isdir(save_dir):
    os.makedirs(save_dir)
model_path = os.path.join(save_dir, model_name)
model.save(model_path)
print('Saved trained model at %s ' % model_path)

import matplotlib.pyplot as plt

# 绘制训练 & 验证的准确率值
plt.plot(history.history['acc'])
plt.plot(history.history['val_acc'])
plt.title('Model accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epoch')
plt.legend(['Train', 'Valid'], loc='upper left')
plt.savefig('tradition_cnn_valid_acc.png')
plt.show()

# 绘制训练 & 验证的损失值
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('Model loss')
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.legend(['Train', 'Valid'], loc='upper left')
plt.savefig('tradition_cnn_valid_loss.png')
plt.show()

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值