keras实现多种分类网络的方式


Posted in Python onJune 11, 2020

Keras应该是最简单的一种深度学习框架了,入门非常的简单.

简单记录一下keras实现多种分类网络:如AlexNet、Vgg、ResNet

采用kaggle猫狗大战的数据作为数据集.

由于AlexNet采用的是LRN标准化,Keras没有内置函数实现,这里用batchNormalization代替

收件建立一个model.py的文件,里面存放着alexnet,vgg两种模型,直接导入就可以了

#coding=utf-8
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Conv2D, MaxPooling2D, ZeroPadding2D, BatchNormalization
from keras.layers import *
from keras.layers.advanced_activations import LeakyReLU,PReLU
from keras.models import Model
 
def keras_batchnormalization_relu(layer):
 BN = BatchNormalization()(layer)
 ac = PReLU()(BN)
 return ac
 
def AlexNet(resize=227, classes=2):
 model = Sequential()
 # 第一段
 model.add(Conv2D(filters=96, kernel_size=(11, 11),
      strides=(4, 4), padding='valid',
      input_shape=(resize, resize, 3),
      activation='relu'))
 model.add(BatchNormalization())
 model.add(MaxPooling2D(pool_size=(3, 3),
       strides=(2, 2),
       padding='valid'))
 # 第二段
 model.add(Conv2D(filters=256, kernel_size=(5, 5),
      strides=(1, 1), padding='same',
      activation='relu'))
 model.add(BatchNormalization())
 model.add(MaxPooling2D(pool_size=(3, 3),
       strides=(2, 2),
       padding='valid'))
 # 第三段
 model.add(Conv2D(filters=384, kernel_size=(3, 3),
      strides=(1, 1), padding='same',
      activation='relu'))
 model.add(Conv2D(filters=384, kernel_size=(3, 3),
      strides=(1, 1), padding='same',
      activation='relu'))
 model.add(Conv2D(filters=256, kernel_size=(3, 3),
      strides=(1, 1), padding='same',
      activation='relu'))
 model.add(MaxPooling2D(pool_size=(3, 3),
       strides=(2, 2), padding='valid'))
 # 第四段
 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(1000, activation='relu'))
 model.add(Dropout(0.5))
 
 # Output Layer
 model.add(Dense(classes,activation='softmax'))
 # model.add(Activation('softmax'))
 
 return model
 
def AlexNet2(inputs, classes=2, prob=0.5):
 '''
 自己写的函数,尝试keras另外一种写法
 :param inputs: 输入
 :param classes: 类别的个数
 :param prob: dropout的概率
 :return: 模型
 '''
 # Conv2D(32, (3, 3), dilation_rate=(2, 2), padding='same')(inputs)
 print "input shape:", inputs.shape
 
 conv1 = Conv2D(filters=96, kernel_size=(11, 11), strides=(4, 4), padding='valid')(inputs)
 conv1 = keras_batchnormalization_relu(conv1)
 print "conv1 shape:", conv1.shape
 pool1 = MaxPool2D(pool_size=(3, 3), strides=(2, 2))(conv1)
 print "pool1 shape:", pool1.shape
 
 conv2 = Conv2D(filters=256, kernel_size=(5, 5), padding='same')(pool1)
 conv2 = keras_batchnormalization_relu(conv2)
 print "conv2 shape:", conv2.shape
 pool2 = MaxPool2D(pool_size=(3, 3), strides=(2, 2))(conv2)
 print "pool2 shape:", pool2.shape
 
 conv3 = Conv2D(filters=384, kernel_size=(3, 3), padding='same')(pool2)
 conv3 = PReLU()(conv3)
 print "conv3 shape:", conv3.shape
 
 conv4 = Conv2D(filters=384, kernel_size=(3, 3), padding='same')(conv3)
 conv4 = PReLU()(conv4)
 print "conv4 shape:", conv4
 
 conv5 = Conv2D(filters=256, kernel_size=(3, 3), padding='same')(conv4)
 conv5 = PReLU()(conv5)
 print "conv5 shape:", conv5
 
 pool3 = MaxPool2D(pool_size=(3, 3), strides=(2, 2))(conv5)
 print "pool3 shape:", pool3.shape
 
 dense1 = Flatten()(pool3)
 dense1 = Dense(4096, activation='relu')(dense1)
 print "dense2 shape:", dense1
 dense1 = Dropout(prob)(dense1)
 # print "dense1 shape:", dense1
 
 dense2 = Dense(4096, activation='relu')(dense1)
 print "dense2 shape:", dense2
 dense2 = Dropout(prob)(dense2)
 # print "dense2 shape:", dense2
 
 predict= Dense(classes, activation='softmax')(dense2)
 
 model = Model(inputs=inputs, outputs=predict)
 return model
 
def vgg13(resize=224, classes=2, prob=0.5):
 model = Sequential()
 model.add(Conv2D(64, (3, 3), strides=(1, 1), input_shape=(resize, resize, 3), padding='same', activation='relu',
      kernel_initializer='uniform'))
 model.add(Conv2D(64, (3, 3), strides=(1, 1), padding='same', activation='relu', kernel_initializer='uniform'))
 model.add(MaxPooling2D(pool_size=(2, 2)))
 model.add(Conv2D(128, (3, 2), strides=(1, 1), padding='same', activation='relu', kernel_initializer='uniform'))
 model.add(Conv2D(128, (3, 3), strides=(1, 1), padding='same', activation='relu', kernel_initializer='uniform'))
 model.add(MaxPooling2D(pool_size=(2, 2)))
 model.add(Conv2D(256, (3, 3), strides=(1, 1), padding='same', activation='relu', kernel_initializer='uniform'))
 model.add(Conv2D(256, (3, 3), strides=(1, 1), padding='same', activation='relu', kernel_initializer='uniform'))
 model.add(MaxPooling2D(pool_size=(2, 2)))
 model.add(Conv2D(512, (3, 3), strides=(1, 1), padding='same', activation='relu', kernel_initializer='uniform'))
 model.add(Conv2D(512, (3, 3), strides=(1, 1), padding='same', activation='relu', kernel_initializer='uniform'))
 model.add(MaxPooling2D(pool_size=(2, 2)))
 model.add(Conv2D(512, (3, 3), strides=(1, 1), padding='same', activation='relu', kernel_initializer='uniform'))
 model.add(Conv2D(512, (3, 3), strides=(1, 1), padding='same', activation='relu', kernel_initializer='uniform'))
 model.add(MaxPooling2D(pool_size=(2, 2)))
 model.add(Flatten())
 model.add(Dense(4096, activation='relu'))
 model.add(Dropout(prob))
 model.add(Dense(4096, activation='relu'))
 model.add(Dropout(prob))
 model.add(Dense(classes, activation='softmax'))
 return model
 
def vgg16(resize=224, classes=2, prob=0.5):
 model = Sequential()
 model.add(Conv2D(64, (3, 3), strides=(1, 1), input_shape=(resize, resize, 3), padding='same', activation='relu',
      kernel_initializer='uniform'))
 model.add(Conv2D(64, (3, 3), strides=(1, 1), padding='same', activation='relu', kernel_initializer='uniform'))
 model.add(MaxPooling2D(pool_size=(2, 2)))
 model.add(Conv2D(128, (3, 2), strides=(1, 1), padding='same', activation='relu', kernel_initializer='uniform'))
 model.add(Conv2D(128, (3, 3), strides=(1, 1), padding='same', activation='relu', kernel_initializer='uniform'))
 model.add(MaxPooling2D(pool_size=(2, 2)))
 model.add(Conv2D(256, (3, 3), strides=(1, 1), padding='same', activation='relu', kernel_initializer='uniform'))
 model.add(Conv2D(256, (3, 3), strides=(1, 1), padding='same', activation='relu', kernel_initializer='uniform'))
 model.add(Conv2D(256, (3, 3), strides=(1, 1), padding='same', activation='relu', kernel_initializer='uniform'))
 model.add(MaxPooling2D(pool_size=(2, 2)))
 model.add(Conv2D(512, (3, 3), strides=(1, 1), padding='same', activation='relu', kernel_initializer='uniform'))
 model.add(Conv2D(512, (3, 3), strides=(1, 1), padding='same', activation='relu', kernel_initializer='uniform'))
 model.add(Conv2D(512, (3, 3), strides=(1, 1), padding='same', activation='relu', kernel_initializer='uniform'))
 model.add(MaxPooling2D(pool_size=(2, 2)))
 model.add(Conv2D(512, (3, 3), strides=(1, 1), padding='same', activation='relu', kernel_initializer='uniform'))
 model.add(Conv2D(512, (3, 3), strides=(1, 1), padding='same', activation='relu', kernel_initializer='uniform'))
 model.add(Conv2D(512, (3, 3), strides=(1, 1), padding='same', activation='relu', kernel_initializer='uniform'))
 model.add(MaxPooling2D(pool_size=(2, 2)))
 model.add(Flatten())
 model.add(Dense(4096, activation='relu'))
 model.add(Dropout(prob))
 model.add(Dense(4096, activation='relu'))
 model.add(Dropout(prob))
 model.add(Dense(classes, activation='softmax'))
 return model

然后建立一个train.py文件,用于读取数据和训练数据的.

#coding=utf-8
import keras
import cv2
import os
import numpy as np
import model
import modelResNet
import tensorflow as tf
from keras.layers import Input, Dense
from keras.preprocessing.image import ImageDataGenerator
 
resize = 224
batch_size = 128
path = "/home/hjxu/PycharmProjects/01_cats_vs_dogs/data"
 
trainDirectory = '/home/hjxu/PycharmProjects/01_cats_vs_dogs/data/train/'
def load_data():
 imgs = os.listdir(path + "/train/")
 num = len(imgs)
 train_data = np.empty((5000, resize, resize, 3), dtype="int32")
 train_label = np.empty((5000, ), dtype="int32")
 test_data = np.empty((5000, resize, resize, 3), dtype="int32")
 test_label = np.empty((5000, ), dtype="int32")
 for i in range(5000):
  if i % 2:
   train_data[i] = cv2.resize(cv2.imread(path + '/train/' + 'dog.' + str(i) + '.jpg'), (resize, resize))
   train_label[i] = 1
  else:
   train_data[i] = cv2.resize(cv2.imread(path + '/train/' + 'cat.' + str(i) + '.jpg'), (resize, resize))
   train_label[i] = 0
 for i in range(5000, 10000):
  if i % 2:
   test_data[i-5000] = cv2.resize(cv2.imread(path + '/train/' + 'dog.' + str(i) + '.jpg'), (resize, resize))
   test_label[i-5000] = 1
  else:
   test_data[i-5000] = cv2.resize(cv2.imread(path + '/train/' + 'cat.' + str(i) + '.jpg'), (resize, resize))
   test_label[i-5000] = 0
 return train_data, train_label, test_data, test_label
 
def main():
 
 train_data, train_label, test_data, test_label = load_data()
 train_data, test_data = train_data.astype('float32'), test_data.astype('float32')
 train_data, test_data = train_data/255, test_data/255
 
 train_label = keras.utils.to_categorical(train_label, 2)
 '''
  #one_hot转码,如果使用 categorical_crossentropy,就需要用到to_categorical函数完成转码
 '''
 test_label = keras.utils.to_categorical(test_label, 2)
 
 inputs = Input(shape=(224, 224, 3))
 
 modelAlex = model.AlexNet2(inputs, classes=2)
 '''
 导入模型
 '''
 modelAlex.compile(loss='categorical_crossentropy',
     optimizer='sgd',
     metrics=['accuracy'])
 '''
 def compile(self, optimizer, loss, metrics=None, loss_weights=None,
     sample_weight_mode=None, **kwargs):
  optimizer:优化器,为预定义优化器名或优化器对象,参考优化器
  loss: 损失函数,为预定义损失函数名或者一个目标函数
  metrics:列表,包含评估模型在训练和测试时的性能指标,典型用法是 metrics=['accuracy']
  sample_weight_mode:如果需要按时间步为样本赋值,需要将改制设置为"temoral"
  如果想用自定义的性能评估函数:如下
   def mean_pred(y_true, y_pred):
   return k.mean(y_pred)
  model.compile(loss = 'binary_crossentropy', metrics=['accuracy', mean_pred],...)
  损失函数同理,再看 keras内置支持的损失函数有
   mean_squared_error
  mean_absolute_error
  mean_absolute_percentage_error
  mean_squared_logarithmic_error
  squared_hinge
  hinge
  categorical_hinge
  logcosh
  categorical_crossentropy
  sparse_categorical_crossentropy
  binary_crossentropy
  kullback_leibler_divergence
  poisson
  cosine_proximity
 '''
 modelAlex.summary()
 '''
 # 打印模型信息
 '''
 modelAlex.fit(train_data, train_label,
    batch_size=batch_size,
    epochs=50,
    validation_split=0.2,
    shuffle=True)
 '''
 def fit(self, x=None,   # x:输入数据
   y=None,     # y:标签 Numpy array
   batch_size=32,   # batch_size:训练时,一个batch的样本会被计算一次梯度下降
   epochs=1,    # epochs: 训练的轮数,每个epoch会把训练集循环一遍
   verbose=1,    # 日志显示:0表示不在标准输入输出流输出,1表示输出进度条,2表示每个epoch输出
   callbacks=None,   # 回调函数
   validation_split=0.,  # 0-1的浮点数,用来指定训练集一定比例作为验证集,验证集不参与训练
   validation_data=None, # (x,y)的tuple,是指定的验证集
   shuffle=True,   # 如果是"batch",则是用来处理HDF5数据的特殊情况,将在batch内部将数据打乱
   class_weight=None,  # 字典,将不同的类别映射为不同的权值,用来在训练过程中调整损失函数的
   sample_weight=None,  # 权值的numpy array,用于训练的时候调整损失函数
   initial_epoch=0,   # 该参数用于从指定的epoch开始训练,继续之前的训练
   **kwargs):
 返回:返回一个History的对象,其中History.history损失函数和其他指标的数值随epoch变化的情况
 '''
 scores = modelAlex.evaluate(train_data, train_label, verbose=1)
 print(scores)
 
 scores = modelAlex.evaluate(test_data, test_label, verbose=1)
 print(scores)
 modelAlex.save('my_model_weights2.h5')
 
def main2():
 train_datagen = ImageDataGenerator(rescale=1. / 255,
          shear_range=0.2,
          zoom_range=0.2,
          horizontal_flip=True)
 test_datagen = ImageDataGenerator(rescale=1. / 255)
 train_generator = train_datagen.flow_from_directory(trainDirectory,
              target_size=(224, 224),
              batch_size=32,
              class_mode='binary')
 
 validation_generator = test_datagen.flow_from_directory(trainDirectory,
               target_size=(224, 224),
               batch_size=32,
               class_mode='binary')
 
 inputs = Input(shape=(224, 224, 3))
 # modelAlex = model.AlexNet2(inputs, classes=2)
 modelAlex = model.vgg13(resize=224, classes=2, prob=0.5)
 # modelAlex = modelResNet.ResNet50(shape=224, classes=2)
 modelAlex.compile(loss='sparse_categorical_crossentropy',
      optimizer='sgd',
      metrics=['accuracy'])
 modelAlex.summary()
 
 modelAlex.fit_generator(train_generator,
      steps_per_epoch=1000,
      epochs=60,
      validation_data=validation_generator,
      validation_steps=200)
 
 modelAlex.save('model32.hdf5')
 #
if __name__ == "__main__":
 '''
 如果数据是按照猫狗大战的数据,都在同一个文件夹下,使用main()函数
 如果数据按照猫和狗分成两类,则使用main2()函数
 '''
 main2()

得到模型后该怎么测试一张图像呢?

建立一个testOneImg.py脚本,代码如下

#coding=utf-8
from keras.preprocessing.image import load_img#load_image作用是载入图片
from keras.preprocessing.image import img_to_array
from keras.applications.vgg16 import preprocess_input
from keras.applications.vgg16 import decode_predictions
import numpy as np
import cv2
import model
from keras.models import Sequential
 
pats = '/home/hjxu/tf_study/catVsDogsWithKeras/my_model_weights.h5'
modelAlex = model.AlexNet(resize=224, classes=2)
# AlexModel = model.AlexNet(weightPath='/home/hjxu/tf_study/catVsDogsWithKeras/my_model_weights.h5')
 
modelAlex.load_weights(pats)
#
img = cv2.imread('/home/hjxu/tf_study/catVsDogsWithKeras/111.jpg')
img = cv2.resize(img, (224, 224))
x = img_to_array(img/255) # 三维(224,224,3)
 
x = np.expand_dims(x, axis=0) # 四维(1,224,224,3)#因为keras要求的维度是这样的,所以要增加一个维度
# x = preprocess_input(x) # 预处理
print(x.shape)
y_pred = modelAlex.predict(x) # 预测概率 t1 = time.time() print("测试图:", decode_predictions(y_pred)) # 输出五个最高概率(类名, 语义概念, 预测概率)
print y_pred

不得不说,Keras真心简单方便。

补充知识:keras中的函数式API——残差连接+权重共享的理解

1、残差连接

# coding: utf-8
"""残差连接 residual connection:
  是一种常见的类图网络结构,解决了所有大规模深度学习的两个共性问题:
   1、梯度消失
   2、表示瓶颈
  (甚至,向任何>10层的神经网络添加残差连接,都可能会有帮助)

  残差连接:让前面某层的输出作为后面某层的输入,从而在序列网络中有效地创造一条捷径。
       """
from keras import layers

x = ...
y = layers.Conv2D(128, 3, activation='relu', padding='same')(x)
y = layers.Conv2D(128, 3, activation='relu', padding='same')(y)
y = layers.Conv2D(128, 3, activation='relu', padding='same')(y)

y = layers.add([y, x]) # 将原始x与输出特征相加

# ---------------------如果特征图尺寸不同,采用线性残差连接-------------------
x = ...
y = layers.Conv2D(128, 3, activation='relu', padding='same')(x)
y = layers.Conv2D(128, 3, activation='relu', padding='same')(y)
y = layers.MaxPooling2D(2, strides=2)(y)

residual = layers.Conv2D(128, 1, strides=2, padding='same')(x) # 使用1*1的卷积,将原始张量线性下采样为y具有相同的形状

y = layers.add([y, residual]) # 将原始x与输出特征相加

2、权重共享

即多次调用同一个实例

# coding: utf-8
"""函数式子API:权重共享
  能够重复的使用同一个实例,这样相当于重复使用一个层的权重,不需要重新编写"""
from keras import layers
from keras import Input
from keras.models import Model


lstm = layers.LSTM(32) # 实例化一个LSTM层,后面被调用很多次

# ------------------------左边分支--------------------------------
left_input = Input(shape=(None, 128))
left_output = lstm(left_input) # 调用lstm实例

# ------------------------右分支---------------------------------
right_input = Input(shape=(None, 128))
right_output = lstm(right_input) # 调用lstm实例

# ------------------------将层进行连接合并------------------------
merged = layers.concatenate([left_output, right_output], axis=-1)

# -----------------------在上面构建一个分类器---------------------
predictions = layers.Dense(1, activation='sigmoid')(merged)

# -------------------------构建模型,并拟合训练-----------------------------------
model = Model([left_input, right_input], predictions)
model.fit([left_data, right_data], targets)

以上这篇keras实现多种分类网络的方式就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
跟老齐学Python之私有函数和专有方法
Oct 24 Python
Python工程师面试题 与Python基础语法相关
Jan 14 Python
Python实现复杂对象转JSON的方法示例
Jun 22 Python
详解Python 实现元胞自动机中的生命游戏(Game of life)
Jan 27 Python
Python进度条实时显示处理进度的示例代码
Jan 30 Python
python tkinter控件布局项目实例
Nov 04 Python
如何分离django中的媒体、静态文件和网页
Nov 12 Python
基于python使用tibco ems代码实例
Dec 20 Python
Python读取文件内容为字符串的方法(多种方法详解)
Mar 04 Python
基于Python的身份证验证识别和数据处理详解
Nov 14 Python
分享PyCharm最新激活码(真永久激活方法)不用每月找安装参数或最新激活码了
Dec 27 Python
Python爬虫之爬取最新更新的小说网站
May 06 Python
python的help函数如何使用
Jun 11 #Python
新手学python应该下哪个版本
Jun 11 #Python
python开发前景如何
Jun 11 #Python
python编写softmax函数、交叉熵函数实例
Jun 11 #Python
python能开发游戏吗
Jun 11 #Python
使用sklearn对多分类的每个类别进行指标评价操作
Jun 11 #Python
python属于解释语言吗
Jun 11 #Python
You might like
php使用正则过滤js脚本代码实例
2014/05/10 PHP
PHP中应该避免使用同名变量(拆分临时变量)
2015/04/03 PHP
深入理解PHP原理之执行周期分析
2016/06/01 PHP
完美的php分页类
2017/10/24 PHP
PHP 裁剪图片
2021/03/09 PHP
jQuery代码优化 遍历篇
2011/11/01 Javascript
javascript操作数组详解
2014/12/17 Javascript
jQuery中[attribute^=value]选择器用法实例
2014/12/31 Javascript
JavaScript控制table某列不显示的方法
2015/03/16 Javascript
jQuery+html5实现div弹出层并遮罩背景
2015/04/15 Javascript
Jquery遍历select option和添加移除option的实现方法
2016/08/26 Javascript
微信公众号支付H5调用支付解析
2016/11/04 Javascript
Bootstrap select多选下拉框实现代码
2016/12/23 Javascript
Vue的elementUI实现自定义主题方法
2018/02/23 Javascript
JS遍历DOM文档树的方法实例详解
2018/04/03 Javascript
JS弹窗 JS弹出DIV并使整个页面背景变暗功能的实现代码
2018/04/21 Javascript
[02:05:03]完美世界DOTA2联赛循环赛 LBZS VS Matador BO2 10.28
2020/10/28 DOTA
Python 转义字符详细介绍
2017/03/21 Python
Python3实现的画图及加载图片动画效果示例
2018/01/19 Python
python 定时修改数据库的示例代码
2018/04/08 Python
解决pyttsx3无法封装的问题
2018/12/24 Python
详解Python 切片语法
2019/06/10 Python
Rosetta Stone官方网站:语言学习
2019/01/05 全球购物
德国受欢迎的旅游和休闲网站:lastminute.de
2019/09/23 全球购物
大二自我鉴定范文
2013/10/05 职场文书
会计辞职信范文
2014/01/15 职场文书
《母亲的恩情》教学反思
2014/02/13 职场文书
2014基层党员干部学习全国两会心得体会
2014/03/17 职场文书
爱情寄语大全
2014/04/09 职场文书
民警个人对照检查剖析材料
2014/09/17 职场文书
幼儿园综治宣传月活动总结
2015/05/07 职场文书
学校禁毒宣传活动总结
2015/05/08 职场文书
2015年留守儿童工作总结
2015/05/22 职场文书
应收账款管理制度
2015/08/06 职场文书
Python实现Hash算法
2022/03/18 Python
MySql如何将查询的出来的字段进行转换
2022/06/14 MySQL