ML、DL、CNN学习记录3


ML、DL、CNN学习记录3

# coding: utf-8
# Date:2020/8/15 19:16
# @Author: hcf
# @Name: layer_name_intro
import os

import numpy as np
import pandas as pd

# import keras
import tensorflow.keras as keras

# 序贯模型
from keras.models import Sequential, Model
# 模型的层
from tensorflow.python.keras.layers import Conv2D, MaxPool2D, Flatten, ReLU, Dense
# 数据集合
from keras.datasets import mnist
"""
from . import mnist 
from . import imdb
from . import reuters
from . import cifar10
from . import cifar100
from . import boston_housing
from . import fashion_mnist
"""
# 加载已经训练完成的模型
from tensorflow.python.keras.models import load_model
# 梯度下降方法
from tensorflow.python.keras.optimizer_v2.gradient_descent import SGD
# one-hot 编码
from tensorflow.python.keras.utils.np_utils import to_categorical
# 图片读取,写入(op)
import cv2
# 交叉熵
from tensorflow.python.keras.losses import categorical_crossentropy


if __name__ == '__main__':

    # 加载的数据在c盘的 .keras文件夹中
    # 训练集:60 000
    # 测试集:10 000
    (x_train,y_train), (x_test,y_test) = mnist.load_data()
    # print(x_train)
    # print(type(x_train))
    # print(x_train.shape)
    # ==================================
    # 数据预处理
    # ==================================
    # 每张图的结构 (28,28) ==> (28,28,1)
    # 所以需要进行转换
    x_train = x_train.reshape((-1, 28, 28, 1))
    x_test = x_test.reshape((-1, 28, 28, 1))
    # 数据类型的one-hot编码
    # 1            2            3           4          ... 10
    # 1000000000   010000000    0010000000  0001000000 ... 0000000001
    y_train = to_categorical(y_train)
    y_test = to_categorical(y_test)
    ''' 进行数据处理
    output_path = 'mnist/'
    if not os.path.exists(output_path):
        os.makdir(output_path)
    m,w,h = x_train.shape
    for i in range(m):
        img = x_train[i]
        c = y_train[i]
        if not os.path.exists():
            img_path = os.path.join(output_path, str(c))
            os.mkdir(img_path)
        img_path = os.path.join(output_path, str(c))
        cv2.imwrite(img_path + str(i)+'.png',img)
    '''
    # =================================================
    # 模型建立
    # =================================================
    # 判断模型是否已经存在后
    if os.path.exists('model_mnist.h5'):
        print('加载模型!!!')
        model = load_model('model_mnist.h5')
    else:
        # 代表序贯模型
        model = Sequential()
        # Image(28,28,1)
        # filter: 过滤器 ==> 生成的下一层通道数目
        # 卷积核大小 kernel_size = 5  ==> (5, 5)
        # 激活函数activation = relu
        # 初始的输入层 才需要设置 input_shape=(28, 28, 1)
        model.add(Conv2D(filters=6, kernel_size=5, padding='same', activation='relu', input_shape=(28, 28, 1)))
        # padding 是否增加 全零
        model.add(MaxPool2D(pool_size=(2, 2), padding='same'))
        # 一个二维的卷积层
        conv_layer = Conv2D(filters=16, kernel_size=5, padding='same', activation='relu')
        # 可以设置  让这一层不进行训练
        conv_layer.trainable = False
        model.add(conv_layer)
        # padding 是否增加 全零
        model.add(MaxPool2D(pool_size=(2, 2), padding='same'))
        # 拉平(向量化)
        model.add(Flatten())
        # 全连接
        model.add(Dense(64, activation='relu'))
        # 主义数据需要 one-hot编码
        model.add(Dense(10, activation='softmax'))
        print('model structure')
    # 打印网络模型信息
    model.summary()

    # ================================
    # 模型训练
    # ================================
    # 给定损失函数, 损失函数用于判断模型工作好不好的,决定了模型结果的好坏
    # 交叉熵 = cross Entropy  =  -ln(y_pred(yi))
    # loss = -sum(y_pred(yi))
    # For example :
    # 误差损失平方和 loss = sum(yi- yi_pred)**2
    #     0    0     1    0     预测结果  交叉熵
    # P1  0.1  0.2  0.4  0.3    Yes      -ln0.4
    # P2  0.01 0.02 0.90 0.07   Yes      -ln0.9
    # 但是 P2 的效果更好,
    # 损失loss:交叉熵
    # 优化器SGD:梯度下降
    #       epoch 一个 epoch 中有若干个 batch
    #       梯度下降是每个batch中进行梯度下降
    # metrics: 准确率
    model.compile(loss=categorical_crossentropy, optimizer=SGD(lr=0.001), metrics=['acc'])
    # epochs=10 : 训练多少轮
    # batch_size=128: 每轮训练中将 128 个当做一批
    # model.fit(x_train, y_train, batch_size=128, epochs=10, validation_split=[x_test,y_test]])
    history = model.fit(x_train, y_train, batch_size=128, epochs=10, validation_split=0.1)
    # 可以打印结果,
    print(history.history)
    model.save('model_mnist.h5')
    # y_test_pred = model.predict(x_test)
    result =model.evaluate(x_test, y_test)
    print('测试结果:', result)

    # ================================================================================
    # 访问模型隐层
    # ================================================================================
    from keras.applications.vgg16 import VGG16, preprocess_input, decode_predictions
    from keras.preprocessing import image
    base_model = model
    img_path = 'son.png'
    output_path = './Layer/'
    img = image.load_img(img_path, target_size=(224,224))
    x = image.img_to_array(img)
    x = np.expand_dims(x, axis=0)
    x = preprocess_input(x)

    if not os.path.exists(output_path):
        os.mkdir(output_path)
    # 遍历模型的每一层
    for layer in base_model.layers:
        # 打印层信息
        # <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x000001F2DC259828>
        print(layer)
        layer_path_name = os.path.join(output_path, layer.name)
        # 打印层名
        print(layer_path_name)
        if not os.path.exists(layer_path_name):
            os.mkdir(layer_path_name)
        # 将某一隐藏层作为模型的输出
        model = Model(inputs=base_model.input, outputs=layer.output)
        # 进行图片预测
        feature_maps = model.predict(x[:, :, 0])[0]
        if len(feature_maps.shape) < 2:
            continue
        # 获取这一层的通道数目
        channel_size = feature_maps.shape[2]
        for c in range(channel_size):
            # 获取某一通道的图像
            feature_map = feature_maps[:, :, c]
            # 最大最小值得差 大于0.1时候
            if np.ptp(feature_map) > 0.1:
                feature_map = 255*(feature_map - np.min(feature_map)) / np.ptp(feature_map)  # 将255改成其他值,看相应结果
            feature_map_path = os.path.join(output_path, layer.name, str(c+1)+'.jpg')
            # 存储 layer 层,第 c 个通道的图像
            cv2.imwrite(feature_map_path, feature_map)
        print('='*40)

model.summary()
在这里插入图片描述

Transfer Learning

使用已经存在的模型处理自己的问题,模型的改造

# include_top=True 考虑最后的全连接
# include_top=False 不考虑后面的全连接
model = ResNet50(weights='imagenet', include_top=False)

Input:

输入必须是模型的设定的大小
output:

需要有自己的输出,所以一般来说不需要之前模型的全连接Dense层。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值