深度学习_图像分类(二)——VGG训练数据(二)

目录

Step 1/4 数据制作 记录

Step 2/4 模型构建(该教程有计算过,就直接贴)

Step 3/4 训练(将数据、模型和损失函数优化器融合)


Step 1/4 数据制作 记录

(每步都会有整体代码附在节后面)

PetImages/
    train/
        Dog/
            1.jpg
            2.jpg
            ...
        Cat/
            1.jpg
            2.jpg
            ...
from tqdm import tqdm      # display Tqdm 是一个快速,可扩展的Python进度条
import cv2                 # working with, mainly resizing, images
import numpy as np         # dealing with arrays
import os                  # dealing with directories


TRAIN_DATA_DIR = r'./PetImages/train'
IMG_SIZE = 224
# one-hot 编码
def label_img(img):
    word_label = img.split('.')[-3]
    if word_label == 'cat': 
        return [1,0]
    elif word_label == 'dog': 
        return [0,1]
def create_train_dataset(path=TRAIN_DATA_DIR):
    training_data = []
    for img in tqdm(os.listdir(TRAIN_DATA_DIR)): # os.listdir突然不灵了,不能返回子层文件检索
        print(img)
        label = label_img(img) # one-hot                    #label
        path = os.path.join(TRAIN_DATA_DIR, img)
        img = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
        img = cv2.resize(img, (IMG_SIZE, IMG_SIZE))     #img
        training_data.append([np.array(img), label])
    shuffle(training_data)
    np.save('train_data.npy', training_data) # training_data 包含数据+标签,需要改动就自行在one-hot改
    return training_data

然而 os.listdir(path)出现问题,并没有返回子树的文件索引,重新弄了一个

TRAIN_DATA_DIR = r'./PetImages/train'
IMG_SIZE = 224    
'''
for parent, dirnames_list, filenames_list in os.walk(TRAIN_DATA_DIR): # 3个信息
    print(parent) # 父节点路径+子节点路径
    for dirname_list in dirnames_list:
        print(dirname_list)   # 子文件名            
    for filename_list in filenames_list:
        print(filename_list)  # 子文件下的文件                   
'''        
for img in tqdm(os.listdir(TRAIN_DATA_DIR)): # os.listdir突然不灵了,不能返回子层文件检索
    path = os.path.join(TRAIN_DATA_DIR, img) # 多加此行
    for path_list in os.listdir(path):
        label = label_data(img)
        path_list = os.path.join(path,path_list)
        src = cv2.imread(path_list, cv2.IMREAD_GRAYSCALE)
        cv2.imshow("src",src)
        cv2.waitKey(0)
        pass   
pass

Step 2/4 模型构建(该教程有计算过,就直接贴)

from keras.layers import *
from keras.models import *
from keras.optimizers import *
height = width = 224
def build_vgg(input_shape=(height, width, 3), num_classes=1000):
    model = Sequential()
    # Block 1, 2层
    model.add(Conv2D(64, 3, 3, activation='relu', border_mode='same', input_shape=input_shape))
    model.add(Conv2D(64, 3, 3, activation='relu',border_mode='same'))
    model.add(MaxPooling2D((2, 2), strides=(2, 2)))
    
    # Block 2, 2层
    model.add(Conv2D(128, 3, 3, activation='relu',border_mode='same'))
    model.add(Conv2D(128, 3, 3, activation='relu',border_mode='same'))
    model.add(MaxPooling2D((2, 2), strides=(2, 2)))
    
    # Block 3, 3层
    model.add(Conv2D(256, 3, 3, activation='relu',border_mode='same'))
    model.add(Conv2D(256, 3, 3, activation='relu',border_mode='same'))
    model.add(Conv2D(256, 3, 3, activation='relu',border_mode='same'))
    model.add(MaxPooling2D((2, 2), strides=(2, 2)))
    
    # Block 4, 3层
    model.add(Conv2D(512, 3, 3, activation='relu',border_mode='same'))
    model.add(Conv2D(512, 3, 3, activation='relu',border_mode='same'))
    model.add(Conv2D(512, 3, 3, activation='relu',border_mode='same'))
    model.add(MaxPooling2D((2, 2), strides=(2, 2)))
    
    # Block 5, 3层
    model.add(Conv2D(512, 3, 3, activation='relu',border_mode='same'))
    model.add(Conv2D(512, 3, 3, activation='relu',border_mode='same'))
    model.add(Conv2D(512, 3, 3, activation='relu',border_mode='same'))
    model.add(MaxPooling2D((2, 2), strides=(2, 2)))
    
    # Classification block, 全连接3层
    # 扁平层-化为一行,行接行
    model.add(Flatten())
    model.add(Dense(4096, activation='relu'))
    model.add(Dropout(0.5))
    model.add(Dense(4096, activation='relu'))
    model.add(Dropout(0.5))
    model.add(Dense(num_classes, activation='softmax'))
    return model
if __name__ == "__main__":
    # reference:keras中文手册: https://keras.io/zh/models/model/    
    # 模型结构
    model = build_vgg()
    # 配置器
    model.compile(loss='categorical_crossentropy', optimizer=Adam(0.0002), metrics=['accuracy'])
    # 模型打印    
    print(model.summary())
    pass

 

Step 3/4 训练(将数据、模型和损失函数优化器融合)

from __future__ import absolute_import, division, print_function
from tqdm import tqdm      # display Tqdm 是一个快速,可扩展的Python进度条
import cv2                 # working with, mainly resizing, images
import numpy as np         # dealing with arrays
import os                  # dealing with directories
from random import shuffle 

TRAIN_DATA_DIR = r'./PetImages/train'
img_width = img_height = 224  
# one-hot 编码
def label_data(label): # word_label = img.split('.')[-3]
    if label == 'cat': 
        return [1,0]
    elif label == 'dog': 
        return [0,1]
def create_train_dataset(path=TRAIN_DATA_DIR):
    training_data = []
    for img in tqdm(os.listdir(TRAIN_DATA_DIR)): # os.listdir突然不灵了,不能返回子层文件检索,只返回['cat','dog']   
        path = os.path.join(TRAIN_DATA_DIR, img) # 多加此行 返回 */cat/ 和 */dog/
        for path_list in os.listdir(path):
            label = label_data(img) # 
            path_list = os.path.join(path, path_list)
            src = cv2.imread(path_list)      #cv2.IMREAD_GRAYSCALE      
            if src is None:
                continue
            src = cv2.resize(src, (img_width, img_height))     #img
            training_data.append([np.array(src), label])
        pass
    pass
    shuffle(training_data)
    np.save('train_data.npy', training_data)
    return training_data


from keras.layers import *
from keras.models import *
from keras.optimizers import *
def build_vgg(input_shape=(img_width, img_height, 3), num_classes=2):
    model = Sequential()
    # Block 1, 2层
    model.add(Conv2D(64, 3, 3, activation='relu', border_mode='same', input_shape=input_shape))
    model.add(Conv2D(64, 3, 3, activation='relu',border_mode='same'))
    model.add(MaxPooling2D((2, 2), strides=(2, 2)))
    
    # Block 2, 2层
    model.add(Conv2D(128, 3, 3, activation='relu',border_mode='same'))
    model.add(Conv2D(128, 3, 3, activation='relu',border_mode='same'))
    model.add(MaxPooling2D((2, 2), strides=(2, 2)))
    
    # Block 3, 3层
    model.add(Conv2D(256, 3, 3, activation='relu',border_mode='same'))
    model.add(Conv2D(256, 3, 3, activation='relu',border_mode='same'))
    model.add(Conv2D(256, 3, 3, activation='relu',border_mode='same'))
    model.add(MaxPooling2D((2, 2), strides=(2, 2)))
    
    # Block 4, 3层
    model.add(Conv2D(512, 3, 3, activation='relu',border_mode='same'))
    model.add(Conv2D(512, 3, 3, activation='relu',border_mode='same'))
    model.add(Conv2D(512, 3, 3, activation='relu',border_mode='same'))
    model.add(MaxPooling2D((2, 2), strides=(2, 2)))
    
    # Block 5, 3层
    model.add(Conv2D(512, 3, 3, activation='relu',border_mode='same'))
    model.add(Conv2D(512, 3, 3, activation='relu',border_mode='same'))
    model.add(Conv2D(512, 3, 3, activation='relu',border_mode='same'))
    model.add(MaxPooling2D((2, 2), strides=(2, 2)))
    
    # Classification block, 全连接3层
    # 扁平层-化为一行,行接行
    model.add(Flatten())
    model.add(Dense(4096, activation='relu'))
    model.add(Dropout(0.5))
    model.add(Dense(4096, activation='relu'))
    model.add(Dropout(0.5))
    model.add(Dense(num_classes, activation='softmax'))
    return model


from sklearn.model_selection import train_test_split
from keras.preprocessing.image import ImageDataGenerator
from keras.callbacks import ModelCheckpoint, Callback, EarlyStopping, ReduceLROnPlateau
if __name__ == "__main__":
    # reference:keras中文手册: https://keras.io/zh/models/model/    
    # --------dataset--------
    Initdata = False # 如果存在数据npy不需要重新生成
    if Initdata == True:
        training_data = create_train_dataset()
    else:
        training_data = np.load('train_data.npy', allow_pickle = True) # 权限allow_pickle = True
    
    # spilt data 
    train, val = train_test_split(training_data, test_size = 0.25)
    X_train = np.array([i[0] for i in train]).reshape(-1,img_width,img_height,3)
    Y_train = np.array([i[1] for i in train])
    X_val = np.array([i[0] for i in val]).reshape(-1,img_width,img_height,3)
    Y_val = np.array([i[1] for i in val])
    
    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
        rotation_range=40,  # randomly rotate images in the range (degrees, 0 to 180)
        shear_range=0.3,    #错切变换,效果就是让所有点的x坐标(或者y坐标)保持不变,而对应的y坐标(或者x坐标)则按比例发生平移
        zoom_range = 0.2, # Randomly zoom image 
        width_shift_range=0.2,  # randomly shift images horizontally (fraction of total width)
        height_shift_range=0.2,  # randomly shift images vertically (fraction of total height)
        horizontal_flip=True,  # randomly flip images
        vertical_flip=True  # randomly flip images
        )  
    

    # --------model--------
    # 
    epochs = 1
    batch_size = 64
    #optimizer = Adam(0.0002)
    optimizer = RMSprop(lr=1e-4)

    learning_rate_reduction = ReduceLROnPlateau(
        monitor='val_loss', 
        patience=4, 
        verbose=1, 
        factor=0.5, 
        min_lr=5e-8
        )

    early_stopping = EarlyStopping(
        monitor='val_loss', 
        patience=6,
        min_delta=0.0002, 
        verbose=1, 
        mode='auto'
        )   

    filepath="./weights/weights.best.hdf5"
    if not os.path.exists('./weights'):
            os.mkdir('./weights')
    checkpoint = ModelCheckpoint(
        filepath, 
        monitor='val_loss', 
        verbose=1, 
        save_best_only=True, 
        mode='auto'
        )

    # 模型结构
    model = build_vgg()
    # 配置器
    model.compile(loss='categorical_crossentropy', optimizer=optimizer, metrics=['accuracy'])
    print(model.summary())
    print(X_train.shape[0])
    
    model_his = model.fit_generator(
        datagen.flow(X_train,Y_train, batch_size=batch_size),
        epochs = epochs, 
        validation_data = (X_val,Y_val), 
        shuffle=True, 
        verbose = 1, 
        steps_per_epoch=X_train.shape[0] // batch_size, 
        callbacks=[learning_rate_reduction, early_stopping, checkpoint]
        )
    model.save(filepath)
    # draw training ——》》》model_his

    pass

'''
# 问题解决 1 :
AttributeError: module ‘tensorboard' has no attribute 'lazy'(谷歌出来的结果是Make sure that you don't have tb-nightly installed in your env.)
我采用pip uninstall tb-nightly指令发现并没有安装
'''

Step 4/4 测试 

网上一大把教程,就不弄了。

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

智能之心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值